什么是动态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
搭建环境
-
创建一个普通项目
-
导包
-
编写数据库
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;
-
编写实体类
package pojo; import lombok.Data; import java.util.Date; @Data public class Blog { private String id; private String title; private String author; private Date createTime; private int views; }
-
编写接口
package dao; import pojo.Blog; import java.util.List; import java.util.Map; public interface BlogMapper { List<Blog> getUsers(Map<String,Object> map); }
if
-
编写接口Mapper配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="dao.BlogMapper"> <select id="getUsers" parameterType="map" resultType="Blog"> select * from blog where 1=1 <if test="title!=null"> and title=#{title} </if> <if test="author!=null"> and author=#{author} </if> </select> </mapper>
-
测试
import dao.BlogMapper; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import pojo.Blog; import utils.IDutils; import utils.MybatisUtils; import java.util.Date; import java.util.HashMap; public class MyTest { @Test public void addBlogTest(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); BlogMapper mapper = sqlSession.getMapper(BlogMapper.class); HashMap<String, Object> map = new HashMap<>(); map.put("title","Java"); mapper.getUsers(map); sqlSession.commit(); sqlSession.close(); } }
choose(when,otherwise)
有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.BlogMapper">
<select id="getUsers" parameterType="map" resultType="Blog">
select * from blog
<where>
<choose>
<when test="title!=null">
title=#{title}
</when>
<when test="author!=null">
and author=#{author}
</when>
</choose>
</where>
</select>
</mapper>
where,set
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.BlogMapper">
<select id="getUsers" parameterType="map" resultType="Blog">
select * from blog where 1=1
<if test="title!=null">
and title=#{title}
</if>
<if test="author!=null">
and author=#{author}
</if>
</select>
</mapper>
我们看这个,可以看到我们写了一个 where 1=1 这是为了我们能够正确的查询,但是我们实际开发中肯定不希望有这种语句,然后就出现了where标签,where能够在where标签体内的条件至少满足一个的时候为我们自动添加where,且如果“and和or”前面是where的话,可以自动去掉“and和or”
set标签则是处理update语句的,看下面这条正常Sql语句
update tablename set password=#{password},name=#{name} where id=#{id}
我们的条件分割的中间是有逗号的,而set的作用就是将set给我们前置,然后去掉多余的逗号,也就是说如果在“name=#{name}”的后面还有逗号的话,set标签会帮我们去掉
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.BlogMapper">
<update id="updateBlog" parameterType="map" >
update user
<set>
<if test="name!=null">
name=#{name},
</if>
<if test="password!=null">
password=#{password},
</if>
</set>
where id=#{id}
</update>
</mapper>