Mybatis---动态SQL(拼接sql语句根据不同的条件生成不同的SQL语句进行复杂查询)
程序员文章站
2024-03-02 12:56:46
...
1.动态SQL
1.1 什么是动态SQL
动态SQL就是指根据不同的条件生成不同的SQL语句
1.2 环境搭建
1.数据库表
-- auto-generated definition
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 '浏览量'
);
2.导包
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
</dependencies>
3.编写核心配置文件
<?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="edu/xalead/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="edu.xalead.dao.BlogMapper"/>
</mappers>
</configuration>
4. 编写实体类
package edu.xalead.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;
}
5.编写实体类对应Mapper接口和Mapper.xml
6.添加一个工具类
-
在com.it.utils中加入IDUtils类,作为可以生成随机id的类,代码:
package edu.xalead.utils; import org.junit.jupiter.api.Test; import java.util.UUID; public class IDUtils { public static String getID(){ return UUID.randomUUID().toString().replaceAll("-","..."); } @Test public void test(){ System.out.println(IDUtils.getID()); } }
-
mapUnderscoreToCamelCase 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。 代码:
12.3开始改造
1.IF
接口代码:
//查询博客
List<Blog> queryBlogIf(Map map);
-
接口.xml代码:(在这里1=1为了sql正常后面会使用where标签)
<select id="queryBlogIf" parameterType="map" resultType="blog"> select * from mybatis_test.blog where 1=1 <if test="title !=null"> and title = #{title} </if> <if test="author != null"> and author = #{author} </if> </select>
-
测试代码:
@Test public void test1(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); BlogMapper mapper = sqlSession.getMapper(BlogMapper.class); Map map = new HashMap(); // map.put("title","vue"); map.put("author","admin"); List<Blog> blogs = mapper.queryBlogIf(map); for (Blog blog : blogs) { System.out.println(blog); } sqlSession.close(); }
2.trim(where , set)
where :保证sql可以正常输出
<select id="queryBlogIf" parameterType="map" resultType="blog">
select * from mybatis_test.blog
<where>
<if test="title !=null">
and title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</where>
</select>
set: update 中
<update id="updateBlog" parameterType="map">
update mybatis_test.blog
<set>
<if test="title != null">
title = #{title},
</if>
<if test="author != null">
author = #{author}
</if>
</set>
where id = #{id};
</update>
trim :可以定制where,set的功能
3.choose(when,otherwise)
相当于switch-case
<select id="queryBlogChoose" parameterType="map" resultType="blog">
select * from mybatis_test.blog
<where>
<choose>
<when test="title !=null">
title = #{title}
</when>
<when test="author !=null">
and author = #{author}
</when>
<otherwise>
and views = #{views}
</otherwise>
</choose>
</where>
</select>
总结:所谓的动态SQL,本质还是SQL语句,只是我们可以在SQL层面,去执行一个逻辑代码
1.4 SQL片段(把sql提取出来)
有时候,我们可能会将一些工共的部分抽取出来,方便复用
-
接口.xml代码:
<sql id="if-title-author"> <!--提取sql片段--> <if test="title !=null"> and title = #{title} </if> <if test="author != null"> and author = #{author} </if> </sql> <select id="queryBlogIf" parameterType="map" resultType="blog"> select * from mybatis_test.blog <where> <!--引入sql片段--> <include refid="if-title-author"/> </where> </select>
注意事项:
- 最好基于单表定义sql片段
- 不要存在where标签
1.5 Foreach
处理大概这类问题
select * from user where 1=1 and (id=0 or id=2 or id=3)
查询id集合对应blog
接口.xml代码:
<!--查询where 1=1 and (id=0 or id=2 or id=3)用foreach-->
<!--类似集合的foreach循环。foreach标签内容分别为:给定一个集合的名字,将取出的内容给定一个名字,开始是的样子(,结尾的样子),分开分隔是or。id和#{id}对应-->
<select id="queryBlogForeach" parameterType="map" resultType="blog">
select * from mybatis_test.blog
<where>
<foreach collection="ids" item="id" open="(" close=")" separator="or">
id = #{id}
</foreach>
</where>
</select>
-
测试代码:
@Test public void test4(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); BlogMapper mapper = sqlSession.getMapper(BlogMapper.class); Map map = new HashMap(); ArrayList<Integer> ids = new ArrayList<Integer>(); ids.add(1); ids.add(2); map.put("ids",ids); List<Blog> blogs = mapper.queryBlogForeach(map); for (Blog blog : blogs) { System.out.println(blog); } sqlSession.close(); }
动态Sql就是在拼接sql语句,我们只要保证sql的正确性,按照Sql的格式,去排列组合就可以了
欢迎访问我的个人博客:http://www.ayjup.cn