MyBatis注解實(shí)現(xiàn)動(dòng)態(tài)SQL問(wèn)題
MyBatis注解實(shí)現(xiàn)動(dòng)態(tài)SQL
在 Mybatis 中,使用注解可以很方便的進(jìn)行sql操作,但很多動(dòng)態(tài) SQL 都是由 xml 配置實(shí)現(xiàn)的。
而隨著 SpringBoot的逐漸發(fā)展,越來(lái)越多的配置由配置文件轉(zhuǎn)成注解的形式。其中包括動(dòng)態(tài) SQL 。
Mybatis 的注解中,使用太過(guò)長(zhǎng)的sql語(yǔ)句看起來(lái)很不美觀。
@Select("SELECT title from book_tbl where id = #{id}")
如果想要在 mapper 中進(jìn)行非必要關(guān)鍵字的查詢時(shí)就需要使用動(dòng)態(tài) SQL,與 xml 配置不同的是,@Select注解中 SQL 語(yǔ)句必須以 <script> 標(biāo)簽包裹。
@Select("<script>"+ "SELECT id " + "from book_tbl" + "<where>" + "<if test 'company_id != null'>" + "and company_id = #{company_id}" + "</if>" + "<if test 'title != null'>" + "and title like CONCAT('%',#{title},'%')" + "</if>" + "</where>" + "ORDER BY create_time desc,rank desc" + "</script>")
MyBatis動(dòng)態(tài)拼接 SQL參數(shù)
之前用JPA可以在@Query注解上拼接sql,實(shí)現(xiàn)動(dòng)態(tài)查詢;現(xiàn)在用mybatis,如何實(shí)現(xiàn)sql的動(dòng)態(tài)拼接參數(shù)
舉例,在JPA中可以實(shí)現(xiàn)類似于下面的sql拼接
plateNumber2 = plateNumber2 + "," + plateNumber; String[] split = plateNumber2.split(","); StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append("SELECT plate_number from p_park_record where park_key = '"+parkDO.getParkKey()+"'"); stringBuffer.append(" and ("); for (int i = 0; i < split.length; i++) { ? ? stringBuffer.append(" plate_number = "+split[i]); ? ? if (i != split.length-1){ ? ? ? ? stringBuffer.append(" OR "); ? ? } } stringBuffer.append(" )"); stringBuffer.append(" order by sensor_exit_time desc"); stringBuffer.append(" limit 1");
此代碼中,核心問(wèn)題是for循環(huán),將不確定數(shù)量的同一個(gè)參數(shù)做拼接
那么在mybatis中該如何實(shí)現(xiàn)
mybatis實(shí)現(xiàn):
plateNumber2 = plateNumber2 + "," + plateNumber; ParkRecordDO parkRecordDO = new ParkRecordDO(); parkRecordDO.setPlateNumber(plateNumber2); parkRecordDO.setParkKey(parkDO.getParkKey()); String onlyPlateNum = parkRecordMapper.getOnlyPlateNum(parkRecordDO);
? ? <select id="getOnlyPlateNum" parameterType="ParkRecordDO" resultType="java.lang.String"> ? ? ? ? SELECT plate_number from p_park_record where park_key = #{parkKey} and sensor_exit_time is not null and ? ? ? ? <foreach collection="plateNumber.split(',')" index="index" item="id" open="(" separator=" or " close=")"> ? ? ? ? ? ? plate_number = #{id} ? ? ? ? </foreach> ? ? ? ? order by sensor_exit_time desc ? ? ? ? limit 1 ? ? </select>
如此實(shí)現(xiàn),與JPA拼接效果相同,重點(diǎn)在于“<foreach”標(biāo)簽中separator屬性,該屬性為元素之間的分隔符,將分隔符設(shè)置為“or”,以此來(lái)實(shí)現(xiàn)該程序邏輯的拼接
最后補(bǔ)充幾個(gè)知識(shí)點(diǎn)
foreach標(biāo)簽的使用
<!-- ? ? ? ? foreach ? ? ? ? collection:指定要遍歷的集合 ? ? ? ? ? ? ? ? ? ? list類型的參數(shù)會(huì)特殊處理封裝在map中,map的key就叫l(wèi)ist ? ? ? ? ? ? ? item:將當(dāng)前遍歷出的元素賦值給指定的變量 ? ? ? ? ? ? ? separator:元素之間的分割符 ? ? ? ? ? ? ? open: 遍歷出的所有結(jié)果拼接一個(gè)開(kāi)始字符 ? ? ? ? ? ? ? close:遍歷出的所有結(jié)果拼接一個(gè)結(jié)束字符 ? ? ? ? ? ? ? index:索引,遍歷list的時(shí)候是索引,item就是當(dāng)前值; ? ? ? ? ? ? ? ? ? ? ? ? ? 遍歷map時(shí)index標(biāo)識(shí)的就是map的key,item就是map的值 ? ? ? ? ? ? ? #{變量名}: 就能取出變量的值就是當(dāng)前遍歷出的元素 --> <select id="queryUserByForEach" resultType="user"> ? ? select * from easybuy_user where id in ? ? <foreach collection="ids" item="item_id" separator="," ? ? ? ? ? ? ?open="(" close=")"> ? ? ? ? #{item_id} ? ? </foreach> </select> <insert id="batchSaveUser" parameterType="user"> ? ? insert into easybuy_user(loginName, userName, password) values ? ? <foreach collection="userList" item="user" separator=","> ? ? ? ? (#{user.loginName}, #{user.userName}, #{user.password}) ? ? </foreach> </insert>
set標(biāo)簽的使用
<!-- ? ? ? ? 使用set標(biāo)簽或者trim標(biāo)簽與if標(biāo)簽相結(jié)合 ? ? ? ? 實(shí)現(xiàn)動(dòng)態(tài)更新sql語(yǔ)句的拼接 --> <update id="updateUserByCondition" parameterType="user"> ? ? update easybuy_user ? ? <set> ? ? ? ? <if test="userName != null"> ? ? ? ? ? ? username = #{userName}, ? ? ? ? </if> ? ? ? ? <if test="email != null"> ? ? ? ? ? ? email = #{email}, ? ? ? ? </if> ? ? </set> ? ? where id = 26; </update>
choose和when標(biāo)簽的使用(作用類似與java中的switch-case)
<select id="queryUserByChoose" resultType="com.unistart.entity.User"> ? ? select * from easybuy_user ? ? <where> ? ? ? ? <choose> ? ? ? ? ? ? <when test="id != null"> ? ? ? ? ? ? ? ? id=#{id} ? ? ? ? ? ? </when> ? ? ? ? ? ? <when test="userName != null"> ? ? ? ? ? ? ? ? userName like #{userName} ? ? ? ? ? ? </when> ? ? ? ? ? ? <when test="sex != null"> ? ? ? ? ? ? ? ? sex = #{sex} ? ? ? ? ? ? </when> ? ? ? ? ? ? <otherwise> ? ? ? ? ? ? ? ? 1=1; ? ? ? ? ? ? </otherwise> ? ? ? ? </choose> ? ? </where> </select>
trim標(biāo)簽的使用
<!-- ? ? ? ? trim標(biāo)簽的使用:解決后面多出的and或or ? ? ? ? prefix="":前綴,trim標(biāo)簽體中是整個(gè)字符串拼串后的結(jié)果 ? ? ? ? ? ? ? ? prefix給拼串后的整個(gè)字符串加一個(gè)前綴 ? ? ? ? prefixOverrides="":前綴覆蓋:去掉整個(gè)字符串前面多余的字符 ? ? ? ? suffix="":后綴,給拼串后的整個(gè)字符串加一個(gè)后綴 ? ? ? ? suffixOverrides="":后綴覆蓋,去掉整個(gè)字符串后面多余的字符 --> <select id="queryUserByTrim" resultType="user"> ? ? select * from easybuy_user ? ? <trim prefix="where" suffixOverrides="and"> ? ? ? ? <if test="id != null"> ? ? ? ? ? ? id = #{id} and ? ? ? ? </if> ? ? ? ? <if test="userName != null and userName!="""> ? ? ? ? ? ? userName like #{userName} and ? ? ? ? </if> ? ? ? ? <if test="email != null and email!="""> ? ? ? ? ? ? email = #{email} and ? ? ? ? </if> ? ? </trim> </select>
where標(biāo)簽的使用
<!-- ? ? ? ? 查詢用戶:要求,攜帶哪些字段查詢條件就按這些字段進(jìn)行查詢 ? ? ? ? 使用的OGNL,類似與EL表達(dá)式 ? ? ? ? 從參數(shù)中取值進(jìn)行判斷,遇見(jiàn)特殊符號(hào)使用轉(zhuǎn)義字符 ? ? ? ? 使用where標(biāo)簽時(shí)要注意,它只能去除第一個(gè)多出來(lái)的and或or --> <select id="queryUserByCondition" resultType="user"> ? ? select * from easybuy_user ? ? <where> ? ? ? ? <if test="id != null"> ? ? ? ? ? ? and id = #{id} ? ? ? ? </if> ? ? ? ? <if test="userName != null and userName!="""> ? ? ? ? ? ? and userName like #{userName} ? ? ? ? </if> ? ? ? ? <if test="email != null and email!="""> ? ? ? ? ? ? and email = #{email} ? ? ? ? </if> ? ? </where> </select>
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java Iterator迭代器與foreach循環(huán)代碼解析
這篇文章主要介紹了Java-Iterator迭代器與foreach循環(huán),主要包括Iterator迭代器接口的操作方法和foreach 循環(huán)語(yǔ)法解析,需要的朋友可以參考下2022-04-04Spring中BeanFactory和ApplicationContext的作用和區(qū)別(推薦)
這篇文章主要介紹了Spring中BeanFactory和ApplicationContext的作用和區(qū)別,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09一篇文章教你如何用Java自定義一個(gè)參數(shù)校驗(yàn)器
這篇文章主要介紹了使用java自定義一個(gè)參數(shù)校驗(yàn)器,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)2021-09-09SpringBoot中注冊(cè)Bean的10種方式總結(jié)
在Spring Boot應(yīng)用中,Bean是構(gòu)成應(yīng)用的核心組件,Spring容器負(fù)責(zé)管理這些Bean,包括它們的創(chuàng)建、配置、組裝、管理和銷毀,在Spring Boot中,有多種方式可以注冊(cè)Bean,本文將詳細(xì)介紹這些不同的注冊(cè)方式,并給出相應(yīng)的示例代碼和適用場(chǎng)景,需要的朋友可以參考下2024-08-08