zoukankan      html  css  js  c++  java
  • Mybatis中的动态SQL在xml中支持的几种常用标签

    mybatis3之后,采用了功能强大的OGNL表达式语言消除了许多其它繁琐的标签,现在动态SQL在xml中支持的几种标签:

    • if
    • choose(when、otherwise)
    • trim(where、set)
    • foreach
    • bind

     一.if标签

    if标签通常用于where语句中,通过判断参数值来决定是否使用某个查询条件,它也经常用于UPDATE语句中判断是否更新某一个字段,还可以再INSERT语句中用来判断是否插入某个字段的值。

    1.1 在where条件中使用if

    用法:含义就是当if满足时,就执行标签体中的内容。

    需求:准备如下数据表,当只输入用户名的时候,就根据这个用户名进行模糊查询匹配的用户;当只输入邮箱时,就根据邮箱完全匹配用户胡;当两者都同时输入时,就需要用这两个条件去查询匹配的用户。

    表格:

    贴下关键代码:

     (1)controller

    @PostMapping("/selectByUser")
        public List<SysUser> selectByUser(){
            SysUser sysUser=new SysUser();
            sysUser.setUserName("tes");
            return userService.selectByUser(sysUser);
        }

    说明:这里只传入了userName。而userEmail为null

    (2)service实现类

    1  @Override
    2     public List<SysUser> selectByUser(SysUser sysUser) {
    3         return userMapper.selectByUser(sysUser);
    4     }
    View Code

    (3)mapper接口

    List<SysUser> selectByUser(SysUser sysUser);

    (4)mapper.xm<select id="selectByUser" resultType="com.example.demo.dao.SysUser">        select id,        user_name userName,

            user_password userPassword,
            user_email userEmail,
            user_info userInfo,
            head_img headImg,
            created_time createTime
            from sys_user
            where 1=1
            <if test="userName!=null and userName!=''">
                and user_name like concat('%',#{userName},'%')
            </if>
            <if test="userEmail!=null and userEmail!=''">
                and user_email=#{userEmail}
            </if>
        </select>

    说明:1.if标签内有一个必填的属性test,test的值是一个符合OGNL要求的判断表达式,表达式的结果可以认为是ture或者false.
    2.当有多个判断条件时,可以使用and或者or进行搭配。
    3.上面两个if,它们是平级的关系,只要有满足if条件的,if标签内的 and user_x=... 这一句就会接在where语句后面。如果不满足,就不会有。
    4.这里写了一个where 1=1 是为了保证当2个if语句都没有的时候,不会直接以where结束,这样sql语句就会报错。
    这种写法where1=1不美观,后面可以采用where标签来拯救它。

    (5)实体类

     1 package com.example.demo.dao;
     2 
     3 
     4 import java.sql.Date;
     5 
     6 public class SysUser {
     7     /**
     8      * 用户ID
     9      */
    10     private Long id;
    11     /**
    12      * 用户名
    13      */
    14     private String userName;
    15     /**
    16      * 密码
    17      */
    18     private String userPassword;
    19     /**
    20      * 邮箱
    21      */
    22     private String userEmail;
    23     /**
    24      * 简介
    25      */
    26     private String userInfo;
    27     /**
    28      * 头像
    29      */
    30     private byte[] headImg;
    31     /**
    32      * 创建时间
    33      */
    34     private Date createTime;
    35 
    36     public Long getId() {
    37         return id;
    38     }
    39 
    40     public void setId(Long id) {
    41         this.id = id;
    42     }
    43 
    44     public String getUserName() {
    45         return userName;
    46     }
    47 
    48     public void setUserName(String userName) {
    49         this.userName = userName;
    50     }
    51 
    52     public String getUserPassword() {
    53         return userPassword;
    54     }
    55 
    56     public void setUserPassword(String userPassword) {
    57         this.userPassword = userPassword;
    58     }
    59 
    60     public String getUserEmail() {
    61         return userEmail;
    62     }
    63 
    64     public void setUserEmail(String userEmail) {
    65         this.userEmail = userEmail;
    66     }
    67 
    68     public String getUserInfo() {
    69         return userInfo;
    70     }
    71 
    72     public void setUserInfo(String userInfo) {
    73         this.userInfo = userInfo;
    74     }
    75 
    76     public byte[] getHeadImg() {
    77         return headImg;
    78     }
    79 
    80     public void setHeadImg(byte[] headImg) {
    81         this.headImg = headImg;
    82     }
    83 
    84     public Date getCreateTime() {
    85         return createTime;
    86     }
    87 
    88     public void setCreateTime(Date createTime) {
    89         this.createTime = createTime;
    90     }
    91 }
    View Code

    采用postman模拟请求,会得到三条和名字模糊匹配的记录:

     1 [
     2     {
     3         "id": 3,
     4         "userName": "test1",
     5         "userPassword": "123456",
     6         "userEmail": "test1@mybatis.tk",
     7         "userInfo": "test1",
     8         "headImg": null,
     9         "createTime": "2020-03-04"
    10     },
    11     {
    12         "id": 1001,
    13         "userName": "test",
    14         "userPassword": "123456",
    15         "userEmail": "test@mybatis.tk",
    16         "userInfo": "管理员",
    17         "headImg": null,
    18         "createTime": "2020-03-19"
    19     },
    20     {
    21         "id": 1002,
    22         "userName": "test1",
    23         "userPassword": "123456",
    24         "userEmail": "test1@mybatis.tk",
    25         "userInfo": "test1",
    26         "headImg": null,
    27         "createTime": "2020-03-25"
    28     },
    29     {
    30         "id": 1003,
    31         "userName": "test1",
    32         "userPassword": "123456",
    33         "userEmail": "test1@mybatis.tk",
    34         "userInfo": "test1",
    35         "headImg": null,
    36         "createTime": "2020-03-29"
    37     },
    38     {
    39         "id": 1004,
    40         "userName": "test1",
    41         "userPassword": "123456",
    42         "userEmail": "test1@mybatis.tk",
    43         "userInfo": "test1",
    44         "headImg": null,
    45         "createTime": "2020-03-29"
    46     }
    47 ]
    View Code

    1.2 在UPDATE更新列中使用if标签

    需求:只更新发生变化的字段。

    (1)controller

    1  @PostMapping("/updateBySelective")
    2     int updateBySelective(SysUser sysUser){
    3         sysUser.setUserName("hello");
    4         sysUser.setId(1L);
    5         return userService.updateBySelective(sysUser);
    6     }
    View Code

    (2)service实现类

    1 @Override
    2     public int updateBySelective(SysUser sysUser) {
    3         return userMapper.updateBySelective(sysUser);
    4     }
    View Code

    (3)mapper接口

    1  int updateBySelective(SysUser sysUser);
    View Code

    (4)mapper.xml

    <update id="updateBySelective">
            update sys_user
            set
            <if test="userName!=null and userName!=''">
                user_name=#{userName},
            </if>
            <if test="userPassword!=null and userPassword!=''">
                user_password=#{userPassword},
            </if>
            <if test="userEmail!=null and userEmail!=''">
                user_email=#{userEmail},
            </if>
            <if test="userInfo!=null and userInfo!=''">
                user_info=#{userInfo},
            </if>
            <if test="headImg!=null">
                head_img=#{headImg,jdbcType=BLOB},
            </if>
            <if test="createTime!=null">
                created_time=#{createTime,jdbcType=TIMESTAMP},
            </if>
            id=#{id}
            where id=#{id}
        </update>

    说明:1.这里 id=#{id}是为了防止所有if都不满足的时候语法错误。即使if中有个别满足的,也不能省去,否则sql语法错误。
    这种写法不美观,仍然然可以通过where标签和set标签来解决。

     1.3 在INSERT动态插入列中使用if标签

    需求:如果某一列的参数值不为空,就使用传入的值;如果传入参数为空,就使用数据库中默认的值(通常为空),而不使用传入的空值。

    (1)controller

    1 @PostMapping("/insertUser")
    2     public int insertUser(){
    3 
    4        SysUser sysUser=new SysUser();
    5        sysUser.setUserName("Tom");
    6        sysUser.setUserEmail("aa.@qq.com");
    7        sysUser.setUserInfo("作家");
    8        return userService.insertUser(sysUser);
    9     }
    View Code

    (2)service实现类

    1 @Override
    2     public int insertUser(SysUser sysUser) {
    3         return userMapper.insertUser(sysUser);
    4     }
    View Code

    (3)mapper接口

    int insertUser(SysUser sysUser);

    (4)mapper.xml

    <insert id="insertUser">
        insert into sys_user(
        user_name,user_password,user_email,
        <if test="userInfo!=null and userInfo!=''">
            user_info,
        </if>
        head_img,created_time)
        values(
        #{userName},#{userPassword},#{userEmail},
        <if test="userInfo!=null and userInfo!=''">
            #{userInfo},
        </if>
        #{headImg,jdbcType=BLOB},#{createTime,jdbcType=TIMESTAMP})
    </insert>

     二. choose(when、otherwise)

    if标签只能实现if功能,没有else功能。于是可以通过本节的组合来实现if..else的功能。choose中农包含when和otherwise两个标签,一个choose中至少有一个when,有0个或1个otherwise.  

    我的理解:when就相当于java中的else if,而otherwise就相当于java中的else。

    需求:准备如下表。当ID有值的时候就优先采用ID进行查询匹配用户;如果ID没有值,那就采用用户名进行查询匹配的用户。

     (1)controller

    1 @PostMapping("/selectByIdOrName")
    2     SysUser selectByIdOrName(){
    3         SysUser sysUser=new SysUser();
    4         sysUser.setId(1L);
    5         sysUser.setUserName("test3");
    6         return userService.selectByIdOrName(sysUser);
    7     }
    View Code

    (2)service实现类

    1 @Override
    2     public SysUser selectByIdOrName(SysUser sysUser) {
    3         return userMapper.selectByIdOrName(sysUser);
    4     }
    View Code

    (3)mapper接口

    SysUser selectByIdOrName(SysUser sysUser);

    (4)mapper.xml

    <select id="selectByIdOrName" resultType="com.example.demo.dao.SysUser">
        select id,
        user_name userName,
        user_password userPassword,
        user_email userEmail,
        user_info userInfo,
        head_img headImg,
        created_time createTime
        from sys_user
        where 1=1
        <choose>
            <when test="id!=null">
                and id=#{id}
            </when>
            <when test="userName!=null and userName!=''">
                and user_name=#{userName}
            </when>
            <otherwise>
                and 1=2
            </otherwise>
        </choose>
    </select>
    {
        "id": 1,
        "userName": "test1",
        "userPassword": "123456",
        "userEmail": "admin@mybatis.tk",
        "userInfo": "管理员",
        "headImg": null,
        "createTime": "2020-03-01"
    }

    三. where、set、trim

     3.1 where标签

    修改之前的where 1=1例子,姓名模糊匹配,邮箱完全匹配查询。

    修改之前:

    <select id="selectByUser" resultType="com.example.demo.dao.SysUser">
            select id,
            user_name userName,
            user_password userPassword,
            user_email userEmail,
            user_info userInfo,
            head_img headImg,
            created_time createTime
            from sys_user
            where 1=1
            <if test="userName!=null and userName!=''">
                and user_name like concat('%',#{userName},'%')
            </if>
            <if test="userEmail!=null and userEmail!=''">
                and user_email=#{userEmail}
            </if>
        </select>

    直接将xml文件改为如下:

    <select id="selectByUser" resultType="com.example.demo.dao.SysUser">
            select id,
            user_name userName,
            user_password userPassword,
            user_email userEmail,
            user_info userInfo,
            head_img headImg,
            created_time createTime
            from sys_user
            <where>
                <if test="userName!=null and userName!=''">
                    and user_name like concat('%',#{userName},'%')
                </if>
                <if test="userEmail!=null and userEmail!=''">
                    and user_email=#{userEmail}
                </if>
            </where>
    
        </select>
    说明:当if都不满足的时候,where中就没有元素,就不会存在之前缺少where 1=1造成sql错误的问题。

    3.2 set用法

    还是之前的例子:

    修改之前:

    <update id="updateBySelective">
            update sys_user
            set
            <if test="userName!=null and userName!=''">
                user_name=#{userName},
            </if>
            <if test="userPassword!=null and userPassword!=''">
                user_password=#{userPassword},
            </if>
            <if test="userEmail!=null and userEmail!=''">
                user_email=#{userEmail},
            </if>
            <if test="userInfo!=null and userInfo!=''">
                user_info=#{userInfo},
            </if>
            <if test="headImg!=null">
                head_img=#{headImg,jdbcType=BLOB},
            </if>
            <if test="createTime!=null">
                created_time=#{createTime,jdbcType=TIMESTAMP},
            </if>
            id=#{id}
            where id=#{id}
        </update>

    修改之后:

     1 <update id="updateUser">
     2         update sys_user
     3         set
     4         <foreach collection="_parameter" item="val" index="key" separator=",">
     5             ${key}=#{val}
     6         </foreach>
     7         where id=#{id}
     8     </update>
     9 
    10     <update id="updateBySelective">
    11         update sys_user
    12         <set>
    13             <if test="userName!=null and userName!=''">
    14                 user_name=#{userName},
    15             </if>
    16             <if test="userPassword!=null and userPassword!=''">
    17                 user_password=#{userPassword},
    18             </if>
    19             <if test="userEmail!=null and userEmail!=''">
    20                 user_email=#{userEmail},
    21             </if>
    22             <if test="userInfo!=null and userInfo!=''">
    23                 user_info=#{userInfo},
    24             </if>
    25             <if test="headImg!=null">
    26                 head_img=#{headImg,jdbcType=BLOB},
    27             </if>
    28             <if test="createTime!=null">
    29                 created_time=#{createTime,jdbcType=TIMESTAMP},
    30             </if>
    31             id=#{id}
    32         </set>
    33         where id=#{id}
    34     </update>
    View Code

    这种只解决了逗号问题,不是很全面的解决问题,仍然需要

    id=#{id}

    3.3 trim标签

    where和set标签的功能都能通过trim标签实现。

     举例:

    (1)还是之前的用户名模糊匹配,邮箱完全匹配的例子:(使用trim标签去除多余的and关键字)

    修改mapper.xml文件:

    <select id="selectByUser" resultType="com.example.demo.dao.SysUser">
            select id,
            user_name userName,
            user_password userPassword,
            user_email userEmail,
            user_info userInfo,
            head_img headImg,
            created_time createTime
            from sys_user
            <trim prefix="where" prefixOverrides="and">
                <if test="userName!=null and userName!=''">
                    and user_name like concat('%',#{userName},'%')
                </if>
                <if test="userEmail!=null and userEmail!=''">
                    and user_email=#{userEmail}
                </if>
            </trim>
    
        </select>

    效果一样的。但是就不会多写where1=1,并且指定了prefix为where。
  • 相关阅读:
    移动应用专项测试
    MAC连接安卓手机通过adb指令安装apk
    Git GUI可视化操作教程
    nestjs中typeorm进行事物操作
    vue-element-admin 实现动态路由(从后台查询出菜单列表绑定侧边栏)
    el-form 表单校验
    vscode设置VUE eslint开发环境
    .netcore signalR 实时消息推送
    psexec局域网执行远程命令
    Asp.Net跨平台 Jexus 5.8.1 独立版
  • 原文地址:https://www.cnblogs.com/Hermioner/p/12591483.html
Copyright © 2011-2022 走看看