一.动态 SQL(XML 版)
1.<if>标签
作用 : 判断参数是否为 null 或满足条件,满足则拼接 SQL ,不满足则跳过
常用属性
test 属性中写的参数名是 Java 属性名,而不是数据库字段
实例 : 动态新增用户
XML
<!-- if标签-->
<insert id="insertUserByCondition">
insert into user_info (
username,
password,
age,
-- java属性名
<if test="gender != null">
gender,
</if>
phone)
values (
#{username},
#{age},
<if test = "gender!=null">
#{gender},
</if>
#{phone});
</insert>
java
//if标签
Integer insertUserByCondition(UserInfo userInfo);
测试代码
java
@Test
void insertUserByCondition() {
UserInfo user = new UserInfo();
user.setId(5);
user.setUsername("updateName");
user.setPassword("updatePwd");
user.setAge((byte) 20);
user.setGender((byte) 1);
user.setPhone("13900139000");
int tmp = userInfoMapperXML.insertUserByCondition(user);
}
2.<trim>标签
作用 : 统一给 SQL片段加前缀,后缀,或自动去除多余前缀(例如 SQL 中的,逗号和多余的 and)
常用属性 :
prefix:整个片段加前缀(如(/SET/WHERE)suffix:整个片段加后缀(如))prefixOverrides:要去掉的开头多余字符suffixOverrides:要去掉的末尾多余字符(最常用:,)
XML
<!-- trim标签 -->
<insert id = "insertUserByTrim">
insert into user_info
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test =" username != null">
username,
</if>
<if test="password!=null">
`password`,
</if>
<if test="age!=null">
age,
</if>
<if test="gender!=null">
gender,
</if>
<if test="phone!=null">
phone,
</if>
</trim>
values
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test =" username != null">
#{username},
</if>
<if test="password!=null">
#{password},
</if>
<if test="age!=null">
#{age},
</if>
<if test="gender!=null">
#{gender},
</if>
<if test="phone!=null">
#{phone},
</if>
</trim>
</insert>
java
//trim标签
Integer insertUserByTrim(UserInfo userInfo);
测试代码
java
@Test
void insertUserByTrim() {
UserInfo user = new UserInfo();
user.setId(5);
user.setUsername("updateName");
user.setPassword("updatePwd");
user.setAge((byte) 20);
user.setGender((byte) 1);
user.setPhone("13900139000");
int tmp = userInfoMapperXML.insertUserByCondition(user);
}
以上 sql 动态解析时会做以下处理 :
- prefix,加上前缀 : (
- suffix,加上后缀 : )
- suffixOverrides 会去掉最后一个多余的逗号
3.<where>标签
作用 :
自动生成 where 关键字
删除开头多余的 and/or
没有条件时,不会生成 where,避免语法错误
<where>标签也可以使用<trim prefix = "where" prefixOverrides="and">替换
XML
<!--where标签-->
<select id="queryUserByCondition" resultType="com.boop.mybatis.model.UserInfo">
select id,username,age,gender,phone
from user_info
<where>
<if test="age!=null">
and age = #{age}
</if>
<if test="gender!=null">
and gender=#{gender}
</if>
</where>
</select>
测试代码
java
@Test
void queryUserByCondition() {
UserInfo user = new UserInfo();
user.setAge((byte)18);
List<UserInfo> tmp = userInfoMapperXML.queryUserByCondition(user);
}
<where>标签也可以使用<trim prefix = "where" prefixOverrides="and">替换
4.<set>标签
作用 :
自动生成 set 关键字
自动删除末尾多余逗号
等价写法 : <trim prefix="set" suffixOverides = ",">
java
//set标签
Integer updateUserByCondition(UserInfo userInfo);
XML
<!-- set标签 -->
<update id="updateUserByCondition">
update user_info
<set>
<if test="username!=null">
username = #{username},
</if>
<if test="age!=null">
age = #{age},
</if>
<if test="deleteFlag!=null">
delrte_flag = #{deleteFlag};
</if>
</set>
where id = #{id}
</update>
测试代码
java
@Test
void updateUserByCondition() {
UserInfo us = new UserInfo();
us.setId(1);//必传参数
us.setDeleteFlag((byte) 1);
us.setUsername("lili");
us.setAge((byte) 266);
int rows = userInfoMapperXML.updateUserByCondition(us);
System.out.println("更新行数:"+rows);
}
5.<foreach>标签
主要属性
collection : 集合名称(方法参数名) , 可以是 List , Set , Map 或对象数组
item : 循环中每一项(#{}中要用到的参数名)
open : 语句块开头字符
close : 语句块结尾字符
separator : 每次遍历之间的分隔符
java
//foreach标签
void deleteByIds(List<Integer> ids);
XML
<!--foreach标签-->
<delete id="deleteByIds">
delete from user_info
where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
测试代码
java
@Test
void deleteByIds() {
List<Integer> ids = Arrays.asList(17,18,19);
userInfoMapperXML.deleteByIds(ids);
System.out.println("批量删除成功,id为"+ids);
}
6.<include>标签
作用 :
把重复的 SQL (如查询字符串,固定条件)抽取成公共片段
多处使用时直接应用 , 便于统一维护
XML
<!-- 定义公共SQL片段 -->
<sql id="baseColumn">
id, username, age, gender, phone, delete_flag, create_time, update_time
</sql>
<!-- 引用片段 -->
<select id="queryAll" resultType="com.boop.mybatis.model.UserInfo">
SELECT <include refid="baseColumn"/>
FROM user_info
WHERE delete_flag = 0
</select>
二.动态 SQL (注解版)
注解版需要使用<script>标签把 SQL 包起来,没有语法提示,容易出错 , 不推荐复杂动态 SQL 使用
java
//动态SQL注解版
@Mapper
public interface UserMapper {
@Insert("<script>" +
"INSERT INTO user_info (username, age" +
"<if test='gender != null'>, gender</if>" +
") VALUES (#{username}, #{age}" +
"<if test='gender != null'>, #{gender}</if>" +
")</script>")
Integer insertUser(UserInfo userInfo);
}