mybatis 动态sql
一、本质
动态sql是,在sql语句添加逻辑语句
官网:https://mybatis.org/mybatis-3/zh/dynamic-sql.html (看官网足够))
二、if
1、接口类
List<Blog> getBlogInfo(Map<String, Object> map);
2、xml映射文件
<select id="getBlogInfo" parameterType="map" resultType="blog"> select * from blog where 1=1 <if test="author != null"> and author = #{author} </if> <if test="title != null"> and title = #{title} </if> </select>
3、测试类
package com.wt.dao; import com.wt.pojo.Blog; import com.wt.utils.MyBatisUtil; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import java.util.HashMap; import java.util.List; import java.util.Map; public class TestBlog { @Test public void getBlog(){ SqlSession sqlSession = MyBatisUtil.getSession(); BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class); List<Blog> blogList = blogMapper.getBlog(); for (Blog blog : blogList) { System.out.println(blog); } sqlSession.close(); } @Test public void getBlogInfo(){ SqlSession sqlSession = MyBatisUtil.getSession(); BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class); Map<String, Object> map = new HashMap<String, Object>(); // 1. 无参数 // List<Blog> blogList = blogMapper.getBlogInfo(map); // for (Blog blog : blogList) { // System.out.println(blog); // } // 2. title有值 // map.put("title", "java"); // 3. title 和 author 都有值 map.put("title", "java"); map.put("author", "tom"); List<Blog> blogList = blogMapper.getBlogInfo(map); for (Blog blog : blogList) { System.out.println(blog); } sqlSession.close(); } }
三、trim(where set)
A、where select delete update
元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除
B、set update
set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号
C、trim 可以自定义 前缀后缀 看官网
四、choose、when、otherwise
与 switch选择语句相似,看看官网,一班和where和set一起使用
案例 choose 和 where结合
a、接口
List<Blog> getBlogWhen(Map<String, Object> map);
b、xml映射文件
<select id="getBlogWhen" resultType="blog" parameterType="map"> select * from blog <where> <choose> <when test="author != null"> and author = #{author} </when> <when test="title != null"> and title = #{title} </when> <otherwise> and views > 50 </otherwise> </choose> </where> </select>
c、测试(略)
五、sql片段
作用:简化代码,提高代码利用率
改良上述代码xml
<!-- 与Django中模板块 差不多--> <sql id="chooseBlog"> <choose> <when test="author != null"> and author = #{author} </when> <when test="title != null"> and title = #{title} </when> <otherwise> and views > 50 </otherwise> </choose> </sql> <select id="getBlogWhen" resultType="blog" parameterType="map"> select * from blog <where> <include refid="chooseBlog"></include> </where> </select>
<sql 用于存放代码块
<include 用于引用代码块
局限性
1、不适应于比较复杂的sql语句,适用于单表查询
2、where不在引用内部的原因(自己理解, 当没有where时,不用执行下面的语句,若包含where,要先执行include 再执行where)
六、foreach
a、sql语句(类似)
SELECT * from blog where id in (1, 4, 5)
注意:万能数据类型Map
b、接口类
List<Blog> getBlogForeach(Map<String, Object> map);
c、xml映射文件
<select id="getBlogForeach" parameterType="map" resultType="blog"> select * from blog <where> <foreach collection="ids" item="id" open="id in (" close=")" separator=","> #{id} </foreach> </where> </select>
d、测试
@Test public void getBlogWhen(){ SqlSession sqlSession = MyBatisUtil.getSession(); BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class); Map<String, Object> map = new HashMap<String, Object>(); ArrayList<Integer> arrayList = new ArrayList<Integer>(); map.put("ids", arrayList); List<Blog> blogList = blogMapper.getBlogForeach(map); for (Blog blog : blogList) { System.out.println(blog); } sqlSession.close(); }
补充
arrayList.add(1); arrayList.add(3); arrayList.add(5);
e、遇到的问题
1)、接口类的数据类型,忘记万事不觉用Map
2)、xml 映射文件错误将 id in 放到 foreach外
id in <foreach collection="ids" item="id" open="(" close=")" separator=",">
3)、测试
实例化Map
实例化ArrayList
将ArrayList对象作为Map的Object