日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

association 实现MyBatis分步查询与延迟加载

發布時間:2024/9/30 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 association 实现MyBatis分步查询与延迟加载 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、分步查詢

1.1什么時候可以用到分步查詢

有的時候需要我們對數據庫進行關聯查詢,比如Employee 持有另一個Department對象的一個引用,我們希望在查詢Employee 的時候把Department也一同查詢出來。這時候我們可以編寫關聯表的SQL 語句,從而將查詢出來的數據使用resultMap進行映射。

我們也可以使用其他的方式將關聯的信息查詢出來,MyBatis 提供了分步查詢的機制,把復雜的SQL 語句簡單化。

關于MyBatis關聯查詢可參考博文:
MyBatis使用resultMap自定義映射規則與關聯映射

1.2分步查詢完成JavaBean 之間關聯

需求:在查詢Employee信息的時候,把其對應的Department信息也一并查詢出來,這里使用分步查詢的方法。使用關聯映射的方法可以參考上面鏈接內的博文。

過程分析:

1根據員工id 向員工數據庫中查詢信息,獲得員工的信息與部門的id。


2.根據部門的id 查詢部門的信息。


3.對查詢的信息進行封裝。

由此可見,實現分步查詢的方法就是將復雜的SQL 語句拆分成簡單的多個SQL 語句,在某個SQL 執行結果的基礎上再進行數據查詢。

1.數據庫表結構:

t_employee 數據庫表結構(其中d_id用于關聯t_dept表 中的id):

