Mybatis之旅第五篇-动态SQL

1、引言

在以前的CRUD例子中,都是一些很简单的SQL,然而实际的业务开发中会有一些复杂的SQL,咱们常常须要拼接SQL,拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。Mybatis个一个强大特性--动态SQL,这一特性能够完全摆脱这种痛苦。html

2、if标签

如今有以下查询:spring

<!-- 根据条件查询用户 -->
    <select id="queryUserByWhere" parameterType="user" resultType="user"> SELECT id, username, birthday, sex, address FROM `user` WHERE sex = #{sex} AND username LIKE '%${username}%' </select>

当咱们带入两个参数时,返回结果不会有问题,但是当咱们只带入姓名,不带入性别时,结果就不合理,由于sex带入的null,做为查询条件就过滤告终果,这个时候咱们须要if标签。sql

改造sql:数组

<!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user"> SELECT id, username, birthday, sex, address FROM `user` WHERE 1=1 <if test="sex!=null and sex !=''"> AND sex = #{sex} </if>
   <if test="username!=null and username!=''"> AND username like '%${username}%' </if>
</select>

将接口和方法都加入其中mybatis

@Test public void testQueryUserByWhere() { // mybatis和spring整合,整合以后,交给spring管理
    SqlSession sqlSession = this.sqlSessionFactory.openSession(); // 建立Mapper接口的动态代理对象,整合以后,交给spring管理
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 使用userMapper执行根据条件查询用户
    User user = new User(); //user.setSex("1");
    user.setUsername("张"); List<User>list = userMapper.queryUserByWhere(user); for (User u : list) { System.out.println(u); } // mybatis和spring整合,整合以后,交给spring管理
 sqlSession.close(); }

结果:app

3、where 标签

where标签会把第一个and忽略,固然若是是or开头的,MyBatis也会把它忽略,此外,在where元素中你不须要考虑空格的问题,MyBatis会智能的帮你加上。ide

<select id="queryUserByWhere1" parameterType="user" resultType="user"> SELECT id, username, birthday, sex, address FROM `user` <!-- where标签能够自动添加where,同时处理sql语句中第一个and或者or关键字 -->
    <where>
        <if test="sex!=null"> AND sex = #{sex} </if>
        <if test="username!=null and username!=''"> AND username like '%${username}%' </if>
    </where>
</select>

4、set 标签

在更新的时候咱们也须要像where同样可以进行动态判断,这个时候就使用set标签,set会使最后的逗号忽略,咱们就能够动态的更新那些修改了的字段。测试

以下:this

<update id="dynamicSetTest" parameterType="user"> update `user` <set>
        <if test="sex != null"> sex = #{sex}, </if>
        <if test="username!=null and username!=''"> username = #{username}, </if>
    </set> where id = #{id} </update>

测试:spa

@Test public void dynamicSetTest() { SqlSession sqlSession = this.sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = new User(); //user.setSex("1");
    user.setUsername("袁大大"); user.setId(26); userMapper.dynamicSetTest(user); sqlSession.commit(); sqlSession.close(); }

5、choose(when,otherwise) 标签

choose的做用相似Java语言中的switch,能够解决咱们只想选择一个查询条件的状况。

以下:

<select id="selectUserByChoose" resultType="user" parameterType="user"> select id, username, birthday, sex, address FROM `user` <where>
            <choose>
                <when test="id !='' and id != null"> id=#{id} </when>
                <when test="username !='' and username != null"> and username like #{username} </when>
                <otherwise> and sex=#{sex} </otherwise>
            </choose>
        </where>
    </select>

这个写法很容易理解,与switch相同,匹配成功后就会跳出。

6、trim 标签

trim标记是一个格式化的标记,能够完成set或者是where标记的功能,怎么用呢:

增长prefix前缀,去掉第一个prefixoverride中内容。

增长suffix后缀,去掉最后一个suffixoverride中内容。

经过trim能够解决where 与set 问题

<select id="selectUserByUsernameAndSex" resultType="user" parameterType="user"> select * from user <!-- <where> <if test="username != null"> username=#{username} </if> <if test="username != null"> and sex=#{sex} </if> </where> -->
    <trim prefix="where" prefixOverrides="and | or">
        <if test="username != null"> and username=#{username} </if>
        <if test="sex != null"> and sex=#{sex} </if>
    </trim>
</select>

先增长where,并去掉第一个and 或者or ,替换了where if 写法。

<!-- 根据 id 更新 user 表的数据 -->
    <update id="updateUserById" parameterType="com.ys.po.User"> update user u <!-- <set> <if test="username != null and username != ''"> u.username = #{username}, </if> <if test="sex != null and sex != ''"> u.sex = #{sex} </if> </set> -->
            <trim prefix="set" suffixOverrides=",">
                <if test="username != null and username != ''"> u.username = #{username}, </if>
                <if test="sex != null and sex != ''"> u.sex = #{sex}, </if>
            </trim> where id=#{id} </update>

增长set,并去掉最后一个逗号,替换了set if写法。

7、SQL片断

写sql时常常会出现一些重复片断,咱们能够进行提取,这样能够作到重用。

先使用sql进行声明:

<!-- 声明sql片断 -->
<sql id="userFields"> id, username, birthday, sex, address </sql>

使用include refid

<select id="queryUserBySqlWhere" parameterType="user" resultType="user">
<!-- SELECT id, username, birthday, sex, address FROM `user` -->
<!-- 使用include标签加载sql片断;refid是sql片断id --> SELECT <include refid ="userFields"/> FROM `user` <!-- where标签能够自动添加where关键字,同时处理sql语句中第一个and关键字 -->
<where>
    <if test="sex != null"> AND sex = #{sex} </if>
<if test="username != null and username != ''"> AND username LIKE '%${username}%' </if>
    </where>
</select>

8、foreach标签

当咱们向sql传递数组或List,mybatis使用foreach解析。

  • foreach标签,进行遍历

  • collection:遍历的集合,这里是QueryVo的ids属性

  • item:遍历的项目,能够随便写,,可是和后面的#{}里面要一致

  • open:在前面添加的sql片断

  • close:在结尾处添加的sql片断

  • separator:指定遍历的元素之间使用的分隔符

    <select id="queryUserByIds" parameterType="com.yuanqinnan.pojo.QueryVo" resultType="user"> SELECT * FROM `user` <where>
        <foreach collection="ids" item="item" open="id IN (" close=")" separator=","> #{item} </foreach>

    改造QueryVo:

    @Data public class QueryVo { private User user; private List<Integer> ids; }

    测试方法:

    @Test public void queryUserByIds(){ SqlSession sqlSession = this.sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); QueryVo user = new QueryVo(); List<Integer>ids = new ArrayList<>(); ids.add(1); ids.add(10); ids.add(24); user.setIds(ids); List<User> list = userMapper.queryUserByIds(user); for (User u : list) { System.out.println(u); } sqlSession.close(); }

    结果

  • 动态sql实际上是一个拼接过程,咱们掌握上面这些标签,就能完成mybatis的动态sql

原文出处:https://www.cnblogs.com/yuanqinnan/p/10712679.html

相关文章
相关标签/搜索