MyBatis - 基础学习8 - 动态sql( if - - choose )
一.什么是动态sql
动态sql就是根据不同的条件生成不同的语句
- 动态 SQL 是 MyBatis 的强大特性之一
- 如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号
- 利用动态 SQL,可以彻底摆脱这种痛苦
二.环境搭建(新建项目)
1.导包(maven导入)
2.配置核心配置文件config.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties resource="db.properties"/> <settings> <setting name="logImpl" value="STDOUT_LOGGING"/> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <typeAliases> <package name="top.lostyou.pojo"/> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <mappers> <mapper class="top.lostyou.dao.BlogMapper"/> </mappers> </configuration>
别的都不说老套路了;多了一个设置 <setting name="mapUnderscoreToCamelCase" value="true"/>
用于解决mysql的下划线命名,和Java的驼峰命名不统一的设置
3.编写实体类和工具类
拓展:我们的id为varchar是字符型,其实是随机生成的;其实大公司都是用随机生成制造ID
@SuppressWarnings("all") //抑制警告
public class IDutils {
public static String getID(){
String s = UUID.randomUUID().toString().replaceAll("-", "");
return s;
}
@Test
public void test(){
System.out.println(IDutils.getID());
}
}
4.编写接口文件和mapper.xml同名文件,然后再核心配置文件中注册
拓展一个标签,我们再命名时不规范的时候总是会弹出警告,此时我们可以使用
@SuppressWarnings("all") 抑制警告
5.测试:插入数据
public class test {
@Test
public void addBlogTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Blog blog = new Blog();
blog.setId(IDutils.getID());
blog.setTitle("Mybatis");
blog.setAuthor("狂神说");
blog.setCreateTime(new Date());
blog.setViews(9999);
mapper.testinsert(blog);
blog.setId(IDutils.getID());
blog.setTitle("Java");
mapper.testinsert(blog);
blog.setId(IDutils.getID());
blog.setTitle("Spring");
mapper.testinsert(blog);
blog.setId(IDutils.getID());
blog.setTitle("微服务");
mapper.testinsert(blog);
sqlSession.close();
}
}
三.动态SQL
1.动态sql之if
- 编写接口
List<Blog> selecctIF(Map map);
- 在mapper.xml中编写动态sql语句
<select id="selecctIF" resultType="blog" parameterType="map"> SELECT * FROM blog WHERE 1=1 <if test="title != null"> and title=#{title} </if> <if test="id != null"> and id=#{id} </if> </select>
where 1=1 是为了我们没有使用动态sql时(没有拼接sql时)要保证语句不会出错
if(动态sql标记,判断) test=“ ” (条件)
- 测试
@Test public void Testselectif(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); BlogMapper mapper = sqlSession.getMapper(BlogMapper.class); HashMap map = new HashMap(); map.put("id","0ab57e6863b9495a8be8fba48acd4385"); List<Blog> blogs = mapper.selecctIF(map); for (Blog blog : blogs) { System.out.println(blog); } sqlSession.close(); }
2.动态SQL之Choose(when,otherwise)
- 编写接口
List<Blog> selectChoose(Map map);
- 在mapper.xml中编写动态sql
</select> <select id="selectChoose" parameterType="map" resultType="blog"> SELECT * FROM blog <where> <choose> <when test="title != null"> and title=#{title} </when> <when test="author != null"> and author = #{author} </when> <otherwise> id = #{id} </otherwise> </choose> </where> </select>
关于choose选择没什么好说的,它们的用法可以在Java中找到,都是学过的知识了
- choose ----- switch
- when ----- case
- otherwise ----- default
并且when和otherwise自带类似于Java break关键字,也就是说当执行了一句when语句之后,就不会执行下一句when语句,即使它满足条件
也就是说我们在执行了when语句之后,就不会执行otherwise语句
掌握:Where语句
它的写入简化和规范了我们的sql语句,如果在下面的判断条件都没成立的情况下(if) 我们原来的 where 1= 1 就显得不规范了
所以衍生出来where标签的第一个作用,当判断条件都不成立时,他就不会在sql语句后添加那个关键字 where
我们在判断语句成立的时候,拼接的sql语句会有 多一个连接词的情况:and | or 比如 where and id = 1;很显然这样的sql语句在编译的时候就会报错
所以衍生出来where标签的第二个作用,当where后面紧跟 and | or 时,它就会帮我们自动删除这个连接词
- 测试
@Test public void TestChoose(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); BlogMapper mapper = sqlSession.getMapper(BlogMapper.class); HashMap map = new HashMap(); map.put("author","狂神说"); map.put("title","Spring"); List<Blog> blogs = mapper.selectChoose(map); for (Blog blog : blogs) { System.out.println(blog); } sqlSession.close(); }
3.动态SQL之set
- 编写接口
int updateSet(Map map);
- 在mapper.xml中编写动态sql
<update id="updateSet" parameterType="map"> UPDATE blog <set> <choose> <when test="author != null and title != null"> author = #{author},title=#{title}, </when> <when test="author != null"> author = #{author}, </when> <when test="title != null"> title=#{title}, </when> </choose> </set> where id = #{id} </update>
有关 update语句没有什么好讲的,用法依旧是普通的sql语句的写法,这里我们嵌入了一些动态sql的东西,本质还是sql拼接
掌握:set 标签
set标签会在update语句后面自动加入set语句,它的作用是,因为sql语法中的update修改的最后一个记录是没有逗号结尾的
所以衍生出set标签的作用是把语句最后一个逗号删除
- 测试
@Test
public void TestUpdate(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
map.put("id","0c8cfe8a84454740bb8386c8ae0ac626");
map.put("title","我服了啊");
int i = mapper.updateSet(map);
if(i>0)
{
System.out.println("修改成功!");
}
else if(i==0){
System.out.println("未改动!");
}
sqlSession.close();
}