Mybatis——动态SQL

根据不同的条件生成不同的sql语句

搭建环境

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

创建基础工程

1.导包

2.编写配置文件

3.编写实体类

@Data
public class Blog {
   private int id;
   private String title;
   private String author;
   private Date createTime;
   private int views;
}

mapUnderscoreToCamelCase:是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。

<settings>
   <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

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

 

IF

mapper接口

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

mapper.xml

<select id="queryBlogIF" parameterType="map" resultType="Blog">
  select * from blog where 1=1
   <if test="title != null">
      and title = #{title}
   </if>
   <if test="views != null">
      and views > #{views}
   </if>
</select>

测试

@Test
public void test2(){
   SqlSession sqlSession = MybatisUtils.getSqlSession();
   BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
   HashMap hashMap = new HashMap();
   hashMap.put("views",5000);
   List<Blog> blogs = blogMapper.queryBlogIF(hashMap);
   for (Blog blog : blogs) {
       System.out.println(blog);
  }
   sqlSession.close();
}

 

常用标签

trim、where、set

where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

<select id="queryBlogIF" parameterType="map" resultType="Blog">
  select * from blog
   <where><!--将where1=1替换-->
       <if test="title != null">
          title = #{title}
       </if>
       <if test="views != null">
          and views > #{views}
       </if>
   </where>
</select>

where 元素等价的自定义 trim 元素为:

<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>

 

set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)

    <update id="updateBlog" parameterType="map">
      update blog
       <set>
           <if test="title != null">
              title = #{title},
           </if>
           <if test="author != null">
              author = #{author},
           </if>
       </set>
      where id = #{id}
   </update>

set 元素等价的自定义 trim 元素:

<trim prefix="SET" suffixOverrides=",">
...
</trim>

 

choose、when、otherwise

choose 元素有点像 Java 中的 switch 语句

<select id="queryBlogChoose" parameterType="map" resultType="Blog">
       select * from 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层面,去执行一个逻辑代码

 

SQL片段

有时我们会将一部分公共的代码抽取出来,方便复用

<sql id="if_title_views">
  select * from blog
   <where>
       <if test="title != null">
          title = #{title}
       </if>
       <if test="views != null">
          and views > #{views}
       </if>
   </where>
</sql>
?
<select id="queryBlogIF" parameterType="map" resultType="Blog">
   <include refid="if_title_views"></include>
</select>

注意:

  • 最好基于单表来定义sql片段

foreach

动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。比如:

<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
 <foreach item="item" index="index" collection="list"
     open="(" separator="," close=")">
      #{item}
 </foreach>
</select>

测试:

<select id="queryBlogForeach" parameterType="map" resultType="Blog">
  select * from blog
   <where>
       <foreach collection="views" item="view" open="(" close=")" separator="or">
          views = #{view}
       </foreach>
   </where>
</select>


@Test
public void test5(){
   SqlSession sqlSession = MybatisUtils.getSqlSession();
   BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
   HashMap hashMap = new HashMap();
   ArrayList<Integer> list = new ArrayList<Integer>();
   list.add(1000);
   list.add(2000);
   hashMap.put("views",list);
   List<Blog> blogs = mapper.queryBlogForeach(hashMap);
   for (Blog blog : blogs) {
       System.out.println(blog);
  }
   sqlSession.close();
}

动态sql就是在拼接sql语句

 

Mybatis——动态SQL

上一篇:基础数据库知识分享(4)


下一篇:MySQL的常用存储引擎InnoDb 和MyISAM 的区别