• Springboot+Mybatis处理复杂数据类型(Map、List等)


    Springboot+Mybatis处理复杂参数类型(Map、List等)

    在实际场景使用springboot+mybatis来完成数据库的增删改查时,可能会面对接收的参数比较复杂的情况。比如在接收restful风格的请求参数时,可能filter里的过滤条件比较复杂,包含有数字、字符串、List等类型混合的请求。同时为了使得mybatis的查询写得更通用,需要覆盖各种场景,这就要借助于Mybatis的各种特性来实现。

    接下来,就以实际的例子来给出代码参考。该部分的代码可以直接沿用到未来的其它实际场景中。

    需求场景

    接收Restful风格的复杂参数请求,利用mybatis处理包含的Map、List、String等数据类型,并根据请求参数进行排序和分页等操作

    请求参数

    在实际场景中遇到的一个复杂restful风格接口中的请求参数,filter里的过滤条件比较多,且参数结构较为复杂:

    {
    	"appKey": "appKey",
    	"filter": {
    		"id": ["609a3d7242ff880018b9e26b"],
    		"eventName": "免费",
    		"eventKey": "click",
    		"positionInfo": {"posId":"5fd9f7b71b52740011016b75", "levelId":"5fd9f7b71b5274001103740"},
    		"clientVersion": ["210f63dd6b6c4c09b4cf55a4"],
            "priority":0
    	},
    	"limit": 999,
    	"populate": "",
    	"projectId": "5fd9f67840e8580047582075",
    	"skip": 0,
    	"sort": {
    		"id": 1
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    对部分数据做了脱敏,但仍然保留了filter中的复杂参数场景。可以看到filter中包含了Map、List、String、Integer,基本包含了主要的数据类型。因此,对这个问题的解决可以延用到许多其它的场景。

    解决方案

    首先给出Mapper.java的代码

    import com.example.data.pojo.Statsevents;
    import org.apache.ibatis.annotations.Param;
    import org.springframework.stereotype.Component;
    
    import java.util.List;
    import java.util.Map;
    
    @Component
    public interface StatseventsMapper {
    
        int deleteByPrimaryKey(String id);
    
        int insert(Statsevents record);
    
        Statsevents selectByPrimaryKey(String id);
    
        List<Statsevents> selectAll(@Param("param") Map<String, Object> paramMap);
    
        int updateByPrimaryKey(Statsevents record);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    上述代码包含了增删改查的四个功能。主要关注于seleteAll查找指定条件的所有数据,这里利用了@Param("param")注解来命令导入的参数,这样在xml文件中就可以用param来使用引入的参数。通过上面的请求参数,确定引入的参数类型为Map

    接下来就是主要的mybatis的xml文件的编写

    <select id="selectAll" parameterType="java.util.Map" resultMap="BaseResultMap">
    
        select id, eventName, eventKey, priority, positionInfo, clientVersion
        from statsevents
        <where>
          
          <if test="param.containsKey('filter') and param.get('filter').size() > 0">
            <foreach collection="param.get('filter').entrySet()" index="key" item='val' separator="and" open=" " close=" ">
            <choose>
                
              <when test="val instanceof com.alibaba.fastjson.JSONArray and val.size()>0">
                ${key} in
                <foreach collection="val" item="_key" open="(" close=")" separator=",">
                  #{_key}
                foreach>
              when>
                
              <when test="val instanceof com.alibaba.fastjson.JSONObject and val.size() > 0">
                <foreach collection="val" index="pKey" item="pVal" open=" " separator="and" close=" ">
                  ${key} like "%${pVal}%"
                foreach>
              when>
              
              <when test="key == 'clientVersion' and val instanceof com.alibaba.fastjson.JSONArray and val.size() > 0">
                <foreach collection="val" item="cVal" open=" " separator="and" close=" ">
                  ${key} like '%${cVal}%'
                foreach>
              when>
                
              <when test="val instanceof Integer and val != null">
                ${key} like '%"status": ${val}%'
              when>
                
              <when test="val instanceof String and val != ''">
                ${key} like '%${val}%'
              when>
            choose>
            foreach>
          if>
        where>
    
        
        <if test="param.containsKey('sort')">
          <foreach collection="param.get('sort').entrySet()" index="key" item="val">
            <if test="val == -1">
              order by ${key} asc
            if>
            <if test="val == 1">
              order by ${key} desc
            if>
          foreach>
        if>
    
        
        <if test="param.containsKey('limit') and param.containsKey('skip')">
          limit ${param.get("skip")}, ${param.get("limit")}
        if>
      select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    上述代码基本完整展示了基于Restful风格的请求参数下,mybatis的处理方式。包含了处理复杂的参数请求,以及根据请求参数进行排序和分页的功能。

    代码讲解

    本次主要是处理Restful风格的请求参数,根据filter里的筛选条件,查询指定数据。

    由于传入的是一个Map的参数类型,因此,最外层使用了处理Map数据类型时的方法。

    mybatis处理Map数据类型的方法

    利用foreach标签进行循环,其中colleaction参数表示待遍历的Map数据集index表示索引(也就是key)item表示每个键的值,index-item就表示了键值对, separator表示遍历每个键值对后的分隔符openclose表示遍历开始前和结束后拼接的字符串

    接下来,对filter下的键值对进行遍历,通过判断不同值的类型,执行相应操作。因为我这里之前引入了fastjson来对Map和List进行处理,因此判断数据类型的时候采用了val instanceof com.alibaba.fastjson.JSONObjectval instanceof com.alibaba.fastjson.JSONArray。如果是原始的Map和List可以直接用val instanceof java.utils.Listval instanceof java.utils.Map来进行判断类型。

    对于Map类型的处理参考刚刚的方式。对于List数据类型的方法如下:

    mybatis处理List数据类型的方法

    利用foreach标签进行循环,其中colleaction参数表示待遍历的List数据集item表示List中的每个值,separator表示遍历每个值后的分隔符openclose表示遍历开始前和结束后拼接的字符串

    接下来分别处理Integer和String的类型,对于Integer类型的数据判空时需要设置val != null

    最后处理排序和分页的功能。根据sort指定的键进行排序,键可以指定为任意值。分页时判断传入的参数中是否有limit和skip参数,利用sql本身的语法实现分页。

  • 相关阅读:
    Python教学管理系统、学生选课考试系统源代码,基于Django
    线程安全
    html制作网页案例代码----(故宫博物馆9页)特效很多
    JRZB-R02保持防跳继电器
    Node.js详解(--模块)
    RHCE之路iptables,firewalld,富规则
    视频转换芯片MS7200概述 HDMI转数字RGB/YUV/HDMI RXReceive/替代IT66021FN
    岩土工程监测利器:多通道振弦数据记录仪应用隧道监测
    二叉搜索树
    基于spring boot 的学生科研项目共享平台 毕业设计-附源码271611
  • 原文地址:https://blog.csdn.net/Urbanears/article/details/126121289