DROP TABLE IF EXISTS `t_employee`; CREATE TABLE `t_employee` (`id` int(11) unsigned zerofill NOT NULL AUTO_INCREMENT,`username` varchar(30) DEFAULT NULL,`gender` char(1) DEFAULT NULL,`email` varchar(20) DEFAULT NULL,`d_id` int(11) DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8;

t_dept數據庫表結構:

DROP TABLE IF EXISTS `t_dept`; CREATE TABLE `t_dept` (`id` int(11) NOT NULL AUTO_INCREMENT,`dept_name` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

2.定義JavaBean

Employee類:

package com.jas.mybatis.bean;public class Employee {private Integer id;private String username;private Character gender;private String email;private Department department;// 省略set、get 與toString 方法 }

Department類:

package com.jas.mybatis.bean;public class Department {private Integer id;private String departmentName;// 省略set、get 與toString 方法 }

3.定義mapper 接口

EmployeeMapper 接口:

package com.jas.mybatis.mapper;import com.jas.mybatis.bean.Employee;public interface EmployeeMapper {/*** 根據員工id 獲取員工信息以及對應的部門信息* * @param id* @return*/Employee getEmpAndDeptById(Integer id); }

DepatmentMapper 接口:

package com.jas.mybatis.mapper;import com.jas.mybatis.bean.Department;public interface DepatmentMapper {/*** 根據部門id 獲得部門信息* * @param id* @return*/Department getDeptById(Integer id); }

4.編寫SQL 語句

DepartmentMpper.xmlSQL 映射文件:

<mapper namespace="com.jas.mybatis.mapper.DepatmentMapper"><!-- 根據部門的id 獲得部門信息 --><select id="getDeptById" resultType="com.jas.mybatis.bean.Department">SELECT id, dept_name departmentName FROM t_dept WHERE id = #{id}</select> </mapper>

EmployeeMapper.xmlSQL 映射文件:

<mapper namespace="com.jas.mybatis.mapper.EmployeeMapper"><resultMap type="com.jas.mybatis.bean.Employee" id="BaseEmployeeResultMap"><!-- 進行數據庫字段與JavaBean 屬性映射 --><id column="id" property="id"/><result column="username" property="username"/><result column="gender" property="gender"/><result column="email" property="email"/><!--使用association 標簽完成分步查詢property:Employee 類中對應的屬性departmentselect:另外一個映射語句的 ID,也就是DepartmentMpper.xml 中的getDeptByIdcolumn:表示數據庫中的哪個字段名作為參數傳給select 中的SQL 語句,如果要傳遞多個參數,可以把多個參數封裝成map,比如:{id = d_id, ...}分析:執行流程是先根據員工的id 查詢到數據庫中的信息,將對應的員工信息先進行映射封裝,然后根據d_id 字段值,去部門表中查詢部門信息,然后再對部門信息進行映射封裝,從而獲得完整的員工信息。--><association property="department" column="d_id"select="com.jas.mybatis.mapper.DepatmentMapper.getDeptById"><!--將數據庫中的部門信息映射到Employee 類中的部門信息屬性中--><id column="d_id" property="id"/><result column="dept_name" property="departmentName"/></association></resultMap><select id="getEmpAndDeptById" resultMap="BaseEmployeeResultMap">SELECT * FROM t_employee WHERE id = #{id}</select> </mapper>

5.測試代碼:

private SqlSession getSqlSession() throws IOException {String resource = "mybatis-config.xml";InputStream is = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);SqlSession sqlSession = sqlSessionFactory.openSession();return sqlSession;}@Testpublic void resultMapTest01() throws IOException {SqlSession sqlSession = getSqlSession();EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);Employee employee = employeeMapper.getEmpAndDeptById(1);System.out.println(employee);sqlSession.close();}

6.查看結果:

從上面的執行結果可以看出在進行Employee查詢結果信息封裝的時候,向數據庫發了兩條SQL 語句,分別獲得員工信息與部門信息。通過把復雜的關聯SQL 語句進行分步,最終完成了分步查詢。

一般情況下Department getDeptById(Integer id);方法在實際的開發過程中是必須要定義的一個方法,這樣在進行關聯查詢的時候,我們只要使用現成的方法即可,不需要再定義復雜的關聯SQL 語句。分步查詢還有一個好處就是可以實現延遲加載,這個延遲加載功能在MyBatis 中可以說是一個非常重要的功能。

下面我們就來看看分步查詢是如何完成延遲加載的。

二、延遲加載

2.1什么是延遲加載

延遲加載也可以理解為按需加載。即在你需要的時候才進行的加載方式,才會向數據庫發送SQL 語句,不需要的時候不會向數據庫中發送SQL。這樣做可以用于減輕數據庫的壓力。

比如上面的分步查詢,我們通過分步查詢分別查詢出了員工信息與部門信息,并把這些信息封裝成了一個Employee對象。如果我們并不需要查詢員工的部門信息,在查詢員工信息的時候,由于分步查詢了部門信息,所以這時候部門信息也會被查出來,但是查詢出來的部門信息是不需要的。本來向數據庫發送一條SQL 語句就可以了,這時候發送了兩條。顯然這樣做不是好的解決辦法,這時候我們就可以使用延遲加載。

2.2實現延遲加載

其實在MyBais 中實現延遲加載的功能是很容易的,只需要在全局的配置文件中進行對應的setting設置即可。

<settings><!-- 延遲加載的全局開關。當開啟時,所有關聯對象都會延遲加載,默認為false --><setting name="lazyLoadingEnabled" value="true"/><!-- 設置屬性按需加載 --><setting name="aggressiveLazyLoading" value="false"/></settings>

你有沒有覺得還需要點什么,其實只要配置了上面的兩個屬性,延遲加載就已經開啟了。

2.3測試:

如果我們只要獲得員工的姓名:

// 省略了 getSqlSession() 方法@Testpublic void resultMapTest01() throws IOException {SqlSession sqlSession = getSqlSession();EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);Employee employee = employeeMapper.getEmpAndDeptById(1);System.out.println(employee.getUsername());sqlSession.close(); }

執行結果:

開啟延遲加載后只發送了一條SQL 語句。

下面我們來看看在沒有開啟延遲加載的情況下獲得員工的姓名:

發現即使你不想要獲得員工的部門信息,由于執行的是分步查詢,所以還是會發送兩條SQL 語句,這顯然不是我們想要的。

如果我們想要獲得員工的部門信息:

@Testpublic void resultMapTest01() throws IOException {SqlSession sqlSession = getSqlSession();EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);Employee employee = employeeMapper.getEmpAndDeptById(1);System.out.println(employee.getDepartment());sqlSession.close();}

執行結果:

因為要獲得部門信息,必須先根據員工的id 獲得員工的部門id ,在根據部門id 獲得部門信息,因此發送了兩條SQL,所以只有在你需要部門信息的時候才會發送查詢部門信息的SQL。

三、總結

這篇博文主要對resultMap中的association標簽實現分步查詢的方式進行了實現,并對分步查詢中的延遲加載機制進行了實現。不管是分步查詢還是延遲加載都是MyBatis 中很重要的知識,希望讀者能夠通過這篇博客學習到一些知識,這也是一直支持著我寫博客的原因。

總結

以上是生活随笔為你收集整理的association 实现MyBatis分步查询与延迟加载的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。