mybatis学习(二)mybatis 动态sql

MyBatis的强大特性之一便是它的动态SQL,这里主要说下<if>,<choose>,<where>,<set>,<foreach>,<bind>。搭建mybatis(基于springBoot)和增删改查,见上文

一、if

  <select id="selectByUser" resultType="com.lbc.mybatisDemo.book.model.SysUser">
        select * 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 like concat('%',#{userEmail},'%')
        </if>
    </select>

if标签里的test是必填属性,该值应该是一个符合OGNL规范的判断表达式,该表达式返回的应该是true 或 false,除此之外所有的非0值均为true,只有0值为false。

判断条件property != null and property !=' ' 适用于任何object对象,而 property !=' ' 或 property == ' '只适应于String类型的字段。

  
         SysUser sysUser = new SysUser();
         sysUser.setUserName("my");
         List<SysUser> query = userMapper.selectByUser(sysUser);
         System.out.println(query);

insert、update同理使用。

二、choose

        通过if标签的学习,我们也意识到了,好像if中并没有if···else···这种类型的判断,而在实际的开发中难免会遇到条件判断的情况,那choose的出现便弥补了这个缺陷,choose标签中含有<when>、<otherwise>两个标签,一个choose应该至少含有一个when标签。


    <select id="selectByIdOrUserName" resultType="com.lbc.mybatisDemo.book.model.SysUser">
        select * from sys_user where 1=1
        <choose>
            <when test="id != null">
                and id = #{id}
            </when>
            <when test="userName !=null and userName !=''">
                and user_name like concat('%',#{userName},'%')
            </when>
            <otherwise>
                and 1 = 2
            </otherwise>

        </choose>

    </select>

这是一个判断是否有id或userName属性的语句,要是两者全为空,则返回一个and 1=2(错误条件,导致选出的结果为空)

 
        SysUser sysUser = new SysUser();
        sysUser.setUserName("my");
        List<SysUser> query = userMapper.selectByIdOrUserName(sysUser);
        System.out.println(query); 

三、where

    <select id="selectByUserWhere" resultType="com.tiza.mybatisDemo.book.model.SysUser">
        select * 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 like concat('%',#{userEmail},'%')
        </if>
        </where>
    </select>

从中很容易看出,之前的where 1= 1 主要是为了防止if的所有语句都不适用,就会导致 select * from sys_user where  这样where没有条件,就会导致sql语句出错。有些开发人员不喜欢用1=1这种形式,那就可以直接用<where>标签,当<where>中的所有条件都不满足时,where也就随之不存在了。

四、set


    <update id="updateByIdSelective">
        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 and headImg !=''">
                head_img = #{headImg,jdbcType = BLOB},
            </if>
            <if test="createTime !=null and createTime !=''">
                create_time =#{createTime,jdbcType =TIMESTAMP}
            </if>

        </set>
        where id = #{id}
    </update>

set是将set值放在标签内,类似上文的where,用法也相似。

五、foreach

foreach是循环的语句,在mybatis中是一种集合的条件属性

  <select id="selectByIdList" resultType="com.lbc.mybatisDemo.book.model.SysUser">
        select * from sys_user  where id in
      <foreach collection="list" open="(" close=")" separator="," item="id" index="i">
          #{id}
      </foreach>
    </select>

foreach包含以下属性

collection:必填 值为要迭代循环的属性名。

item:变量名,值为从迭代对象中取的每一个值。

index:索引的属性名,在集合数组情况下值为当前索引值,当迭代循环的对象是Map类型时,这个值为Map的Key

open:整个循环内容开头的字符串。

close:整个循环内容结束的字符串。

separator:每次循环的分隔符。

collection对象中可以是集合list也可以是map对象

1、只有一个数组参数或集合参数时

DefaultSqlSession中wrapCollection方法如下:

 private Object wrapCollection(Object object) {
        DefaultSqlSession.StrictMap map;
        if (object instanceof Collection) {
            map = new DefaultSqlSession.StrictMap();
            map.put("collection", object);
            if (object instanceof List) {
                map.put("list", object);
            }

            return map;
        } else if (object != null && object.getClass().isArray()) {
            map = new DefaultSqlSession.StrictMap();
            map.put("array", object);
            return map;
        } else {
            return object;
        }
    }

当参数为collection集合时,默认会转为一个key为collection的Map,若参数为list集合时,那么map的可以就为“list”(foreach标签中的collection = "list" 就可以得到这个list集合),当参数为数组时,也会转换为map,默认的key则会变成array。

注:使用@Param时指定名称,则collection要对应修改该名称。

    List<SysUser> selectByIdList(List<Long> idArray);
    List<SysUser> selectByIdList(@Param("custom") List<Long> idArray);

2、有多个参数时

@Param应该给每一个参数指定一个名称用于区分

3、参数为map时

使用map参数与@Param类似,要指定名称给collection,否则找不到对应的value,如不指定名称,默认的名称为_parameter。

4、参数为对象时

这种情况要指定对象的属性名,对象内多层嵌套的对象,要用属性.属性(集合和数组可以使用下标值),从而指定深层的属性值。

 

 

foreach中的批量插入


    <insert id="insertList" >
        insert into sys_user (user_name,user_password,user_email,user_info,head_img,create_time)
        value
        <foreach collection="list" item="user" separator=",">
            (#{user.userName},#{user.userPassword},#{user.userEmail},#{user.userInfo},#{user.headImg,jdbcType = BLOB},#{user.createTime,jdbcType =TIMESTAMP})
        </foreach>
       </insert>

int insertList(List<SysUser> sysUsers);

      List<SysUser> userList = new ArrayList<SysUser>();
        for (int i = 0; i < 3; i++) {
            SysUser user1 = new SysUser();
            user1.setUserName("Test"+i);
            user1.setUserPassword("123456");
            user1.setUserEmail("1233@123.com");
            userList.add(user1);
        }
        int row = userMapper.insertList(userList);
        System.out.println(row);

foreach实现动态update

    <update id="updateByMap">
    update sys_user
    set
    <foreach collection="_parameter" item="val" index="key" separator=",">
        ${key} = #{val}
    </foreach>
    where id  = #{id}

    </update>

其中: 

#{}这种方式SQL语句是经过预编译的

${}在动态解析时候,会传入参数字符串

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值