MyBatis實現(xiàn)高級映射的示例代碼
1 association 和 collection 介紹
在之前的 SQL 映射文件中提及了 resultMap 元素的 association 和 collection 標(biāo)簽,這兩個標(biāo)簽是用來關(guān)聯(lián)查詢的,它們的屬性幾乎一致,以下是對它們屬性的描述,紅色標(biāo)注的是常用屬性。
屬性 | 描述 |
---|---|
property | 實體類屬性名 |
column | 數(shù)據(jù)庫字段名或者其別名 |
javaType | 實體類屬性的 Java 類型 |
jdbcType | 數(shù)據(jù)庫列的數(shù)據(jù)類型 |
ofType | 指定關(guān)聯(lián)對象的類型。它通常用于泛型類型的情況,以確保正確的類型轉(zhuǎn)換 |
select | 指定一個子查詢,用于加載關(guān)聯(lián)的對象 |
fetchType | 用于控制加載策略,比如立即加載還是延遲加載。常見的取值有 lazy(延遲加載)和 eager(立即加載) |
resultMap | 引用預(yù)定義的結(jié)果映射,以便更靈活地配置關(guān)聯(lián)對象的映射規(guī)則 |
resultSet | 指定結(jié)果集的名稱,以便在多結(jié)果集的情況下進行區(qū)分 |
autoMapping | 是否自動映射所有列到目標(biāo)對象的屬性上。默認(rèn)為 true,表示自動映射;設(shè)置為 false 則表示不自動映射 |
columnPrefix | 當(dāng)使用內(nèi)連接查詢時,這個屬性可以用來指定前綴,以區(qū)分關(guān)聯(lián)表的列名 |
foreignColumn | 指定外鍵對應(yīng)的列名 |
notNullColumn | 指定一個列名,只有當(dāng)該列的值不為 null 時,才會執(zhí)行關(guān)聯(lián)查詢 |
typeHandler | 自定義的類型處理器 |
2 案例分析
以典型的 員工 (Employee) 和部門 (Department) 為例
- 一個員工只能在一個部門:Employee -> Department(一對一)
- 一個部門可以包含多個員工:Department -> Employee(一對多)
以用戶 (User) 和角色 (Role) 為例,兩者成了一個雙向的一對多,從而變成了多對多,不做介紹
- 一個用戶可以擁有多個角色:User -> Role(一對多)
- 一個角色可以賦予多個用戶:Role -> User(一對多)
表 department 和 表 employee
# 創(chuàng)建 department 表 drop table if exists department; create table department( department_id int(11) primary key auto_increment, #主鍵,自增 department_name varchar(255) )charset=utf8; # 插入數(shù)據(jù) insert into department(department_name) values ('開發(fā)部'), ('人力資源部'), ('市場營銷部'), ('財務(wù)部'), ('行政部'), ('監(jiān)察部'), ('客服服務(wù)部'); # 創(chuàng)建 employee 表 drop table if exists employee; create table employee( employee_id int(11) primary key auto_increment, #主鍵,自增 employee_name varchar(255), employee_age int(11), employee_sex char(32), employee_email varchar(255), employee_address varchar(255), department_id int(11) )charset=utf8; # 插入數(shù)據(jù) insert into employee values (1, '唐浩榮', 23, 1, '15477259875@163.com', '中國上海浦東區(qū)', 1), (2, '黃飛鴻', 32, 1, '86547547@qq.com', '大清廣東', 2), (3, '十三姨', 18, 0, '520520520@gmail.com', '大清廣東', 3), (4, '納蘭元述', 28, 1, '545627858@qq.com', '大清京師', 5), (5, '梁寬', 31, 1, '8795124578@qq.com', '大清廣東', 7), (6, '蔡徐坤', 20, 0, '4257895124@gmail.com', '四川成都', 4), (7, '楊超越', 21, 0, '8746821252@qq.com', '中國北京', 7), (8, '馬保國', 66, 1, '6666666666@qq.com', '廣東深圳', 6), (9, '馬牛逼', 45, 1, 'asdfg45678@163.com', '湖北武漢', 3);
3 一對一關(guān)聯(lián)和一對多關(guān)聯(lián)
工程目錄
Department 類
public class Department { //部門id private Integer deptId; //部門名稱 private String deptName; //部門有哪些員工 private List<Employee> employees; // Getter、Setter、toString 方法省略 }
Employee 類
public class Employee { //員工id private Integer empId; //員工名稱 private String empName; //員工年齡 private Integer empAge; //員工性別 private Integer empSex; //員工郵箱 private String empEmail; //員工地址 private String empAddress; //員工所屬部門,和部門表構(gòu)成一對一的關(guān)系,一個員工只能在一個部門 private Department department; // Getter、Setter、toString 方法省略 }
創(chuàng)建 DepartmentMapper
public interface DepartmentMapper { //查詢所有數(shù)據(jù) @Select("select * from department") @Results(id = "deptMap1", value = { @Result(property = "deptId", column = "department_id"), @Result(property = "deptName", column = "department_name"), // 一對多關(guān)聯(lián)對象 // 根據(jù) department_id 來比較 @Result(property = "employees", column = "department_id", many = @Many(select = "com.mapper.EmployeeMapper.selectEmpByDeptId")) }) List<Department> selectAll(); // 根據(jù) id 查找部門 @Select("select * from department where department_id = #{id}") @Results(id = "deptMap2", value = { @Result(property = "deptId", column = "department_id"), @Result(property = "deptName", column = "department_name") }) Department findDepartmentById(int id); }
創(chuàng)建 EmployeeMapper
public interface EmployeeMapper { //查詢所有數(shù)據(jù) @Select("select * from employee") @Results(id = "empMap1", value = { @Result(property = "empId", column = "employee_id", id = true), @Result(property = "empName", column = "employee_name"), @Result(property = "empAge", column = "employee_age"), @Result(property = "empSex", column = "employee_sex"), @Result(property = "empEmail", column = "employee_email"), @Result(property = "empAddress", column = "employee_address"), // 一對一關(guān)聯(lián)對象 // 根據(jù) department_id 來比較 @Result(property = "department", column = "department_id", one = @One(select = "com.mapper.DepartmentMapper.findDepartmentById"))} ) List<Employee> selectAll(); //根據(jù)員工id查詢數(shù)據(jù) @Select("select * from employee where employee_id = #{id}") @ResultMap("empMap1") Employee selectEmpByEmpId(@Param("id") int empId); // 根據(jù) department_id 查詢數(shù)據(jù) @Select("select * from employee where department_id = #{id}") @ResultMap("empMap1") Employee selectEmpByDeptId(@Param("id") int deptId); }
log4j.properties
log4j.rootLogger=DEBUG, Console #Console log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.Console.layout=org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n log4j.logger.java.sql.ResultSet=INFO log4j.logger.org.apache=INFO log4j.logger.java.sql.Connection=DEBUG log4j.logger.java.sql.Statement=DEBUG log4j.logger.java.sql.PreparedStatement=DEBUG
mysql.properties
url=jdbc:mysql://localhost:3306/study?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC name=root password=123456 driver=com.mysql.cj.jdbc.Driver
MyBatis 配置文件 mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 通過properties標(biāo)簽,讀取java配置文件的內(nèi)容 --> <properties resource="mysql.properties" /> <!-- 配置環(huán)境.--> <environments default="development"> <environment id="development"> <!--配置事務(wù)的類型--> <transactionManager type="JDBC"></transactionManager> <!--dataSource 元素使用標(biāo)準(zhǔn)的 JDBC 數(shù)據(jù)源接口來配置 JDBC 連接對象源 --> <dataSource type="POOLED"> <!--配置連接數(shù)據(jù)庫的4個基本信息--> <property name="url" value="${url}" /> <property name="username" value="${name}" /> <property name="password" value="${password}" /> <property name="driver" value="${driver}" /> </dataSource> </environment> </environments> <!--通過包 package 引入 SQL 映射文件--> <mappers> <package name="com.mapper"/> </mappers> </configuration>
創(chuàng)建 EmployeeTest 測試類
public class EmployeeTest { //定義 SqlSession SqlSession sqlSession = null; //定義 EmployeeMapper 對象 private EmployeeMapper mapper = null; @Before public void getSqlSession() throws IOException { //加載 mybatis 全局配置文件 Resources // 原 InputStream is = MybatisTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml"); InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); //創(chuàng)建 SqlSessionFactory 對象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //根據(jù) sqlSessionFactory 產(chǎn)生 session sqlSession = sqlSessionFactory.openSession(); // 創(chuàng)建Mapper接口的的代理對象,getMapper方法底層會通過動態(tài)代理生成 EmployeeMapper 的代理實現(xiàn)類 mapper = sqlSession.getMapper(EmployeeMapper.class); } //查詢所有員工數(shù)據(jù) @Test public void testSelectAll() { List<Employee> listEmployee = mapper.selectAll(); for (Employee employee : listEmployee) { System.out.println(employee); } sqlSession.close(); } //根據(jù)員工 id 查詢數(shù)據(jù) @Test public void testSelectById() { Employee employee = mapper.selectEmpByEmpId(1); System.out.println(employee); sqlSession.close(); } }
測試結(jié)果
查詢所有員工數(shù)據(jù),包括員工所在部門(一個員工屬于一個部門)
創(chuàng)建 DepartmentTest 測試類
public class DepartmentTest { //定義 SqlSession SqlSession sqlSession = null; //定義 DepartmentMapper 對象 private DepartmentMapper mapper = null; @Before public void getSqlSession() throws IOException { //加載 mybatis 全局配置文件 Resources // 原 InputStream is = MybatisTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml"); InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); //創(chuàng)建 SqlSessionFactory 對象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //根據(jù) sqlSessionFactory 產(chǎn)生 session sqlSession = sqlSessionFactory.openSession(); // 創(chuàng)建Mapper接口的的代理對象,getMapper方法底層會通過動態(tài)代理生成 DepartmentMapper 的代理實現(xiàn)類 mapper = sqlSession.getMapper(DepartmentMapper.class); } //查詢所有部門數(shù)據(jù) @Test public void testSelectAll() { List<Department> listDepartment = mapper.selectAll(); for (Department department : listDepartment) { System.out.println(department); } sqlSession.close(); } //根據(jù)部門 id 查詢 數(shù)據(jù) @Test public void testSelectById() { Department department = mapper.findDepartmentById(1); System.out.println(department); sqlSession.close(); } }
測試結(jié)果
查詢所有部門信息,包括該部門有哪些員工(一個部門有多個員工)
4 參考文檔
到此這篇關(guān)于MyBatis實現(xiàn)高級映射的示例代碼的文章就介紹到這了,更多相關(guān)MyBatis 高級映射內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
提升網(wǎng)絡(luò)請求穩(wěn)定性HttpClient的重試機制深入理解
這篇文章主要為大家介紹了提升網(wǎng)絡(luò)請求穩(wěn)定性HttpClient的重試機制深入理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-10-10Java關(guān)鍵字synchronized基本使用詳解
這篇文章主要給大家介紹了關(guān)于Java關(guān)鍵字synchronized基本使用的相關(guān)資料,synchronized可以用來同步靜態(tài)和非靜態(tài)方法,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-01-01Windows7下的Java運行環(huán)境搭建過程圖解
這篇文章主要介紹了Windows7下的Java運行環(huán)境搭建過程圖解,需要的朋友可以參考下2014-04-04java實現(xiàn)后臺數(shù)據(jù)顯示在前端
這篇文章主要為大家詳細介紹了java實現(xiàn)后臺數(shù)據(jù)顯示在前端,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-02-02Android應(yīng)用開發(fā)之將SQLite和APK一起打包的方法
這篇文章主要介紹了Android應(yīng)用開發(fā)之將SQLite和APK一起打包的方法,文章時間較早,盡管現(xiàn)在開發(fā)環(huán)境已大都遷移至Android Studio上,但打包原理依然相同,需要的朋友可以參考下2015-08-08Java中內(nèi)存異常StackOverflowError與OutOfMemoryError詳解
這篇文章主要介紹了 Java中內(nèi)存異常StackOverflowError與OutOfMemoryError詳解的相關(guān)資料,需要的朋友可以參考下2017-03-03