Mybatis分解式查詢使用方法
一、Mybatis一對多分解式查詢
分解式查詢就是將一條Sql語句拆分成多條
在MyBatis多表查詢中,使用連接查詢時一個Sql語句就可以查詢出所有的數(shù)據(jù)。如:
# 查詢班級時關(guān)聯(lián)查詢出學(xué)生
select *
from classes
left join student
on student.classId = classes.cid
也可以使用分解式查詢,即將一個連接Sql語句分解為多條Sql語句,如:
# 查詢班級時關(guān)聯(lián)查詢出學(xué)生
select * from classes;
select * from student where classId = 1;
select * from student where classId = 2;
這種寫法也叫N+1查詢。
連接查詢:
優(yōu)點:降低查詢次數(shù),從而提高查詢效率。
缺點:如果查詢返回的結(jié)果集較多會消耗內(nèi)存空間。
N+1查詢:
優(yōu)點:結(jié)果集分步獲取,節(jié)省內(nèi)存空間。
缺點:由于需要執(zhí)行多次查詢,相比連接查詢效率低。
我們以查詢班級時關(guān)聯(lián)查詢出學(xué)生為例,使用N+1查詢:
1. 新增持久層接口方法
新增ClassesMapper2.java接口
package com.example.mapper;
import com.example.pojo.Classes;
import java.util.List;
public interface ClassesMapper2 {
List<Classes> findAll();
}新增StudentMapper.java接口
package com.example.mapper;
import com.example.pojo.Student;
import java.util.List;
public interface StudentMapper2 {
List<Student> findByClassId(int classId);
}2. 新增映射文件對應(yīng)的標(biāo)簽
新增ClassesMapper.xml映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.ClassesMapper2">
<!-- 自定義映射關(guān)系 -->
<resultMap id="myClassesMapper" type="com.example.pojo.Classes">
<id property="cid" column="cid"/>
<result property="className" column="className"/>
<!-- select: 從表查詢調(diào)用的方法 column:調(diào)用方法時傳入的參數(shù)字段 -->
<collection property="studentList" column="cid"
ofType="com.example.pojo.Student"
select="com.example.mapper.StudentMapper2.findByClassId"/>
</resultMap>
<select id="findAll" resultMap="myClassesMapper">
select * from classes
</select>
</mapper>新增StudentMapper.xml映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.StudentMapper2">
<select id="findByClassId"
parameterType="int"
resultType="com.example.pojo.Student">
select * from student where classId = ${classId}
</select>
</mapper>3. 新增測試方法
// 分解式查詢一對多
@Test
public void testFindAllClasses2(){
ClassesMapper2 classesMapper2 = session.getMapper(ClassesMapper2.class);
List<Classes> all = classesMapper2.findAll();
all.forEach(System.out::println);
}4. 運行效果

在這里我們可以看到確實是分開了了兩條查詢語句
二、Mybatis一對一分解式查詢
查詢學(xué)生時關(guān)聯(lián)查詢出班級也可以使用分解式查詢,首先將查詢語句分開:
select * from student;
select * from classes where cid = ?
1. 新增持久層接口方法
新增StudentMapper3.java接口
package com.example.mapper;
import com.example.pojo.Student;
import java.util.List;
public interface StudentMapper3 {
// 查詢所有學(xué)生
List<Student> findAll();
}新增ClassesMapper3.java接口
package com.example.mapper;
import com.example.pojo.Classes;
import java.util.List;
public interface ClassesMapper3 {
// 根據(jù)ID查詢班級
Classes findById(int cid);
}2. 新增映射文件對應(yīng)的標(biāo)簽
新增ClassesMapper.xml映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.ClassesMapper3">
<select id="findByCid"
resultType="com.example.pojo.Classes"
parameterType="int">
select * from classes where cid = ${cid}
</select>
</mapper>新增StudentMapper.xml映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.StudentMapper3">
<!-- 自定義映射關(guān)系 -->
<resultMap id="MyClassesMapper" type="com.example.pojo.Student">
<id property="sid" column="sid"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<!-- select: 從表查詢調(diào)用的方法 column:調(diào)用方法時傳入的參數(shù)字段 -->
<association property="classes" column="classId"
javaType="com.example.pojo.Classes"
select="com.example.mapper.ClassesMapper3.findByCid"/>
</resultMap>
<select id="findAll" resultMap="MyClassesMapper">
select * from student
</select>
</mapper>3. 新增測試方法
// 分解式查詢一對一
@Test
public void testFindAllStudent2(){
StudentMapper3 studentMapper3 = session.getMapper(StudentMapper3.class);
List<Student> all = studentMapper3.findAll();
all.forEach(System.out::println);
}4. 運行效果

