动态 SQL:
动态SQL 是Mybatis的强⼤特性之⼀,能够完成不同条件下不同的 sql 拼接。
1. <if> 标签:
Mapper.xml实现:
<insert id="insertByCondition">
insert into userinfo (username, password, age
<if test="gender != null">
, gender
</if>
) values (#{username}, #{password}, #{age}
<if test="gender != null">
, #{gender}
</if>
)
</insert>
2. <trim>标签
-
prefix:表示整个语句块,以prefix的值作为前缀
-
suffix:表示整个语句块,以suffix的值作为后缀
-
prefixOverrides:表示整个语句块要去除掉的前缀
-
suffixOverrides:表示整个语句块要去除掉的后缀
Mapper.xml实现:
<insert id="insertByCondition">
insert into userinfo
<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>
</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>
</trim>
</insert>
在以上sql动态解析时,会做如下处理:
- 基于prefix配置,开始部分加上 (
- 基于suffix配置,结束部分加上 )
- 多个组织的语句都以 逗号 结尾,在最后拼接好的字符串还会以 逗号 结尾,会基于suffixOverrides配置去掉最后一个 逗号
注解实现方式(不推荐):
@Insert("<script>" +
"insert into userinfo " +
"<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> " +
"</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> " +
"</trim>" +
"</script>")
Integer insertByCondtion(UserInfo userInfo);
3. <where>标签
Mapper.xml实现:
<select id="queryUserByCondition" resultType="com.code.mybatis.model.UserInfo">
select * from userinfo
<trim prefix="where" prefixOverrides="and">
<if test="age != null">
age = #{age}
</if>
<if test="gender != null">
and gender = #{gender}
</if>
<if test="deleteFlag != null">
and delete_flag = #{deleteFlag}
</if>
</trim>
</select>
将 <trim prefix="where" prefixOverrides="and"> 改为 <where> :
<select id="queryUserByCondition" resultType="com.code.mybatis.model.UserInfo">
select * from userinfo
<where>
<if test="age != null">
age = #{age}
</if>
<if test="gender != null">
and gender = #{gender}
</if>
<if test="deleteFlag != null">
and delete_flag = #{deleteFlag}
</if>
</where>
</select>
where 标签可以 生成 where 关键字,并且去除最前面的 and 或者 or;
如果 where 标签代码块没有一个查询条件,则省略掉 where 关键字。
4. <set>标签
Mapper.xml实现:
<update id="updateByCondition">
update userinfo
<trim prefix="set" suffixOverrides=",">
<if test="password !=null">
password = #{password},
</if>
<if test="age !=null">
age = #{age},
</if>
<if test="gender !=null">
gender = #{gender}
</if>
</trim>
where id = #{id}
</update>
将 <trim prefix="set" suffixOverrides=","> 改为 <set> :
<update id="updateByCondition">
update userinfo
<set>
<if test="password !=null">
password = #{password},
</if>
<if test="age !=null">
age = #{age},
</if>
<if test="gender !=null">
gender = #{gender}
</if>
</set>
where id = #{id}
</update>
set 标签可以 生成 set 关键字,并且去除整个代码块后面的 逗号;
5. <foreach>标签
-
collection: 绑定方法参数中的集合,如List,Set,Map或数组对象
-
item: 遍历时的每一个对象
-
open: 语句块开头的字符串close:语句块结束的字符串
-
separator: 每次遍历之间间隔的字符串
接口方法:
Integer batchDelete(List<Integer> ids);
Mapper.xml实现:
<delete id="batchDelete">
delete from userinfo
where id in
-- (1, 2, 3 ,4)
<foreach collection="ids" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</delete>
测试方法:
@Test
void batchDelete() {
List<Integer> ids = Arrays.asList(new Integer[]{2,3 ,11,12});
userInfoXmlMapper.batchDelete(ids);
}
6. <include>标签
将冗余重复的代码提取出来,简化代码。
-
<sql>:定义可重用的SQL片段
-
<include>:通过属性refid,指定包含的SQL片段
<sql id="selectAll">
select * from userinfo
</sql>
<select id="selectAllUser" resultType="com.code.mybatis.model.UserInfo">
<include refid="selectAll"></include>
</select>
【补充】XML 可以使用 generator 插件实现:
插件一般在项目初始化时使用:
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.5</version>
<configuration>
<!--generator配置文件所在位置-->
<configurationFile>src/main/resources/generator/generatorConfig.xml</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
</dependencies>
</plugin>
注意,文件名、路径、密码、文件的目录的修改,顺序不可更改。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<!-- 配置生成器 -->
<generatorConfiguration>
<!-- 一个数据库一个context -->
<context id="MysqlTables" targetRuntime="MyBatis3Simple" defaultModelType="flat">
<!--去除注释-->
<commentGenerator>
<property name="suppressDate" value="true"/>
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!--数据库链接信息-->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://127.0.0.1:3306/mybatis_test?serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true"
userId="root"
password="123456">
</jdbcConnection>
<!-- 生成实体类 -->
<javaModelGenerator targetPackage="com.code.generator.model" targetProject="src/main/java" >
<property name="enableSubPackages" value="false"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- 生成mapxml文件 -->
<sqlMapGenerator targetPackage="mapperGenerator" targetProject="src/main/resources" >
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- 生成mapxml对应client,也就是接口dao -->
<javaClientGenerator targetPackage="com.code.generator.mapper" targetProject="src/main/java" type="XMLMAPPER" >
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- table可以有多个,每个数据库中的表都可以写一个table,tableName表示要匹配的数据库表,
也可以在tableName属性中通过使用%通配符来匹配所有数据库表,只有匹配的表才会自动生成文件 -->
<table tableName="userinfo">
<property name="useActualColumnNames" value="false" />
<!-- 数据库表主键 -->
<generatedKey column="id" sqlStatement="Mysql" identity="true" />
</table>
<table tableName="articleinfo">
<property name="useActualColumnNames" value="false" />
<!-- 数据库表主键 -->
<generatedKey column="id" sqlStatement="Mysql" identity="true" />
</table>
</context>
</generatorConfiguration>
总结:
简单SQL 使用注解相对更好用,复杂SQL 使用XML更好用,注解和XML可以一起使用。
如果觉得作者写得还不错的话, 点赞 / 收藏 / 评论 / 转发 四连支持一下吧~😘
最重要的是点一个大大的关注, 你的支持就是作者创作的最大动力!!!