什么是动态sql?
动态SQL指的是根据不同的查询条件 , 生成不同的Sql语句.我们之前写的 SQL 语句都比较简单,如果有比较复杂的业务,我们需要写复杂的 SQL 语句,往往需要拼接,而拼接 SQL ,稍微不注意,由于引号,空格等缺失可能都会导致错误。那么怎么去解决这个问题呢?这就要使用 mybatis 动态SQL,通过 if, choose, when, otherwise, trim, where, set, foreach等标签,可组合成非常灵活的SQL语句,从而在提高 SQL 语句的准确性的同时,也大大提高了开发人员的效率。
准备工作
- 创建数据库blog表
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
- 创建实体类Blog
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Blog {
private String id;
private String title;
private String author;
//注意该属性和数据库字段不相同,可以在Mybatis核心配置文件中配置自动开启驼峰命名自动映射
private Date createTime;
private int views;
}
- 创建一个随机的UUID作为id
public class IDUtils {
public static String getId(){
return UUID.randomUUID().toString().replaceAll("-","");
}
}
- 创建接口类BlogMapper
public interface BlogMapper {
//添加一个博客信息
int addBlog(Blog blog);
}
- 创建Mapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace绑定一个对应的dao/mapper接口-->
<mapper namespace="dao.BlogMapper">
<insert id="addBlog" parameterType="Blog">
insert into blog (id,title,author,create_time,views)
values (#{id},#{title},#{author},#{createTime},#{views});
</insert>
</mapper>
- Mybatis核心配置文件配置自动开启驼峰命名自动映射和注册Mapper
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 注册接口Mapper映射-->
<mappers>
<!-- 使用class绑定接口-->
<mapper class="dao.BlogMapper"/>
</mappers>
- 测试类
public class Test {
@org.junit.Test
public void test(){
//通过封装好的工具类获取SqlSession会话
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//通过接口类型class获取接口对象实例(动态代理)
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
//执行接口中的方法
mapper.addBlog(new Blog(IDUtils.getId(),"Mybatis如此简单","chenhui",new Date(),9999));
mapper.addBlog(new Blog(IDUtils.getId(),"Java如此简单","chenhui",new Date(),9999));
mapper.addBlog(new Blog(IDUtils.getId(),"Spring如此简单","chenhui",new Date(),9999));
mapper.addBlog(new Blog(IDUtils.getId(),"微服务如此简单","chenhui",new Date(),9999));
sqlSession.commit();
//关闭SqlSession
sqlSession.close();
}
}
- 结果
动态sql之if语句
需求:根据作者名字和博客名字来查询博客!如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询
- 接口类
//按照不同的需求查询
List<Blog> queryBlogIf(Map map);
- Mapper.xml文件
<!-- 如果参数未传值则查询所有blog表数据,如果作者名字title为空,那么只根据博客名字author查询,
反之,则根据作者名来查询,如果title和author都有值则根据两个参数查询
-->
<select id="queryBlogIf" parameterType="map" resultType="Blog">
select id,title,author,create_time,views from blog where 1=1
<if test="title!=null">
and title=#{title}
</if>
<if test="author!=null">
and author=#{author}
</if>
</select>
- 测试类
public class Test {
@org.junit.Test
public void test(){
//通过封装好的工具类获取SqlSession会话
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//通过接口类型class获取接口对象实例(动态代理)
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
//执行接口中的方法
HashMap<String,Object> map=new HashMap<String, Object>();
//map.put("title","Java如此简单");
//map.put("author","chenhui");
List<Blog> blogs = mapper.queryBlogIf(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.commit();
//关闭SqlSession
sqlSession.close();
}
}
未传参数则查询所有数据
根据title和author来传值
根据title传值
根据author来传值