Mybatis動態(tài)SQL實(shí)例詳解
動態(tài)SQL
什么是動態(tài)SQL?
MyBatis的官方文檔中是這樣介紹的?
動態(tài) SQL 是 MyBatis 的強(qiáng)大特性之一。如果你使用過 JDBC 或其它類似的框架,你應(yīng)該能理解根據(jù)不同條件拼接 SQL 語句有多痛苦,例如拼接時(shí)要確保不能忘記添加必要的空格,還要注意去掉列表最后一個(gè)列名的逗號。利用動態(tài) SQL,可以徹底擺脫這種痛苦。
使用動態(tài) SQL 并非一件易事,但借助可用于任何 SQL 映射語句中的強(qiáng)大的動態(tài) SQL 語言,MyBatis 顯著地提升了這一特性的易用性。
如果你之前用過 JSTL 或任何基于類 XML 語言的文本處理器,你對動態(tài) SQL 元素可能會感覺似曾相識。在 MyBatis 之前的版本中,需要花時(shí)間了解大量的元素。借助功能強(qiáng)大的基于 OGNL 的表達(dá)式,MyBatis 3 替換了之前的大部分元素,大大精簡了元素種類,現(xiàn)在要學(xué)習(xí)的元素種類比原來的一半還要少。
換句話說,我們可以根據(jù)傳入?yún)?shù)的不同,來執(zhí)行不同的查詢條件。
IF標(biāo)簽:
如何使用?
我們首先創(chuàng)建一個(gè)Mapper接口,起名為:UserMapper ,并增加一個(gè)方法
public interface UserMapper { public List<User> findByCondition(User user); }
同時(shí)創(chuàng)建一個(gè)xml文件,起名為UserMapper.xml 然后編寫SQL
<mapper namespace="com.dxh.dao.UserMapper"> <select id="findByCondition" parameterType="com.dxh.pojo.User" resultType="com.dxh.pojo.User"> SELECT * FROM user where 1=1 <if test="id != null"> and id = #{id} </if> <if test="username != null"> and username = #{username} </if> </select> </mapper>
這個(gè)SQL的意思是:
- 當(dāng)id不為null的時(shí)候執(zhí)行的SQL是:SELECT * FROM user where id = #{id}
- 當(dāng)id為null的時(shí)候執(zhí)行的SQL是 SELECT * FROM user where 1=1
很明顯我們可以看到where 1=1 是多余的,因此我們可以這樣寫:
<select id="findByCondition" parameterType="com.dxh.pojo.User" resultType="com.dxh.pojo.User"> SELECT * FROM user <where> <if test="id != null"> and id = #{id} </if> <if test="username != null"> and username = #{username} </if> </where> </select>
測試:
編寫一個(gè)測試類:
package com.dxh.test; import com.dxh.dao.UserMapper; import com.dxh.pojo.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.List; public class TestMain { @Test public void test1() throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = build.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = new User(); user.setId(1); List<User> byCondition = mapper.findByCondition(user); for (User user1 : byCondition) { System.out.println(user1); } System.out.println("======"); User user2 = new User(); List<User> byCondition2 = mapper.findByCondition(user2); for (User user3 : byCondition2) { System.out.println(user3); } } }
我們執(zhí)行兩次mapper.findByCondition()
,分別傳入user和user2,一個(gè)的id有被賦值,一個(gè)沒有,最后的結(jié)果為:
User{id=1, username='lucy'}
======
User{id=1, username='lucy'}
User{id=2, username='李四'}
User{id=3, username='zhaowu'}
foreach標(biāo)簽:
當(dāng)我們需要查詢出 id為1、2、3時(shí)應(yīng)該怎么做? SQL應(yīng)該這樣寫:SELECT * FROM user where id in (1,2,3)。那么使用mybatis的foreach標(biāo)簽應(yīng)該如何使用?
如何使用?
在UserMapper接口中增加一個(gè)方法:List<User> findByIds(int[] arr);
public List<User> findByIds(int[] arr);
在UserMapper.xml 中編寫:
<select id="findByIds" parameterType="list" resultType="com.dxh.pojo.User"> SELECT * FROM user <where> <foreach collection="array" open="id in (" close=")" item="id" separator=","> #{id} </foreach> </where> </select>
我們可以看到,foreach中我們使用到了5個(gè)值:
- collection 這里就是寫我們傳入的類型,如果是數(shù)組就是array ,如果是集合就是list
- open 我們之前說到SELECT * FROM user where id in (1,2,3)正確的SQL應(yīng)該這樣寫,那么open就是填寫我們需要拼接的前半部分
- close 填寫我們需要拼接的后半部分
- item 我們需要遍歷的值是id,所以就填寫id
- separator ......where id in (1,2,3) 1,2,3之間用,分割。
測試:
@Test public void test2() throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = build.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); int[] arr={1,3}; List<User> byCondition = mapper.findByIds(arr); for (User user1 : byCondition) { System.out.println(user1); } }
輸出結(jié)果:
User{id=1, username='lucy'}
User{id=3, username='zhaowu'}
正確~
最后
這里只是介紹了兩個(gè)經(jīng)常使用的標(biāo)簽,mybatis中還有很多標(biāo)簽,比如choose、when、otherwise、trim、set等等
值得一說的是Mybatis的官方網(wǎng)站中已經(jīng)支持中文了,母語看著更舒服~
https://mybatis.org/mybatis-3/zh/
到此這篇關(guān)于Mybatis動態(tài)SQL的文章就介紹到這了,更多相關(guān)Mybatis動態(tài)SQL內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MyBatis 動態(tài)拼接Sql字符串的問題
- mybatis的動態(tài)sql詳解(精)
- MyBatis 執(zhí)行動態(tài) SQL語句詳解
- Mybatis動態(tài)SQL之if、choose、where、set、trim、foreach標(biāo)記實(shí)例詳解
- oracle+mybatis 使用動態(tài)Sql當(dāng)插入字段不確定的情況下實(shí)現(xiàn)批量insert
- mybatis動態(tài)sql之Map參數(shù)的講解
- 詳解Java的MyBatis框架中動態(tài)SQL的基本用法
- MyBatis動態(tài)Sql之if標(biāo)簽的用法詳解
- MyBatis執(zhí)行動態(tài)SQL的方法
- Mybatis模糊查詢和動態(tài)sql語句的用法
相關(guān)文章
將字符串?dāng)?shù)字格式化為樣式1,000,000,000的方法
這篇文章主要介紹了將字符串?dāng)?shù)字格式化為樣式1,000,000,000的方法,有需要的朋友可以參考一下2014-01-01Java日期接收報(bào)錯:could?not?be?parsed,?unparsed?text?found?a
在做Java開發(fā)時(shí)肯定會碰到傳遞時(shí)間參數(shù)的情況,這篇文章主要給大家介紹了關(guān)于Java日期接收報(bào)錯:could?not?be?parsed,?unparsed?text?found?at?index?10的解決辦法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01JAVA使用ElasticSearch查詢in和not in的實(shí)現(xiàn)方式
今天小編就為大家分享一篇關(guān)于JAVA使用Elasticsearch查詢in和not in的實(shí)現(xiàn)方式,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12Java線程編程中isAlive()和join()的使用詳解
這篇文章主要介紹了Java線程編程中isAlive()和join()的使用詳解,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-09-09Spring實(shí)戰(zhàn)之協(xié)調(diào)作用域不同步的Bean操作示例
這篇文章主要介紹了Spring實(shí)戰(zhàn)之協(xié)調(diào)作用域不同步的Bean操作,結(jié)合實(shí)例形式分析了Spring協(xié)調(diào)作用域不同步的Bean相關(guān)配置及使用技巧,需要的朋友可以參考下2019-11-11SpringBoot整合Dubbo zookeeper過程解析
這篇文章主要介紹了SpringBoot整合Dubbo zookeeper過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02解決mapper.xml中resultType映射類型的問題
這篇文章主要介紹了解決mapper.xml中resultType映射類型的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06Java高級之虛擬機(jī)加載機(jī)制的實(shí)例講解
下面小編就為大家分享一篇Java高級之虛擬機(jī)加載機(jī)制的實(shí)例講解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12shiro并發(fā)人數(shù)登錄控制的實(shí)現(xiàn)代碼
在做項(xiàng)目中遇到這樣的需求要求每個(gè)賬戶同時(shí)只能有一個(gè)人登錄或幾個(gè)人同時(shí)登錄,如果是同時(shí)登錄的多人,要么不讓后者登錄,要么踢出前者登錄,怎么實(shí)現(xiàn)這樣的功能呢?下面小編給大家?guī)砹藄hiro并發(fā)人數(shù)登錄控制的實(shí)現(xiàn)代碼,一起看看吧2017-09-09