目錄
1 association 和 collection 介紹
2 案例分析
3 一對一關聯和一對多關聯
4 參考文檔
1 association 和 collection 介紹
? ? ? ? 在之前的 SQL 映射文件中提及了 resultMap 元素的 association 和 collection 標簽,這兩個標簽是用來關聯查詢的,它們的屬性幾乎一致,以下是對它們屬性的描述,紅色標注的是常用屬性。
屬性 | 描述 |
---|---|
property | 實體類屬性名 |
column | 數據庫字段名或者其別名 |
javaType | 實體類屬性的 Java 類型 |
jdbcType | 數據庫列的數據類型 |
ofType | 指定關聯對象的類型。它通常用于泛型類型的情況,以確保正確的類型轉換 |
select | 指定一個子查詢,用于加載關聯的對象 |
fetchType | 用于控制加載策略,比如立即加載還是延遲加載。常見的取值有 lazy(延遲加載)和 eager(立即加載) |
resultMap | 引用預定義的結果映射,以便更靈活地配置關聯對象的映射規則 |
resultSet | 指定結果集的名稱,以便在多結果集的情況下進行區分 |
autoMapping | 是否自動映射所有列到目標對象的屬性上。默認為 true,表示自動映射;設置為 false 則表示不自動映射 |
columnPrefix | 當使用內連接查詢時,這個屬性可以用來指定前綴,以區分關聯表的列名 |
foreignColumn | 指定外鍵對應的列名 |
notNullColumn | 指定一個列名,只有當該列的值不為 null 時,才會執行關聯查詢 |
typeHandler | 自定義的類型處理器 |
2 案例分析
以典型的 員工 (Employee) 和部門 (Department) 為例
- 一個員工只能在一個部門:Employee -> Department(一對一)
- 一個部門可以包含多個員工:Department -> Employee(一對多)
以用戶 (User) 和角色 (Role) 為例,兩者成了一個雙向的一對多,從而變成了多對多,不做介紹
- 一個用戶可以擁有多個角色:User -> Role(一對多)
- 一個角色可以賦予多個用戶:Role -> User(一對多)
表 department?和 表 employee
# 創建 department 表
drop table if exists department;
create table department(
department_id int(11) primary key auto_increment, #主鍵,自增
department_name varchar(255)
)charset=utf8;# 插入數據
insert into department(department_name) values
('開發部'),
('人力資源部'),
('市場營銷部'),
('財務部'),
('行政部'),
('監察部'),
('客服服務部');# 創建 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;# 插入數據
insert into employee values
(1, '唐浩榮', 23, 1, '15477259875@163.com', '中國上海浦東區', 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 一對一關聯和一對多關聯
工程目錄
Department 類
public class Department {//部門idprivate Integer deptId;//部門名稱private String deptName;//部門有哪些員工private List<Employee> employees;// Getter、Setter、toString 方法省略
}
Employee 類
public class Employee {//員工idprivate Integer empId;//員工名稱private String empName;//員工年齡private Integer empAge;//員工性別private Integer empSex;//員工郵箱private String empEmail;//員工地址private String empAddress;//員工所屬部門,和部門表構成一對一的關系,一個員工只能在一個部門private Department department;// Getter、Setter、toString 方法省略
}
創建?DepartmentMapper
public interface DepartmentMapper {//查詢所有數據@Select("select * from department")@Results(id = "deptMap1", value = {@Result(property = "deptId", column = "department_id"),@Result(property = "deptName", column = "department_name"),// 一對多關聯對象// 根據 department_id 來比較@Result(property = "employees", column = "department_id",many = @Many(select = "com.mapper.EmployeeMapper.selectEmpByDeptId"))})List<Department> selectAll();// 根據 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);
}
創建?EmployeeMapper
public interface EmployeeMapper {//查詢所有數據@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"),// 一對一關聯對象// 根據 department_id 來比較@Result(property = "department", column = "department_id",one = @One(select = "com.mapper.DepartmentMapper.findDepartmentById"))})List<Employee> selectAll();//根據員工id查詢數據@Select("select * from employee where employee_id = #{id}")@ResultMap("empMap1")Employee selectEmpByEmpId(@Param("id") int empId);// 根據 department_id 查詢數據@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 configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 通過properties標簽,讀取java配置文件的內容 --><properties resource="mysql.properties" /><!-- 配置環境.--><environments default="development"><environment id="development"><!--配置事務的類型--><transactionManager type="JDBC"></transactionManager><!--dataSource 元素使用標準的 JDBC 數據源接口來配置 JDBC 連接對象源 --><dataSource type="POOLED"><!--配置連接數據庫的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>
創建?EmployeeTest 測試類
public class EmployeeTest {//定義 SqlSessionSqlSession sqlSession = null;//定義 EmployeeMapper 對象private EmployeeMapper mapper = null;@Beforepublic void getSqlSession() throws IOException {//加載 mybatis 全局配置文件 Resources// 原 InputStream is = MybatisTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml");InputStream is = Resources.getResourceAsStream("mybatis-config.xml");//創建 SqlSessionFactory 對象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);//根據 sqlSessionFactory 產生 sessionsqlSession = sqlSessionFactory.openSession();// 創建Mapper接口的的代理對象,getMapper方法底層會通過動態代理生成 EmployeeMapper 的代理實現類mapper = sqlSession.getMapper(EmployeeMapper.class);}//查詢所有員工數據@Testpublic void testSelectAll() {List<Employee> listEmployee = mapper.selectAll();for (Employee employee : listEmployee) {System.out.println(employee);}sqlSession.close();}//根據員工 id 查詢數據@Testpublic void testSelectById() {Employee employee = mapper.selectEmpByEmpId(1);System.out.println(employee);sqlSession.close();}
}
測試結果
查詢所有員工數據,包括員工所在部門(一個員工屬于一個部門)
創建?DepartmentTest?測試類
public class DepartmentTest {//定義 SqlSessionSqlSession sqlSession = null;//定義 DepartmentMapper 對象private DepartmentMapper mapper = null;@Beforepublic void getSqlSession() throws IOException {//加載 mybatis 全局配置文件 Resources// 原 InputStream is = MybatisTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml");InputStream is = Resources.getResourceAsStream("mybatis-config.xml");//創建 SqlSessionFactory 對象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);//根據 sqlSessionFactory 產生 sessionsqlSession = sqlSessionFactory.openSession();// 創建Mapper接口的的代理對象,getMapper方法底層會通過動態代理生成 DepartmentMapper 的代理實現類mapper = sqlSession.getMapper(DepartmentMapper.class);}//查詢所有部門數據@Testpublic void testSelectAll() {List<Department> listDepartment = mapper.selectAll();for (Department department : listDepartment) {System.out.println(department);}sqlSession.close();}//根據部門 id 查詢 數據@Testpublic void testSelectById() {Department department = mapper.findDepartmentById(1);System.out.println(department);sqlSession.close();}
}
測試結果
查詢所有部門信息,包括該部門有哪些員工(一個部門有多個員工)
4 參考文檔
篇篇“參考”這位博主的文檔。。。不過確實寫的挺好的
Mybatis3詳解(八)----高級映射之一對一映射 - 唐浩榮 - 博客園 (cnblogs.com)
Mybatis3詳解(九)----高級映射之一對多映射 - 唐浩榮 - 博客園 (cnblogs.com)