OK,確實是查詢出來了。
三、Mybatis延遲加載
分解式查詢又分為兩種加載方式:
立即加載:在查詢主表時就執(zhí)行所有的Sql語句。
延遲加載:又叫懶加載,首先執(zhí)行主表的查詢語句,使用從表數(shù)據(jù)時才觸發(fā)從表的查詢語句。
延遲加載在獲取關(guān)聯(lián)數(shù)據(jù)時速度較慢,但可以節(jié)約資源,即用即取。
1. 開啟延遲加載
設(shè)置所有的N+1查詢都為延遲加載,在Mybatis配置文件中添加以下設(shè)置:
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="lazyLoadTriggerMethods" value=""/>
</settings>設(shè)置某個方法為延遲加載:
在 <association> 、 <collection> 中添加fetchType屬性設(shè)置加載方式。
lazy:延遲加載;eager:立即加載。
2. 測試延遲加載
由于打印對象時會調(diào)用對象的 toString 方法, toString 方法默認(rèn)會觸發(fā)延遲加載的查詢,所以我們無法測試出延遲加載的效果。
我們在配置文件設(shè)置lazyLoadTriggerMethods屬性,該屬性指定對象的什么方法觸發(fā)延遲加載,設(shè)置為空字符串即可。
測試方法:
@Test
public void testFindAllClasses2(){
ClassesMapper2 classesMapper2 = session.getMapper(ClassesMapper2.class);
List<Classes> all = classesMapper2.findAll();
all.forEach(System.out::println);
System.out.println("---------------------");
System.out.println(all.get(0).getStudentList());
}運行結(jié)果:

OK,這個很明顯了,就是第一次查詢的時候沒有將學(xué)生列表查詢出來,等到后續(xù)需要查詢的時候載查詢。
一般情況下,一對多查詢使用延遲加載,一對一查詢使用立即加載。
到此這篇關(guān)于Mybatis分解式查詢使用方法的文章就介紹到這了,更多相關(guān)Mybatis分解式查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mybatis打印的sql日志不寫入到log文件的問題及解決
這篇文章主要介紹了mybatis打印的sql日志不寫入到log文件的問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08
使用JMeter從JSON響應(yīng)的URL參數(shù)中提取特定值
在使用Apache JMeter進(jìn)行API測試時,我們經(jīng)常需要從JSON格式的響應(yīng)中提取特定字段的值,這可以通過使用JMeter內(nèi)置的JSON提取器和正則表達(dá)式提取器來完成,本文介紹JMeter JSON提取特定值的相關(guān)知識,感興趣的朋友跟隨小編一起看看吧2024-03-03
SpringBoot解決@Component無法注入其他Bean的問題
這篇文章主要介紹了SpringBoot解決@Component無法注入其他Bean的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
淺談SpringBoot @Autowired的兩種注入方式
本文主要介紹了兩種SpringBoot @Autowired注入方式,具有一定的參考價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-06-06
從0到1學(xué)SpringCloud之SpringCloud?gateway網(wǎng)關(guān)路由配置示例詳解
Spring?Cloud?Gateway的目標(biāo)提供統(tǒng)一的路由方式且基于Filter?鏈的方式提供了網(wǎng)關(guān)基本的功能,?例如:安全、監(jiān)控、指標(biāo)和限流?,這篇文章主要介紹了從0到1學(xué)SpringCloud之SpringCloud?gateway網(wǎng)關(guān)路由配置示例詳解,需要的朋友可以參考下2023-04-04

