MyBatis的动态SQL

MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
动态SQL元素和JSTL或基于类似XML的文本处理器相似。在MyBatis之前的版本中,有很多元素需要花时间了解。MyBatis 3大大精简了元素种类,现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于OGNL的表达式来淘汰其它大部分元素。

if元素

使用test属性来判断,如果结果true,把这部分内容拼接sql中,如果结果false,去除这个部分内容。

<select id="selectBySex" parameterType="map" resultType="user">
    select * from user where 1=1
    <if test="sex != null and sex != ''">
      and sex = #{sex}
    </if>
</select>

测试代码:

@Test
public void test09() {
    SqlSession sqlSession = SqlSessionFactoryUtils.openSqlSession();
    UserDao userDao = sqlSession.getMapper(UserDao.class);
    Map map = new HashMap();
    map.put("sex",1);
    List<User> users = userDao.selectBySex(map);
    System.out.println(users);
    sqlSession.commit();
    sqlSession.close();
}

choose、when、otherwise元素

相当于java中的switch、case、default。

<select id="selectUserListByWhen"  resultType="user" parameterType="user">
    SELECT * FROM user WHERE 1=1
    <choose>
        <when test="username !=null and username!=''">
            AND username like '%${username}%'
        </when>
        <when test="sex !=null and sex!=''">
            AND sex = #{sex}
        </when>
        <otherwise>
            AND age = #{age}
        </otherwise>
    </choose>
</select>

测试代码:

@Test
public void test10() {
    SqlSession sqlSession = SqlSessionFactoryUtils.openSqlSession();
    UserDao userDao = sqlSession.getMapper(UserDao.class);
    User user = new User();
    user.setSex("1");
    List<User> users = userDao.selectUserListByWhen(user);
    System.out.println(users);
    sqlSession.commit();
    sqlSession.close();
}

以上例子中:
<1> 当sex和username 都不为null的时候, 那么选择二选一(前者优先),
<2> 如果都为null, 那么就选择 otherwise中的,
<3> 如果sex和username 只有一个不为null, 那么就选择不为null的那个。

注:无论是if和 when中的判断,如果需要写and,则必须小写。

where、set元素

在前面if和choose元素中,where后面跟有1=1,如果没有1=1这个条件的话,就可能会产生错误:

select * from user where and sex = #{sex}

当然我们可以改成:

<select id="selectBySex" parameterType="map" resultType="user">
    select * from user where
    <if test="sex != null and sex != ''">
      and sex = #{sex}
    </if>
</select>

但是若if中test为false时,就变成了:

select * from user where 

这个时候,我们可以使用where元素:

<select id="selectBySex" parameterType="map" resultType="user">
    select * from user 
	<where>
    	  <if test="sex != null and sex != ''">
      	and sex = #{sex}
      </if>
  </where>
</select>

一般在修改某条记录的时候,我们希望只修改有值传入的字段:

<update id="updateUserById" parameterType="user">
    update user set
    <if test="username != null and username !=’’"> username = #{username}, </if>
    <if test="sex != null and sex !=’’"> sex = #{sex}, </if>
    <if test="password != null and password !=’’">    password = #{password} </if>
    <where>
        <if test="id != null"> id = #{id}</if>
    </where>
</update>

测试代码:

    @Test
    public void test11() {
        SqlSession sqlSession = SqlSessionFactoryUtils.openSqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        User user = new User();
        user.setId(1);
        user.setSex("1");
        user.setUsername("小明");
        int num = userDao.updateUserById(user);
        System.out.println(num);
        sqlSession.commit();
        sqlSession.close();
    }

运行时,发现报错了。。。原来最后执行的SQL语句:where前面多了一个逗号。

update user set username = '小明', sex = '1', where id = 1

添加元素:

<update id="updateUserById" parameterType="user">
    update user 
    <set>
    <if test="username != null and username !=’’"> username = #{username}, </if>
    <if test="sex != null and sex !=’’"> sex = #{sex}, </if>
    <if test="password != null and password !=’’">    password = #{password} </if>
   </set> 
<where>
        <if test="id != null"> id = #{id}</if>
    </where>
</update>

update语句,set语句中存在不合适的逗号,会自动删除。

foreach元素

在MySQL中可以使用in来查询多条符合要求的记录,比如:

select * from user where id in (1,2,3)

如果将1,2,3封装在集合或者数组中,可以使用进行遍历并查询,如下:

    <select id="selectUserListInId" resultType="user">
        SELECT * FROM user WHERE id IN
        <foreach item="item" index="index" collection="list" open="(" separator="," close=")">
            #{item}
        </foreach>
    </select>

测试代码:

    @Test
    public void test12() {
        SqlSession sqlSession = SqlSessionFactoryUtils.openSqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        List list = new ArrayList();
        list.add(1);
        list.add(2);
        list.add(3);
        List<User> users = userDao.selectUserListInId(list);
        System.out.println(users);
        sqlSession.commit();
        sqlSession.close();
    }

属性介绍(这里只考虑 List和数组):

    collection    :传的参数 只有list、array两值,不能写错
    item		  :每次遍历的值赋值给变量item
    open	      :表示该语句以什么开始
    close         :表示该语句以什么结束
    separator     :表示该语句以什么隔开
    index	      :元素的序号
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值