MyBatis之动态Sql拼接
前言
Mybatis 的映射⽂件中,前⾯我们的 SQL 都是⽐较简单的,有些时候业务逻辑复杂时,我们的 SQL是
动态变化的,在MyBatis之前对于一些复杂的 SQL 对于我们业务开发时候是不支持的,有时候需要我们为了一两个参数从而去编写重复的sql语句,对此,MyBatis提供了动态Sql去根据不同的条件动态的生成sql语句,极大了对复杂业务查询提供了便利性。
例
对此我们可以根据不同的取值,使用不同的Sql去查询。
业务查询实时可以根据id,或者name的传入而决定去查询所有还是根据条件查询。
Where 和 If 标签
MyBatis可以使用where
与if
去动态拼接Sql,从而生成不同的Sql处理业务逻辑。
<select id="findByCondition" parameterType="user" resultType="user">
select * from User
<where>
<if test="id!=0">
and id=#{id}
</if>
<if test="username!=null and username!='' ">
and username=#{username}
</if>
</where>
</select>
where
标签相当于 1==1 表示真值条件if
标签用来条件判断拼接Sql
foreach标签
循环执⾏sql的拼接操作,例如:SELECT * FROM USER WHERE id IN (1,2)。
<select id="findByIds" parameterType="list" resultType="user">
select * from User
<where>
<foreach collection="list" open="id in(" close=")" item="id"
separator=",">
#{id}
</foreach>
</where>
</select>
foreach标签的属性含义如下:
标签⽤于遍历集合,它的属性:
- collection:代表要遍历的集合元素,注意编写时不要写#{}
- open:代表语句的开始部分
- close:代表结束部分
- item:代表遍历集合的每个元素,⽣成的变量名
- sperator:代表分隔符
SQL⽚段抽取
Sql 中可将重复的 sql 提取出来,使⽤时⽤ include 引⽤即可,最终达到 sql 重⽤的⽬的
<!--抽取sql⽚段简化编写-->
<sql id="selectUser" select * from User</sql>
<select id="findById" parameterType="int" resultType="user">
<include refid="selectUser"></include> where id=#{id}
</select>
<select id="findByIds" parameterType="list" resultType="user">
<include refid="selectUser"></include>
<where>
<foreach collection="array" open="id in(" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
可以看到使用 sql
标签将两个sql重复的部分select * from User
抽取出来,再使用include
标签将其引入。
trim
先说一下 trim 标签4个参数:
- prefix
给sql语句拼接的前缀 - suffix
给sql语句拼接的后缀 - prefixOverrides
去除sql语句前面的关键字或者字符,该关键字或者字符由prefixOverrides属性指定,假设该属性指定为"AND",当sql语句的开头为"AND",trim标签将会去除该"AND" - suffixOverrides
去除sql语句后面的关键字或者字符,该关键字或者字符由suffixOverrides属性指定
<select id="findList" resultType="user">
select name,id from user
<trim prefix="where" prefixOverrides="and | or" suffix="order by name" suffixOverrides=",">
<if test="name != null and name != ''">
and name = #{name}
</if>
<if test="sex != null and sex != ''">
and sex = #{sex}
</if>
<if test="loc != null and loc != ''">
and loc = #{loc}
</if>
</trim>
</select>
如果第一个if条件成立 那么 sql 会变成
select name,id from user where name = #{name} …
prefixOverrides 去除了第一个and
suffixOverrides=","
同理 suffixOverrides
会去除最后一个,
的,在update
标签中最常用
choose 标签
有的时候我们并不想应用所有的条件,而只是想从多个选项中选择一个,可以使用choose标签
<select id="getStudentListChoose" parameterType="user" resultMap="user">
SELECT * from User WHERE 1=1
<where>
<choose>
<when test="name!=null and student!='' ">
AND name LIKE CONCAT(CONCAT('%', #{name}),'%')
</when>
<when test="sex!= null and sex!= '' ">
AND sex = #{sex}
</when>
<otherwise>
AND AGE = 15
</otherwise>
</choose>
</where>
</select>
MyBatis动态标签可以方便的处理不同条件下生成不同sql语句的场景,很方便我们业务不同条件下sql查询。