动态SQL是Mybatis的一大重要特性,它可以完成不同条件下的SQL拼接,降低了因为SQL语句书写中的小错误而造成程序报错的概率,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号,利用动态SQL就可以解决这些难题。
常见动态SQL标签:
- <if>
- <where>
- <choose> <when> <otherwise>
- <set>
- <foreach>
- <trim>
目录
实体类及数据库相关配置
实体类
数据库连接配置
数据库数据
标签
sql语句
测试结果
标签
sql语句
测试结果
choose> 标签
sql语句
测试结果
标签
sql语句
测试结果
标签
sql语句
测试结果
标签
标签可以替换其他标签
实体类及数据库相关配置
实体类
@Data //加上lombok注解 方便对实体类进行操作
public class UserInfo {
private Integer id;
private String username;
private String password;
}
数据库连接配置
# 配置数据库连接
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/blog?characterEncoding=utf8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# 设置日志级别
logging:
level:
com:
example:
demo: debug
mybatis:
# 配置 mybatis xml 文件的保存路径
mapper-locations: classpath:/mybatis/**Mapper.xml
# 开启 MyBatis SQL 打印
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
数据库数据
<if>标签
作用:判断一个参数是否有值,如果没有值就会隐藏if中的sql语句
sql语句
<select id="getUserById" resultType="com.example.demo.model.UserInfo">
select * from userinfo where 1= 1
<if test="id!=null">
and id=#{id}
</if>
</select>
测试结果
输入id:
不传入id:
传入id时,就会拼接if标签内的sql语句,否则不进行拼接。
<where>标签
上述使用if语句进行查询时我们加了一个条件where 1=1,这个语句是为了保证语句成立的,不至于程序报错,但是Mybatis中设计了更好的方法,就是把<where>也作为一个标签元素,从而达到动态添加where的效果
作用:实现查询中的where sql替换的,如果没有任何查询条件,那么它可以隐藏查询中的where sql,如果存在查询条件,那么会生成where的sql查询,并且where标签可以自动去除最前面的一个and字符
sql语句
<select id="getUserById" resultType="com.example.demo.model.UserInfo">
select * from userinfo
<where>
<if test="id!=null">
and id=#{id}
</if>
</where>
</select>
测试结果
传入id:
不传入id:
在查找时,如果传入id就会拼接条件查询的语句,否则不拼接查询表内所有数据。
choose> <when> <otherwise>标签
在使用< if >元素时,只要test属性中的表达式为true,就会执行元素中的条件语句,但是在实际应用中,有时只需要从多个选项中选择一个去执行。在这种场景下,使用< if > 元素进行处理是非常不合理的。如果使用的是Java语言,这种情况显然更适合switch语句来处理,那么MyBatis中有没有类似的语句呢?当然是有的。针对上面的情况,MyBatsi可以用< choose >,< when >,< otherwise >元素组合去实现上面的情况
作用:从多个选项中选择一个去进行sql语句的拼接
sql语句
<select id="getUserByChoose" resultType="com.example.demo.model.UserInfo">
select * from userinfo
<where>
<choose>
<when test="id!=null">
id=#{id}
</when>
</choose>
<choose>
<when test="username!=null">
username=#{username
</when>
</choose>
<choose>
<when test="password!=null">
password=#{password}
</when>
</choose>
</where>
</select>
测试结果
当条件满足其中一项时后面就不会再去匹配,这里id匹配正确就会停止后面username以及password的匹配(不管这两个字段是否匹配成功),当所输入的字段均不能被匹配也可以使用<otherwise>标签返回默认值。
<set>标签
作用:进行修改操作时,配合if标签来处理非必要传输,会自动去除最后一个英文逗号
sql语句
<update id="update">
update userinfo
<set>
<if test="id!=null">
id=#{id},
</if>
<if test="username!=null">
username=#{username},
</if>
<if test="password!=null">
password=#{password}
</if>
</set>
where id=#{id}
</update>
测试结果
<foreach>标签
作用:对集合进行循环
<foreach>标签中的主要属性介绍:
- collection:绑定方法参数中的集合,如List、Set、Map或数组对象
- item:遍历时的每一个对象
- open:语句块开头的字符串
- close:语句块结束的字符串
- separator:每次遍历之间间隔的字符串
sql语句
<delete id="deleteByIds">
delete from userinfo where id in
<foreach collection="ids" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</delete>
测试结果
<trim>标签
作用:相当于替换,也可以去除 SQL 语句前后多余的某个字符
<trim>标签中的主要属性介绍:
- prefix:表示整个语句块,以prefix的值作为前缀
- suffix:表示整个语句块,以suffix的值作为前缀
- prefixOverrides:表示整个语句块要去掉的前缀
- suffixOverrides:表示整个语句块要去掉的后缀
<trim>标签可以替换其他标签
<where> 等于 <trim prefix="where" prefixOverrides="and">
<set> 等于 <trim prefix="set" suffixOverrides=",">