Mybatis動(dòng)態(tài)SQL實(shí)例詳解
動(dòng)態(tài)SQL
什么是動(dòng)態(tài)SQL?
MyBatis的官方文檔中是這樣介紹的?
動(dòng)態(tài) SQL 是 MyBatis 的強(qiáng)大特性之一。如果你使用過(guò) JDBC 或其它類似的框架,你應(yīng)該能理解根據(jù)不同條件拼接 SQL 語(yǔ)句有多痛苦,例如拼接時(shí)要確保不能忘記添加必要的空格,還要注意去掉列表最后一個(gè)列名的逗號(hào)。利用動(dòng)態(tài) SQL,可以徹底擺脫這種痛苦。
使用動(dòng)態(tài) SQL 并非一件易事,但借助可用于任何 SQL 映射語(yǔ)句中的強(qiáng)大的動(dòng)態(tài) SQL 語(yǔ)言,MyBatis 顯著地提升了這一特性的易用性。
如果你之前用過(guò) JSTL 或任何基于類 XML 語(yǔ)言的文本處理器,你對(duì)動(dòng)態(tài) SQL 元素可能會(huì)感覺(jué)似曾相識(shí)。在 MyBatis 之前的版本中,需要花時(shí)間了解大量的元素。借助功能強(qiáng)大的基于 OGNL 的表達(dá)式,MyBatis 3 替換了之前的大部分元素,大大精簡(jiǎn)了元素種類,現(xiàn)在要學(xué)習(xí)的元素種類比原來(lái)的一半還要少。
換句話說(shuō),我們可以根據(jù)傳入?yún)?shù)的不同,來(lái)執(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 然后編寫(xiě)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 是多余的,因此我們可以這樣寫(xiě):
<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>
測(cè)試:
編寫(xiě)一個(gè)測(cè)試類:
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è)沒(méi)有,最后的結(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)該這樣寫(xiě):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 中編寫(xiě):
<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 這里就是寫(xiě)我們傳入的類型,如果是數(shù)組就是array ,如果是集合就是list
- open 我們之前說(shuō)到SELECT * FROM user where id in (1,2,3)正確的SQL應(yīng)該這樣寫(xiě),那么open就是填寫(xiě)我們需要拼接的前半部分
- close 填寫(xiě)我們需要拼接的后半部分
- item 我們需要遍歷的值是id,所以就填寫(xiě)id
- separator ......where id in (1,2,3) 1,2,3之間用,分割。
測(cè)試:
@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等等
值得一說(shuō)的是Mybatis的官方網(wǎng)站中已經(jīng)支持中文了,母語(yǔ)看著更舒服~
https://mybatis.org/mybatis-3/zh/
到此這篇關(guān)于Mybatis動(dòng)態(tài)SQL的文章就介紹到這了,更多相關(guān)Mybatis動(dòng)態(tài)SQL內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MyBatis 動(dòng)態(tài)拼接Sql字符串的問(wèn)題
- mybatis的動(dòng)態(tài)sql詳解(精)
- MyBatis 執(zhí)行動(dòng)態(tài) SQL語(yǔ)句詳解
- Mybatis動(dòng)態(tài)SQL之if、choose、where、set、trim、foreach標(biāo)記實(shí)例詳解
- oracle+mybatis 使用動(dòng)態(tài)Sql當(dāng)插入字段不確定的情況下實(shí)現(xiàn)批量insert
- mybatis動(dòng)態(tài)sql之Map參數(shù)的講解
- 詳解Java的MyBatis框架中動(dòng)態(tài)SQL的基本用法
- MyBatis動(dòng)態(tài)Sql之if標(biāo)簽的用法詳解
- MyBatis執(zhí)行動(dòng)態(tài)SQL的方法
- Mybatis模糊查詢和動(dòng)態(tài)sql語(yǔ)句的用法
相關(guān)文章
SpringBoot接口訪問(wèn)頻率限制的實(shí)現(xiàn)方式
接口訪問(wèn)頻率限制是通過(guò)在一定時(shí)間內(nèi)限制用戶對(duì)接口的訪問(wèn)次數(shù)來(lái)實(shí)現(xiàn)的,在Spring Boot中,我們可以通過(guò)多種方式來(lái)實(shí)現(xiàn)接口的限流,如使用過(guò)濾器、攔截器或者借助第三方庫(kù),本文給大家講解的非常詳細(xì),需要的朋友可以參考下2024-07-07
Java 深入淺出分析Synchronized原理與Callable接口
Synchronized關(guān)鍵字解決的是多個(gè)線程之間訪問(wèn)資源的同步性,synchronized關(guān)鍵字可以保證被它修飾的方法或者代碼塊在任意時(shí)刻只能有一個(gè)線程執(zhí)行,Runnable是執(zhí)行工作的獨(dú)立任務(wù),但是不返回任何值。如果我們希望任務(wù)完成之后有返回值,可以實(shí)現(xiàn)Callable接口2022-03-03
Java用Cookie限制點(diǎn)贊次數(shù)(簡(jiǎn)版)
最近做了一個(gè)項(xiàng)目,其中有項(xiàng)目需求是,要用cookie實(shí)現(xiàn)限制點(diǎn)贊次數(shù),特此整理,把實(shí)現(xiàn)代碼分享給大家供大家學(xué)習(xí)2016-02-02
Netty分布式pipeline管道傳播事件的邏輯總結(jié)分析
這篇文章主要為大家介紹了Netty分布式pipeline管道傳播事件總結(jié)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03
SpringBoot JPA懶加載失效的解決方案(親測(cè)有效)
這篇文章主要介紹了SpringBoot JPA懶加載失效的解決方案(親測(cè)有效),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08

