文章目錄
之前文章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 <= ?