【Spring Boot】Mybatis操作数据库,动态SQL:<if>标签、<trim>标签、<where>标签、<set>标签、<foreach>标签、<sql>和<include>标签
这篇博客详细介绍了MyBatis中动态SQL的使用方法及其重要性。动态SQL能够根据不同条件灵活拼接SQL语句,特别适用于非必填字段的场景。博客首先阐述了动态SQL的作用,随后通过具体示例展示了常用标签的用法:<if>标签:根据条件动态包含SQL片段。<trim>标签:智能处理SQL片段的前后缀(如逗号)。<where>标签:自动生成WHERE子句并处理多余的AND/OR。<set
动态SQL
1.动态SQL的作用?
1.1 动态SQL的作用
当我们注册时需要填写一些信息,有写信息必须填写,有些信息可以不填写,这时我们使用传统的SQL无法满足需求,需要使用动态SQL。
比如,注册时让填写 用户名(必填)、密码(必填)、电话(非必填);
如果使用传统的SQL:
insert into user_info username, password, phone values(?,?,?);
当只填写用户名和密码时,再用上述的SQL语句就会报错,需要改成使用如下的SQL语句:
insert into user_info username, password values(?,?);
当用户填写用户名、密码和电话时使用上述的SQL语句也会报错
上述的文件需要使用动态SQL的方法,动态SQL的实现需要使用标签。
1.2 标签
-
<if> 标签
功能:根据条件动态拼接SQL片段,只有当条件满足时,标签内的SQL才会被包含。
语法:<if test="条件"> SQL片段 </if> -
<trim> 标签
功能:对SQL片段进行前缀或后缀的添加或移除,灵活处理SQL拼接中的多余关键字(如AND、OR、,等)。
语法:<trim prefix="前缀" suffix="后缀" prefixOverrides="移除的前缀" suffixOverrides="移除的后缀"> SQL片段 </trim> -
<where> 标签
功能:专门用于动态生成WHERE子句,自动处理多余的AND或OR,简化WHERE条件的拼接。
语法:<where> SQL条件片段 </where> -
<set> 标签
功能:用于动态生成UPDATE语句中的SET子句,自动移除多余的逗号(,)。
语法:<set> SQL更新片段 </set> -
<sql> 和 <include> 标签
功能:
<sql>:定义可重用的SQL片段。
<include>:引用中定义的片段。
语法:<!-- 定义SQL片段 --> <sql id="片段ID"> SQL内容 </sql> <!-- 引用SQL片段 --> <include refid="片段ID" />
2.准备数据
2.1.MySQL数据准备
(1)创建数据库:
CREATE DATABASE mybatis_study DEFAULT CHARACTER SET utf8mb4;
(2)使用数据库
-- 使⽤数据数据
USE mybatis_study;
(3)创建用户表
-- 创建表[⽤⼾表]
CREATE TABLE `user_info` (
`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
`username` VARCHAR ( 127 ) NOT NULL,
`password` VARCHAR ( 127 ) NOT NULL,
`age` TINYINT ( 4 ) NOT NULL,
`gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-⼥ 0-默认',
`phone` VARCHAR ( 15 ) DEFAULT NULL,
`delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',
`create_time` DATETIME DEFAULT now(),
`update_time` DATETIME DEFAULT now() ON UPDATE now(),
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
(4)添加用户信息
-- 添加⽤⼾信息
INSERT INTO mybatis_study.user_info( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_study.user_info( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_study.user_info( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_study.user_info( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );
2.2.创建对应的实体类
实体类的属性名与表中的字段名⼀⼀对应
@Data
public class UserInfo {
private Integer id;
private String username;
private String password;
private Integer age;
private Integer gender;
private String phone;
private Integer deleteFlag;
private Date createTime;
private Date updateTime;
}

注意:在实际开发中不管什么实体类都要设置删除标志、创建时间、修改时间
3.<if>标签
3.1 在注解中使用
在注解中写标签时需要使用<script></script>标签
Mapper接口:
@Mapper
public interface UserInfoMapper {
@Options(useGeneratedKeys= true, keyProperty = "id")
@Insert("<script>"+
"insert into user_info (username, password, age, "+
"<if test='gender!=null'>gender,</if>"+
"<if test='phone!=null'>phone</if>)"+
"values(#{username}, #{password},#{age},"+
"<if test='gender!=null'> #{gender},</if>"+
"<if test='phone!=null'> #{phone}</if>)"
+"</script>")
Integer Insert(UserInfo userInfo);
}
说明:<if test='gender!=null'> #{gender},</if>中的gender如果不为空,则把#{gender},拼接到SQL字符串中;如果gender为空,则#{gender},不会在SQL语句中出现。
测试代码:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoMapperTest {
@Test
void insert() {
UserInfo userInfo =new UserInfo();
userInfo.setUsername("333");
userInfo.setPassword("333");
userInfo.setAge(20);
// 不填写gender
// userInfo.setGender(1);
userInfo.setPhone("3333");
Integer count = userInfoMapper.Insert(userInfo);
log.info("影响的行数:"+count + " 返回的id:"+ userInfo.getId());
}
SQL中的结果:
如果测试代码改为如下:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoMapperTest {
@Test
void insert() {
UserInfo userInfo =new UserInfo();
userInfo.setUsername("333");
userInfo.setPassword("333");
userInfo.setAge(20);
userInfo.setGender(1);
// userInfo.setPhone("3333");
Integer count = userInfoMapper.Insert(userInfo);
log.info("影响的行数:"+count + " 返回的id:"+ userInfo.getId());
}
}
运行结果:
可以看到Preparing中的SQL语句中多一个,号,需要学习<trim>标签
3.2 在XML文件中实现
Mapper接口:
@Mapper
public interface UserInfoXMLMapper {
//定义接口
Integer insert(UserInfo userInfo);
}
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">
<mapper namespace="org.example.mybatis.mapper.UserInfoXMLMapper">
<insert id = "insert" useGeneratedKeys="true" keyProperty="id">
insert into user_info (username,
password,
age,
<if test="gender!=null">
gender,
</if>
<if test="phone!=null">
phone
</if>
)
values(
#{username},
#{password},
#{age},
<if test="gender!=null">
#{gender},
</if>
<if test="phone!=null">
#{phone}
</if>
)
</insert>
</mapper>
测试类:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoXMLMapperTest {
@Autowired
private UserInfoXMLMapper userInfoXMLMapper;
@Test
void insert() {
UserInfo userInfo= new UserInfo();
userInfo.setUsername("4444");
userInfo.setPassword("4444");
userInfo.setAge(19);
// 不填写gender
// userInfo.setGender(1);
userInfo.setPhone("4444");
Integer count = userInfoXMLMapper.insert(userInfo);
log.info("影响的行数:"+count + " 返回的主键:"+ userInfo.getId());
}
}
运行结果:
MySQL插入的结果:
如果测试代码改为如下:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoXMLMapperTest {
@Autowired
private UserInfoXMLMapper userinfoXMLMapper;
@Test
void insert() {
UserInfo userInfo =new UserInfo();
userInfo.setUsername("333");
userInfo.setPassword("333");
userInfo.setAge(20);
userInfo.setGender(1);
// userInfo.setPhone("3333");
Integer count = userInfoXMLMapper.Insert(userInfo);
log.info("影响的行数:"+count + " 返回的id:"+ userInfo.getId());
}
}
运行结果:
可以看到Preparing中的SQL语句中多一个,号,需要学习<trim>标签
3.3 不使用<if>标签
有同学就会想,把所有的的字段都列出来,想插入什么值就在对象中设置什么值,使用<if>标签不是麻烦了吗!
如下面:
Mapper接口
@Mapper
public interface UserInfoMapper {
@Insert("insert into user_info (username, password, age, gender, phone)"+
"values(#{username}, #{password}, #{age}, #{gender}, #{phone})")
Integer Insert(UserInfo userInfo);
}
测试代码:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoMapperTest {
@Test
void insert() {
UserInfo userInfo =new UserInfo();
userInfo.setUsername("333");
userInfo.setPassword("333");
userInfo.setAge(20);
// 不填写gender
// userInfo.setGender(1);
userInfo.setPhone("3333");
Integer count = userInfoMapper.Insert(userInfo);
log.info("影响的行数:"+count + " 返回的id:"+ userInfo.getId());
}
运行结果:
插入SQL中的结果:
而使用<if>标签插入的结果是0,哪一个是对的呢?
看一下创建表user_info设置的默认值:
gender设置的默认值为0,为什么插入的是null呢?
答:创建的userInfo对象时会把所有属性初始化为默认值,String类型的默认值为null,所以把null作为参数传入了SQL中。
所以,动态SQL需要使用标签。
4.<trim>标签
4.1 标签的属性
当SQL语句中使用多个标签是会出现有,多余的问题,<trim>标签就可以派上用场了。
标签中有如下属性:
(1)prefix:表⽰整个语句块,以prefix的值作为前缀
(2)suffix:表⽰整个语句块,以suffix的值作为后缀
(3)prefixOverrides:表⽰整个语句块要去除掉的前缀
(4)suffixOverrides:表⽰整个语句块要去除掉的后缀
4.2 在注解中使用
Mapper接口:
@Mapper
public interface UserInfoMapper {
@Options(useGeneratedKeys= true, keyProperty = "id")
@Insert("<script>"+
"insert into user_info ("+
"<trim suffixOverrides=','>"+
"username, password, age, "+
"<if test='gender!=null'>gender,</if>"+
"<if test='phone!=null'>phone</if>"+
"</trim>"+
")"+
"values("+
"<trim suffixOverrides=','>"+
"#{username}, #{password},#{age},"+
"<if test='gender!=null'> #{gender},</if>"+
"<if test='phone!=null'> #{phone}</if>"+
"</trim>"+
")"+
"</script>")
Integer Insert(UserInfo userInfo);
}
测试代码:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoMapperTest {
@Autowired
private UserInfoMapper userInfoMapper;
@Test
void insert() {
UserInfo userInfo =new UserInfo();
userInfo.setUsername("444");
userInfo.setPassword("4444");
userInfo.setAge(20);
userInfo.setGender(1);
// userInfo.setPhone("4444");
Integer count = userInfoMapper.Insert(userInfo);
log.info("影响的行数:"+count + " 返回的id:"+ userInfo.getId());
}
}
运行结果:
MySQL:
Mapper最终的改进:
@Mapper
public interface UserInfoMapper {
@Options(useGeneratedKeys= true, keyProperty = "id")
@Insert("<script>"+
"insert into user_info "+
"<trim prefix='(' suffix=')' suffixOverrides=','>"+
"username, password, age, "+
"<if test='gender!=null'>gender,</if>"+
"<if test='phone!=null'>phone</if>"+
"</trim>"+
"values "+
"<trim prefix='(' suffix=')' suffixOverrides=','>"+
"#{username}, #{password},#{age},"+
"<if test='gender!=null'> #{gender},</if>"+
"<if test='phone!=null'> #{phone}</if>"+
"</trim>"+
"</script>")
Integer Insert(UserInfo userInfo);
}
4.3 在XML文件中使用
Mapper接口:
@Mapper
public interface UserInfoXMLMapper {
//定义接口
Integer insert(UserInfo userInfo);
}
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">
<mapper namespace="org.example.mybatis.mapper.UserInfoXMLMapper">
<insert id = "insert" useGeneratedKeys="true" keyProperty="id">
insert into user_info (
<trim suffixOverrides="," >
username,
password,
age,
<if test="gender!=null">
gender,
</if>
<if test="phone!=null">
phone
</if>
</trim>
)
values(
<trim suffixOverrides=",">
#{username},
#{password},
#{age},
<if test="gender!=null">
#{gender},
</if>
<if test="phone!=null">
#{phone}
</if>
</trim>
)
</insert>
测试代码:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoXMLMapperTest {
@Autowired
private UserInfoXMLMapper userInfoXMLMapper;
@Test
void insert() {
UserInfo userInfo= new UserInfo();
userInfo.setUsername("5555");
userInfo.setPassword("5555");
userInfo.setAge(20);
userInfo.setGender(1);
//userInfo.setPhone("5555");
Integer count = userInfoXMLMapper.insert(userInfo);
log.info("影响的行数:"+count + " 返回的主键:"+ userInfo.getId());
}
}
运行结果:
MySQL:
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">
<mapper namespace="org.example.mybatis.mapper.UserInfoXMLMapper">
<insert id = "insert" useGeneratedKeys="true" keyProperty="id">
insert into user_info
<trim prefix="(" suffix=")" suffixOverrides="," >
username,
password,
age,
<if test="gender!=null">
gender,
</if>
<if test="phone!=null">
phone
</if>
</trim>
values
<trim prefix="(" suffix=")" suffixOverrides=",">
#{username},
#{password},
#{age},
<if test="gender!=null">
#{gender},
</if>
<if test="phone!=null">
#{phone}
</if>
</trim>
</insert>
在以上 sql 动态解析时,会将第⼀个 部分做如下处理:
(1)基于prefix配置,开始部分加上配置,结束部分加上“(”
(2)基于suffix配置,结束部分加上“)”
(3)多个 组织的语句可能以,结尾,在最后拼接好的字符串还会以suffixOverrides 配置去掉最后⼀个,
5.<where>标签
需求: 传⼊的用户对象,根据属性做where条件查询,用户对象中属性不为 null 的,都为查询条件.。
如 username 为 “a”,则查询条件为 where username=“a”
5.1 不使用<where>标签
Mapper接口:
@Mapper
public interface UserInfoMapper {
@Select("<script>"+
"select id,username, password, age, gender, phone,delete_flag,create_time,update_time "+
" from user_info "+
" where "+
"<if test ='username!=null'> username=#{username}</if>"+
"<if test ='age!=null'> and age=#{age} </if> "+
"<if test ='phone!=null'> and phone=#{phone}</if>"+
"</script>"
)
List<UserInfo> queryAllUser(UserInfo userInfo);
}
测试代码:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoMapperTest {
@Autowired
private UserInfoMapper userInfoMapper;
@Test
void queryAllUser() {
UserInfo userInfo = new UserInfo();
userInfo.setUsername("lisi");
userInfo.setAge(20);
userInfo.setPhone("lisi");
userInfoMapper.queryAllUser(userInfo);
}
}
运行结果:
把测试代码改为:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoMapperTest {
@Autowired
private UserInfoMapper userInfoMapper;
@Test
void queryAllUser() {
UserInfo userInfo = new UserInfo();
//userInfo.setUsername("lisi");
userInfo.setAge(20);
userInfo.setPhone("lisi");
userInfoMapper.queryAllUser(userInfo);
}
}
运行结果:
把测试代码改为:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoMapperTest {
@Autowired
private UserInfoMapper userInfoMapper;
@Test
void queryAllUser() {
UserInfo userInfo = new UserInfo();
//userInfo.setUsername("lisi");
//userInfo.setAge(20);
//userInfo.setPhone("lisi");
userInfoMapper.queryAllUser(userInfo);
}
}
运行结果:
上述两个问题可以使用在where语句后添加 1=1(不推荐),也可以使用<where>标签解决
5.2 在注解中使用
Mapper接口:
@Mapper
public interface UserInfoMapper {
@Select("<script>"+
"select id,username, password, age, gender, phone,delete_flag,create_time,update_time "+
" from user_info "+
" <where>"+
"<if test ='username!=null'>and username=#{username}</if>"+
"<if test ='age!=null'> and age=#{age} </if> "+
"<if test ='phone!=null'> and phone=#{phone}</if>"+
"</where>"+
"</script>"
)
List<UserInfo> queryAllUser(UserInfo userInfo);
}
测试代码:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoMapperTest {
@Autowired
private UserInfoMapper userInfoMapper;
@Test
void queryAllUser() {
UserInfo userInfo = new UserInfo();
userInfo.setUsername("lisi");
userInfo.setAge(20);
userInfo.setPhone("lisi");
userInfoMapper.queryAllUser(userInfo);
}
}
运行结果:
测试代码:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoMapperTest {
@Autowired
private UserInfoMapper userInfoMapper;
@Test
void queryAllUser() {
UserInfo userInfo = new UserInfo();
//userInfo.setUsername("lisi");
userInfo.setAge(20);
userInfo.setPhone("lisi");
userInfoMapper.queryAllUser(userInfo);
}
}
运行结果:
5.3 在XML文件中使用
Mapper接口:
@Mapper
public interface UserInfoXMLMapper {
List<UserInfo> queryAllUser(UserInfo uerInfo);
}
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">
<mapper namespace="org.example.mybatis.mapper.UserInfoXMLMapper">
<resultMap id="baseMap" type="org.example.mybatis.model.UserInfo">
<id column="id" property="id"></id>
<result column="delete_flag" property="deleteFlag"></result>
<result column="create_time" property="createTime"></result>
<result column="update_time" property="updateTime"></result>
</resultMap>
<select id ="queryAllUser" resultType="org.example.mybatis.model.UserInfo">
select id ,username, password, age, gender, phone,
delete_flag, create_time ,
update_time from user_info
<where>
<if test="username!=null">
and username=#{username}
</if>
<if test="age!=null">
and age=#{age}
</if>
<if test="phone!=null">
and phone=#{phone}
</if>
</where>
</select>
</mapper>
测试代码:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoXMLMapperTest {
@Autowired
private UserInfoXMLMapper userInfoXMLMapper;
@Test
void queryAllUser() {
UserInfo userInfo = new UserInfo();
userInfo.setUsername("lisi");
userInfo.setAge(20);
userInfo.setPhone("lisi");
List<UserInfo> list = userInfoXMLMapper.queryAllUser(userInfo);
for (Object item : list) {
log.info(item.toString());
}
}
}
运行结果:
测试代码:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoXMLMapperTest {
@Autowired
private UserInfoXMLMapper userInfoXMLMapper;
@Test
void queryAllUser() {
UserInfo userInfo = new UserInfo();
//userInfo.setUsername("lisi");
//userInfo.setAge(20);
//userInfo.setPhone("lisi");
List<UserInfo> list = userInfoXMLMapper.queryAllUser(userInfo);
for (Object item : list) {
log.info(item.toString());
}
}
}
运行结果:
6.<set>标签
需求: 根据传⼊的⽤⼾对象属性来更新⽤⼾数据,可以使⽤标签来指定动态内容.接⼝定义: 根据传⼊的⽤⼾ id 属性,修改其他不为 null 的属性
6.1 在注解中使用
Mapper接口:
@Mapper
public interface UserInfoMapper {
@Update(
"<script>"+
"update user_info " +
"<set>"+
"<if test='username!=null'> username=#{username}, </if>" +
"<if test='password!=null'> password=#{password},</if>"+
"<if test='age!=null'> age=#{age},</if>"+
"<if test='gender!=null'>gender=#{gender},</if>"+
"<if test='phone!=null'> phone=#{phone}, </if>"+
"</set>"+
"where id = #{id} "+
"</script>"
)
Integer update(UserInfo userInfo);
}
测试代码:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoMapperTest {
@Test
void update() {
UserInfo userInfo = new UserInfo();
userInfo.setId(3);
userInfo.setUsername("33333");
userInfo.setPhone("33333");
userInfoMapper.update(userInfo);
}
}
运行结果:
MySQL:
6.2 在XML文件中使用
Mapper接口:
@Mapper
public interface UserInfoXMLMapper {
Integer update(UserInfo uerInfo);
}
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">
<mapper namespace="org.example.mybatis.mapper.UserInfoXMLMapper">
<resultMap id="baseMap" type="org.example.mybatis.model.UserInfo">
<id column="id" property="id"></id>
<result column="delete_flag" property="deleteFlag"></result>
<result column="create_time" property="createTime"></result>
<result column="update_time" property="updateTime"></result>
</resultMap>
<update id ="update">
update user_info
<set>
<if test="username!=null">
username=#{username},
</if>
<if test="password!=null">
password=#{password},
</if>
<if test="age!=null">
age=#{age},
</if>
<if test="gender!=null">
gender=#{gender},
</if>
<if test="phone!=null">
phone=#{phone},
</if>
</set>
where id =#{id}
</update>
</mapper>
测试代码:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoXMLMapperTest {
@Autowired
private UserInfoXMLMapper userInfoXMLMapper;
@Test
void update() {
UserInfo userInfo= new UserInfo();
userInfo.setUsername("44444");
userInfo.setPhone("44444");
userInfo.setId(4);
userInfoXMLMapper.update(userInfo);
}
}
运行结果:
MySQL:
6.<foreach>标签
6.1 属性介绍
对集合进⾏遍历时可以使⽤该标签。标签有如下属性:
(1)collection:绑定⽅法参数中的集合,如 List,Set,Map或数组对象
(2)item:遍历时的每⼀个对象
(3)open:语句块开头的字符串
(4)close:语句块结束的字符串
(5)separator:每次遍历之间间隔的字符串
6.2 在注解中使用
需求: 根据多个userid, 删除⽤⼾数据
Mapper接口:
@Mapper
public interface UserInfoMapper {
@Delete("<script>"+
"delete from user_info where id in "+
"<foreach collection='ids' item='id' separator=',' open='(' close=')' >"+
"#{id}"+
"</foreach>"+
"</script>"
)
Integer delete(@Param("ids") List<Integer> ids);
}
测试代码:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoMapperTest {
@Autowired
private UserInfoMapper userInfoMapper;
@Test
void delete() {
List<Integer> list = Arrays.asList(29,30);
userInfoMapper.delete(list);
}
运行结果:
6.3 在XML文件中使用
需求: 根据多个userid, 删除⽤⼾数据
Mapper接口:
@Mapper
public interface UserInfoXMLMapper {
// 定义接口
// 注意,这里要用@param注解明确参数
Integer delete(@Param("ids") List<Integer> ids);
}
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">
<mapper namespace="org.example.mybatis.mapper.UserInfoXMLMapper">
<resultMap id="baseMap" type="org.example.mybatis.model.UserInfo">
<id column="id" property="id"></id>
<result column="delete_flag" property="deleteFlag"></result>
<result column="create_time" property="createTime"></result>
<result column="update_time" property="updateTime"></result>
</resultMap>
<delete id ="delete">
delete from user_info
where id in
<foreach collection="ids" item="id" separator="," open="(" close=")" >
#{id}
</foreach>
</delete>
</mapper>
测试代码:
@Slf4j
@SpringBootTest //启动Sring 容器
class UserInfoXMLMapperTest {
@Autowired
private UserInfoXMLMapper userInfoXMLMapper;
@Test
void delete() {
List<Integer> list = Arrays.asList(25,26,27,28);
userInfoXMLMapper.delete(list);
}
}
运行结果:
7.<sql>和<include>标签
在xml映射⽂件中配置的SQL,有时可能会存在很多重复的⽚段,此时就会存在很多冗余的代码
我们可以对重复的代码⽚段进⾏抽取,将其通过<sql>标签封装到⼀个SQL⽚段,然后再通过<include>进行引用
<sql></sql>定义可重⽤的SQL⽚段
<include>通过属性refid,指定包含的SQL⽚段
如:
<sql id="allColumn">
id, username, age, gender, phone, delete_flag, create_time, update_time
</sql>
通过<include>标签在需要的位置进行引用
<select id="queryAllUser" resultMap="BaseMap">
select
<include refid="allColumn"></include>
from userinfo
</select>
<select id="queryById" resultType="com.example.demo.model.UserInfo">
select
<include refid="allColumn"></include>
from userinfo where id= #{id}
</select>
更多推荐



所有评论(0)