Mybaits 框架的动态 SQL 技术是一种根据特定条件动态拼接 SQL 语句的功能 , 它存在的意义是为了解决拼接 SQL 语句字符串时的痛点问题
Mybatis 中动态 SQL 怎么理解?有什么作用?怎么去实现?
Mybatis 的动态 SQL 是指可以根据不同的条件动态生成 SQL 语句。它的作用主要是实现动态生成不同的 SQL 语句,以达到更灵活、高效的查询、更新、删除等操作。它大大增强了 SQL 动态适配的能力。
动态 SQL 的实现主要有两种方式:基于 XML 的实现和基于注解的实现。
例如,以下是一个使用了 if 和 where 的例子:
<select id="queryByStatus" resultType="User">
SELECT * FROM user WHERE 1=1
<if test="status != null">
AND status = #{status}
</if>
<if test="username != null">
AND username like '%'||#{username}||'%'
</if>
</select>
例如,以下是一个使用@SelectProvider 注解的例子:
@SelectProvider(type = SqlProvider.class, method = "queryByStatus")
List<User> queryByStatus(String status, String username);
其中,SqlProvider 是一个动态 SQL 的提供类,其中 queryByStatus 方法返回一个字符串类型的 SQL 语句,该方法根据用户实际传入的参数动态生成 SQL 语句。
动态 SQL 的实现可以根据实际的业务需求和场景,选择基于 XML 或注解两种方式进行编写。使用动态 SQL 可以方便地生成不同的 SQL 语句,使得查询、插入、更新等操作更加灵活、高效。同时,也需要注意 SQL 注入和动态 SQL 的维护难度问题。
if 标签可通过test属性
的表达式进行判断 , 若表达式的结果为 true , 则标签中的内容会执行 ; 反之标签中的内容不会执行
if 中 test 属性判断的是实体类当中属性的值
语法展示:
<select id="getEmpByCondition" resultType="Emp">
select * from t_emp where
<if test="empName != null and empName != '' ">
emp_name = #{empName}
</if>
<if test="age != null and age != ''">
and age = #{age}
</if>
<if test="gender != null and gender != ''">
and gender = #{gender}
</if>
</select>
where 和 if 一般结合使用:
注意:where 标签不能去掉条件最后多余的 and
<select id="getEmpByCondition" resultType="Emp">
select * from t_emp
<where>
<if test="empName != null and empName != '' ">
emp_name = #{empName}
</if>
<if test="age != null and age != ''">
and age = #{age}
</if>
<if test="gender != null and gender != ''">
and gender = #{gender}
</if>
</where>
</select>
trim 用于去掉或添加标签中的内容
常用属性:
<select id="getEmpByCondition" resultType="Emp">
select * from t_emp
<trim prefix="where" suffixOverrides="and">
<if test="empName != null and empName != '' ">
emp_name = #{empName} and
</if>
<if test="age != null and age != ''">
age = #{age} and
</if>
<if test="gender != null and gender != ''">
gender = #{gender}
</if>
</trim>
</select>
choose、when、 otherwise 相当于 if...else if..else
<select id="getEmpByChose" resultType="Emp">
select * from t_emp
<where>
<choose>
<when test="empName != null and empName != ''">
emp_name = #{empName}
</when>
<when test="age != null and age != ''">
age = #{age}
</when>
<when test="gender != null and gender != ''">
gender = #{gender}
</when>
</choose>
</where>
</select>
<!--int insertMoreEmp(List<Emp> emps);-->
<insert id="insertMoreEmp">
insert into t_emp values
<foreach collection="emps" item="emp" separator=",">
(null,#{emp.ename},#{emp.age},#{emp.sex},#{emp.email},null)
</foreach>
</insert>
<!--int deleteMoreByArray(int[] eids);-->
<delete id="deleteMoreByArray">
delete from t_emp where
<foreach collection="eids" item="eid" separator="or">
eid = #{eid}
</foreach>
</delete>
<!--int deleteMoreByArray(int[] eids);-->
<delete id="deleteMoreByArray">
delete from t_emp where eid in
<foreach collection="eids" item="eid" separator="," open="(" close=")">
#{eid}
</foreach>
</delete>
Mybatis 中的 foreach 标签用于循环遍历一个集合,动态生成 SQL 中的 in 语句。它的作用主要是构建动态 SQL 语句,一般用于 IN 查询、批量插入、更新和删除等操作。
foreach 标签的使用方法如下:
<select id="selectByIds" resultMap="userResultMap">
SELECT * from user WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
上述代码中,ids
是一个列表,在 SQL 执行时,会将集合中的元素遍历一遍,生成类似于 (1, 2, 3)
的 SQL 语句。其中,open
、separator
、close
等属性用于定义拼接语句的开头、元素间的分隔符和结尾。
除了对于 IN 语句拼接,foreach 标签还可以用于批量插入、更新和删除等操作,例如:
<insert id="batchInsert" parameterType="java.util.List" useGeneratedKeys="true">
INSERT INTO user (username, password) VALUES
<foreach collection="users" item="user" separator=",">
(#{user.username}, #{user.password})
</foreach>
</insert>
<update id="batchUpdate" parameterType="java.util.List">
UPDATE user SET
<foreach collection="users" item="user" separator=",">
password = #{user.password}
</foreach>
WHERE id IN
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</update>
<delete id="batchDelete" parameterType="java.util.List">
DELETE FROM user WHERE id IN
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
这三个示例分别是批量插入、批量更新和批量删除的实现方式。注意,这里 users
和 ids
也是列表,分别代表了待插入的用户和需要操作的记录的 ID。
通过使用 foreach 标签,Mybatis 使得动态 SQL 的拼接变得灵活而高效。可以通过遍历集合,动态生成 SQL 语句,以达到动态适配的目的。
sql 片段 , 可以记录一段公共 sql 片段 , 在使用的地方通过 include 标签进行引入
<sql id="empColumns">
eid,ename,age,sex,did
</sql>
select <include refid="empColumns"></include> from t_emp
Mybatis 中的 SQL 片段是一段预编译的 SQL 语句,它可以被多次使用。SQL 片段的作用是将常用的 SQL 语句封装成一个可重用的组件,方便在多个地方使用。
Mybatis 中的 SQL 片段有两种类型:
Mybatis 中的 SQL 片段可以通过 XML 文件或注解的方式定义,其中 XML 文件是一种常见的方式。在 XML 文件中,可以使用 <select> 、<update>、<insert>
等标签来定义 SQL 片段,并通过参数绑定来实现动态 SQL 的功能。
SQL 片段(SQL Fragments)是 Mybatis 中一个重要的功能,它的作用是将一段 SQL 片段用 <sql>
元素封装,并在需要的地方通过 <include>
元素引用。主要有以下几个作用:
在 Mybatis 的 Mapper XML 文件中,可以在 <sql>
标签中定义 SQL 片段,例如:
<sql id="queryColumns">
id, username, password
</sql>
然后在其他的 SQL 语句中,通过 <include>
元素引用该 SQL 片段:
<select id="selectById" parameterType="int" resultMap="userResultMap">
SELECT <include refid="queryColumns"/> FROM user WHERE id = #{id}
</select>
上述语句中,使用 <include>
引用了 SQL 片段 "queryColumns" 中定义的代码 id, username, password
,简化了 SQL 语句的编写。
通过使用 SQL 片段,可以方便地提高代码复用和维护的效率,使 SQL 代码更加清晰和易于阅读和理解。