文章目录
之前文章Mybatis系列(十一)mapper映射文件之insert,update,delete,Mybatis系列(十)mapper映射文件之select元素(一对一,一对多,多对多)主要介绍mybatis关于CRUD的操作,其实mybatis还有强大的动态SQL,今天就让我们一探究竟吧。
一、动态SQL的元素
元素 | 作用 | 备注 |
---|---|---|
if | 判断语句 | 单条件分支判断 |
choose(when,otherwise) | 相当于java中的switch和case语句 | 多条件分支判断 |
trim(when,set) | 辅助元素,用于处理特定的SQL拼接问题,比如去掉多余的and,or | 用于处理SQL拼接 |
foreach | 循环语句 | 在in语句等列举条件常用 |
简单的介绍后,我们就来看看怎么用吧
二、if元素
<select id="findUserByName" parameterType="java.lang.String" resultType="com.sean.entity.User">
SELECT * FROM user WHERE
<if test="name !=null">
name = #{name}
</if>
and age=20
</select>
如果传name不等于null,就作为where条件进行拼接,如果为空岂不是很尴尬,语句变成了SELECT * FROM user WHERE and age=20
,别怕我们有where语句(当然项目中也有加入where 1=1 )
if,和where元素中出现There is no getter for property named 'name' in 'class java.lang.String
,报错怎么解决,请移步这篇文章
Mybatis异常There is no getter for property named ‘name’ in ‘class java.lang.String’
三、where元素
<select id="findUserByName" parameterType="java.lang.String" resultType="com.sean.entity.User">
SELECT * FROM user
<where>
<if test="name !=null">
name = #{name}
</if>
and age=20
</where>
</select>
这样当where元素里边的条件成立时,才会加入where这个SQL关键字组装到SQL里边,否则不加入。
四、trim元素
有时候要去掉一些特殊的SQL语句,比如常见的and,or。使用trim元素也能到达预期的效果
上边where元素就可以写成这样
<select id="findUserByName" parameterType="java.lang.String" resultType="com.sean.entity.User">
SELECT * FROM user
<trim prefix="where" prefixOverrides="and">
<if test="name !=null">
name = #{name}
</if>
and age=20
</trim>
</select>
trim元素意味着要去掉一些特殊的字符串,prefix
代表的是语句的前缀,prefixOverrides
代表的是需要去掉哪种字符串。
五、set元素
与where一样的用法
<update id="updateUserByName">
update user
<set>
<if test="mobile != null">
mobile = #{mobile}
</if>
<if test="age != null">
age = #{age}
</if>
</set>
where name = #{name}
</update>
上边的set语句用trim也可以这样写
<update id="updateUserByName">
update user
<trim prefix="set" suffixOverrides=",">
<if test="mobile != null">
mobile = #{mobile},
</if>
age = 20,
</trim>
where name = #{name}
</update>
WHERE是使用的 prefixOverrides(前缀), SET是使用的 suffixOverrides (后缀),可以把age=20 后的逗号去掉
六、foreach元素
java有种for循环,mybatis有foreach,循环的对象一般是java数组或者集合
<select id="findUserByAge" resultType="com.sean.entity.User">
SELECT * FROM user where age in
<foreach item="age" index="index" collection="ageArray"
open="(" separator="," close=")">
#{age}
</foreach>
</select>
List<User> findUserByAge(@Param("ageArray") int[] ageArray);
- collection配置的ageArray是传递进来的参数名称,它可以是一个数组,List,Set等集合
- item配置的是循环中当前的元素
- index配置的是当前元素在集合中的位置下标
- open,close配置的是以什么符号将这些数组元素包装起来
- separator是各个元素的间隔符
七、choose元素
<select id="findUser" resultType="com.sean.entity.User">
SELECT * FROM user
<where>
<choose>
<when test="name != null">
name = #{name}
</when>
<when test="age != null">
age = #{age}
</when>
<otherwise>
mobile =#{mobile}
</otherwise>
</choose>
</where>
</select>
User findUser(@Param("age") Integer age,@Param("name") String name,@Param("mobile") String mobile);
八、mybatis中like怎么写
有两种写法,不要在SQL中拼接,会造成SQL注入的安全问题
1.concat
<select id="findUserByName" parameterType="java.lang.String" resultType="com.sean.entity.User">
SELECT * FROM user
<trim prefix="where" prefixOverrides="and">
<if test="name !=null">
name like concat('%',#{name},'%')
</if>
and age=20
</trim>
</select>
2.bind
<select id="findUserByName" parameterType="java.lang.String" resultType="com.sean.entity.User">
<bind name="pattern" value="'%' + name + '%'"></bind>
SELECT * FROM user
<trim prefix="where" prefixOverrides="and">
<if test="name !=null">
name like #{pattern}
</if>
and age=20
</trim>
</select>
九、mybatis中 大于,小于号怎么写
- 使用xml语法转义:
>
为大于号“ >”;<
为小于号 “<” ;
<select id="findUserByNameAndTime" parameterType="java.lang.String" resultType="com.sean.entity.User">
SELECT * FROM user
<trim prefix="where" prefixOverrides="and">
<if test="name !=null">
name like concat('%',#{name},'%')
</if>
and create_time <= #{createTime}
</trim>
</select>
- 使用<![CDATA[]]>,因为CDATA 部分中的所有内容都会被解析器忽略,所以建议使用<![CDATA[]]>
<select id="findUserByNameAndTime" parameterType="java.lang.String" resultType="com.sean.entity.User">
SELECT * FROM user
<trim prefix="where" prefixOverrides="and">
<if test="name !=null">
name like concat('%',#{name},'%')
</if>
<![CDATA[ and create_time <= #{createTime} ]]>
</trim>
</select>
两种方法打印的执行SQL
Preparing: SELECT * FROM user where name like concat('%',?,'%') and create_time <= ?