文章目录
- 前言
- 一、环境搭建
- 二、if
- 三、choose - when - otherwise
- 四、set
- 五、foreach
- 六、SQL片段
前言
1)什么是动态SQL?
答:动态SQL就是根据不同的条件生成不同的SQL语句。
2)优点:可摆脱SQL语句拼接带来的繁琐。
接下来,将以一个实例介绍动态sql用到的标签。
一、环境搭建
1)创建一个测试用的到数据库中的表blog,表中的数据可任意添加。
CREATE TABLE `blog`(
`id` VARCHAR(50) NOT NULL COMMENT '博客id',
`title` VARCHAR(100) NOT NULL COMMENT '博客标题',
`author` VARCHAR(30) NOT NULL COMMENT '博客作者',
``blog`` DATETIME NOT NULL COMMENT '创建时间',
`views` INT(30) NOT NULL COMMENT '浏览量'
)ENGINE=INNODB DEFAULT CHARSET=utf8
2)创建实体类Blog。(此处省略了get/set/toString方法,练习是需添加)
public class Blog {
private String id;
private String title;
private String author;
private Date createTime; // 属性名和字段名不一致,设置里面开启驼峰命名法
private int views;
}
3)创建实体的接口BlogMapper
public interface BlogMapper {
}
4)设置mybatis-congfig.xml配置文件。
注意:1)中表的字段名为create_time,而2)中实体类的属性名为createTime,因此须在设置中配置表中字段名转java的驼峰命名法。
<?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>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSl=true"/>
<property name="username" value="root"/>
<property name="password" value="12345"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper class="com.ali.mapper.BlogMapper"></mapper>
</mappers>
</configuration>
5)创建sqlSession的工具类
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
// 获得处理sql语句的对象
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
6)创建一个验证结果的测试类Test。
public class UserMapperTest {
@Test
public void test(){
}
}
二、if
1)<if> :根据条件匹配where中子内容。
<where>:只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
2)代码实现:
目标:查找符合条件的title和author信息。
①在BlogMapper中:
public interface BlogMapper {
List<Blog> quarrBlogs(Map map);
}
②在BlogMapper.xml中:
<select id="quarrBlogs" parameterType="map" resultType="com.ali.pojo.Blog">
select * from mybatis.blog
<where>
<if test="title != null">
and title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</where>
</select>
③测试:
public class UserMapperTest {
@Test
public void test(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
map.put("title", "mybatis");
map.put("author", "hi");
List<Blog> blogs = mapper.quarrBlogs(map);
for (Blog blog : blogs) {
System.out.println(blogs);
}
sqlSession.commit();
sqlSession.close();
}
}
三、choose - when - otherwise
1)功能:从多个条件中选择一个使用。类似于Java 中的 switch 语句。
<when>:在什么条件下执行什么语句。
<otherwise>最后一个条件下执行什么语句
2)代码实现:
目标:查找符合条件的title或者author信息。
①在BlogMapper中:
public interface BlogMapper {
List<Blog> quarrBlogs2(Map map);
}
②在BlogMapper.xml中:
目标:按title或者author信息查找内容。
<select id="quarrBlogs2" parameterType="map" resultType="com.ali.pojo.Blog">
select * from mybatis.blog
<where>
<choose>
<when test="title != null">
title = #{title};
</when>
<otherwise >
and author = #{author}
</otherwise>
</choose>
</where>
</select>
③测试:
public class UserMapperTest {
@Test
public void test(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
map.put("title", "mybatis");
List<Blog> blogs = mapper.quarrBlogs2(map);
for (Blog blog : blogs) {
System.out.println(blogs);
}
sqlSession.commit();
sqlSession.close();
}
}
四、set
1)<set> :用于动态更新语句。可以用于动态包含需要更新的列,忽略其它不更新的列。
2)代码实现:
目标:更新title或author信息。
①在BlogMapper中:
public interface BlogMapper {
int updateBlog(Map map);
}
②在BlogMapper.xml中:
<update id="updateBlog" parameterType="com.ali.pojo.Blog">
update mybatis.blog
<set>
<if test="title != null">
title = #{title},
</if>
<if test="author != null" >
author = #{author}
</if>
</set>
where id = #{id}
</update>
③测试:
public class UserMapperTest {
@Test
public void test(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
map.put("title", "java");
mapper.updateBlog(map);
sqlSession.commit();
sqlSession.close();
}
}
五、foreach
1)<for> :对集合进行遍历,尤其是在构建 IN 条件语句的时候。
<!-- 类似于下面sql语句 -->
select * from table where (id=1 or id=2 or id=3)
list = [1, 2, 3]
<foreach item="item" index="index" collection="list"
open="(" separator="or" close=")">
id = #{item}
</foreach>
2)代码实现:
目标:查找id集合中的所有信息。
①在BlogMapper中:
public interface BlogMapper {
List<Blog> quarrBlogs3(Map map);
}
②在BlogMapper.xml中:
<select id="quarrBlogs3" parameterType="map" resultType="com.ali.pojo.Blog">
select * from mybatis.blog
<where>
<foreach collection="ids" item="id" open="(" close=")" separator="or">
id = #{id}
</foreach>
</where>
</select>
③测试:
public class UserMapperTest {
@Test
public void test(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
ArrayList<Integer> ids= new ArrayList<>();
ids.add(1);
ids.add(2);
map.put("ids", ids);
List<Blog> blogs = mapper.quarrBlogs3(map);
for (Blog blog : blogs) {
System.out.println(blogs);
}
sqlSession.commit();
sqlSession.close();
}
}
六、SQL片段
1)功能:将重复的sql语句提出来模块化,类似于java中的将常用代码功能提出来变成函数,使用的时候直接调用,减少代码冗余。
适用于:在单表中操作,并且该sql片段不存在where标签。
2)代码实现:
在上述例子中,我们发现关于判断title和author是否为空的代码经常使用,因此可以将该部分代码提取出来变成sql块。在原代码中用include标签调用。
<sql id="fragment">
<if test="title != null">
and title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</sql>
<select id="quarrBlogs" parameterType="com.ali.pojo.Blog" resultType="com.ali.pojo.Blog">
select * from mybatis.blog
<where>
<include refid="fragment"></include>
</where>
</select>