Mybatis笔记12--动态SQL

    技术2022-09-02  94

    12、动态SQL

    什么是动态SQL:动态SQL就是根据不同的条件生成不同的SQL语句

    动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

    使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

    如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。

    if choose (when, otherwise) trim (where, set) foreach

    1、搭建环境

    CREATE TABLE `blog`( `id` VARCHAR(50) NOT NULL COMMENT '博客id', `title` VARCHAR(100) NOT NULL COMMENT '博客标题', `author` VARCHAR(30) NOT NULL COMMENT '博客作者', `create_time` DATETIME NOT NULL COMMENT '创建时间', `views` INT(30) NOT NULL COMMENT '浏览量' )ENGINE=INNODB DEFAULT CHARSET=utf8

    创建一个基础工程

    导包

    编写配置文件

    编写实体类

    @Data public class Blog { private String id; private String title; private String author; private Date createTime;//属性名与字段名不一致 private int views; }

    解决实体类中属性名与字段名不一致问题,在核心配置文件中配置 mapUnderscoreToCamelCase

    <settings> <!--标准的日志工厂实现--> <setting name="logImpl" value="STDOUT_LOGGING"/> <!--名字必须和官网一样,不能有有空格--> <!--是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。 --> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>

    编写实体类对应的Mapper接口和Mapper.xml文件

    在BlogMapper接口中写方法

    //查询博客 List<Blog> getBlogIF(Map map);

    在对应的BlogMapper.xml中写sql语句

    <!--动态SQL if使用--> <select id="getBlogIF" resultType="Blog" parameterType="map"> select * from mybatis.blog where 1=1 <if test="title !=null"> and title=#{title} </if> <if test="author!=null"> and author=#{author} </if> </select>

    测试

    @Test public void getBlogIF(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); BlogMapper mapper = sqlSession.getMapper(BlogMapper.class); HashMap map = new HashMap(); map.put("title","好看的"); map.put("author","春雪恒"); List<Blog> blog = mapper.getBlogIF(map); for (Blog blog1 : blog) { System.out.println(blog1); } sqlSession.close(); }

    3、 trim (where, set)

    BlogMapper.xml

    <!--动态语句 set用法--> <update id="updateBlog" parameterType="map"> update mybatis.blog <set> <if test="title !=null"> title=#{title}, </if> <if test="author !=null"> author=#{author} </if> </set> where id =#{id} </update> <!--动态SOL where使用 where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。 而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。 --> <select id="getBlogChoose" parameterType="map" resultType="Blog"> select * from mybatis.blog <where> <if test="title !=null"> title=#{title} </if> <if test="author!=null"> and author=#{author} </if> </where> </select>

    4、choose (when, otherwise)

    BlogMapper.xml

    <!--动态SQL语句 choose使用 choose相当于switch只能选择执行一个条件 条件按顺序 --> <select id="getBlogChoose" parameterType="map" resultType="Blog"> select * from mybatis.blog <where> <choose> <when test="title !=null"> title=#{title} </when> <when test="author!=null"> author=#{author} </when> <otherwise> views=#{views} </otherwise> </choose> </where> </select>

    所谓的动态语句SQL,本质还是SQL语句,只是我们可以再SQL层面,去执行一个逻辑代码

    5、SQL片段

    有时候,我们可能会将一些功能的部分抽取出来,方便重复使用

    使用sql标签抽取公共部分

    <!--使用sql标签抽取公共部分--> <sql id="if-title-author"> <if test="title !=null"> and title=#{title} </if> <if test="author!=null"> and author=#{author} </if> </sql>

    在需要使用的地方用include标签调用

    <!--使用include调用sql片段--> <select id="getBlogIF" resultType="Blog" parameterType="map"> select * from mybatis.blog where 1=1 <include refid="if-title-author"></include> </select>

    注意事项:

    最好基于单表来定义SQL片段!sql片段中不要存在where标签!

    6、foreach

    foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。

    select *from blog where 1=1 and <foreach item="id" collection="ids" open="(" separator="or" close=")"> id =#{id} </foreach> (id=1 or id=2 or id=3) <!-- select *from blog where 1=1 and (id=1 or id=2 or id=3) 我们现在传一个map,这个map中存在一个集合! --> <select id="getBlogForEach" parameterType="map" resultType="Blog"> select * from mybatis.blog <where> <foreach collection="ids" item="id" open="and (" close=")" separator="or"> id = #{id} </foreach> </where> </select>

    测试:

    @Test public void getBlogForEach(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); BlogMapper mapper = sqlSession.getMapper(BlogMapper.class); HashMap map = new HashMap(); ArrayList<Integer> ids = new ArrayList<Integer>(); ids.add(1); ids.add(2); ids.add(3); for (Integer id : ids) { System.out.println(id); } map.put("ids",ids); List<Blog> blog = mapper.getBlogForEach(map); for (Blog blog1 : blog) { System.out.println(blog1); } sqlSession.close(); }

    动态SQL就是在拼接SQL语句,我们只要保证SQL的正确性,按照SQL的格式,去排列组合就可以了!

    建议:

    先在mysql中写出完整的SQL,在去对应的去修改成为我们的动态SQL实现通用即可!
    Processed: 0.014, SQL: 12