MyBatis --- 映射關係【一對1、一對多、多對多】,懶加載機制

映射(多、一)對一的關聯關係java

1)若只想獲得關聯對象的id屬性,不用關聯數據表sql

2)若但願獲得關聯對象的其餘屬性,要關聯其數據表mybatis

舉例:app

員工與部門的映射關係爲:多對一測試

1.建立表this

員工表spa

肯定其外鍵是部門表的 idxml

DROP TABLE IF EXISTS emp;

CREATE TABLE emp(
id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
emp_name VARCHAR(255) DEFAULT NULL,
gender CHAR(1) DEFAULT NULL,
email VARCHAR(255) DEFAULT NULL,
dept_id INT(22) DEFAULT NULL,
FOREIGN KEY (dept_id) REFERENCES dept(id)
)

 部門表對象

CREATE TABLE dept (
id INT(11) PRIMARY KEY AUTO_INCREMENT,
dept_name VARCHAR(255)
)

 2.建立相應的實體類和Mapper接口blog

查詢的方法有三!

方法一:

- 寫關聯的 sql 語句

將兩個表經過部門表的id關聯,查找員工表id爲1的員工信息

SELECT e.id,e.emp_name,e.gender,e.email,e.dept_id,d.id,d.dept_name
FROM emp e,dept d
WHERE e.dept_id = d.id AND e.id = 1

 - 在sql映射文件中寫映射sql語句【聯合查詢:級聯屬性封裝結果集】

使用resultMap映射,對於【對一】關係能夠不用 association

<resultMap type="com.neuedu.mybatis.entity.TblEmployee" id="getEmployeeByIdMap">
      <!-- Employee -->
      <id column="id" property="id"/>
       <result column="emp_name" property="empName"/>
       <result column="gender" property="gender"/>
       <result column="email" property="email"/>
       <!-- Department -->
       <result column="id" property="dept.id"/>
       <result column="dept_name" property="dept.deptName"/>
</resultMap>
<select id="getEmployeeById" resultMap="getEmployeeByIdMap">
      SELECT e.id,e.emp_name,e.gender,e.email,e.dept_id,d.id,d.dept_name
      FROM emp e,dept d
      WHERE e.dept_id = d.id AND e.id = #{id}
</select>

 - 編寫測試用例

private ApplicationContext ioc = new ClassPathXmlApplicationContext("bean.xml");
@Test
public void test() {
      TblEmployeeMapper bean = ioc.getBean(TblEmployeeMapper.class);
      TblEmployee employee = bean.getEmployeeById(1);
      System.out.println(employee);
}

 方法二:使用association來定義關聯對象的規則,【比較正規的,推薦的方式】

<resultMap type="com.neuedu.mybatis.entity.TblEmployee" id="getEmployeeByIdMap">
      <!-- Employee -->
      <id column="id" property="id"/>
       <result column="emp_name" property="empName"/>
       <result column="gender" property="gender"/>
       <result column="email" property="email"/>
       <!--
               association能夠指定聯合的javaBean對象
               property="dept":指定哪一個屬性是聯合的對象
               javaType:指定這個屬性對象的類型【不能省略】
            -->
       <association property="dept" javaType="com.neuedu.mybatis.entity.TblDepartment">
                  <id column="id" property="id"/>
                  <result column="dept_name" property="deptName"/>
       </association>
</resultMap>

<select id="getEmployeeById" resultMap="getEmployeeByIdMap">
      SELECT e.id,e.emp_name,e.gender,e.email,e.dept_id,d.id,d.dept_name
      FROM emp e,dept d
      WHERE e.dept_id = d.id AND e.id = #{id}
</select>

 方法三:上述結果至關於使用嵌套結果集的形式,還可使用 association 進行分步查詢:

使用association進行分步查詢:
   1.先按照員工id查詢員工信息
   2.根據查詢員工信息中d_id值取部門表查出部門信息
   3.部門設置到員工中:
<!-- 經過id與resultMap相連 -->
<select id="selectDept" resultType="com.neuedu.mybatis.entity.TblDepartment">
      select d.id,d.dept_name
      from dept d
      where d.id = #{id}
</select>
<!-- 經過id被查找employee的select找到 -->
<resultMap type="com.neuedu.mybatis.entity.TblEmployee" id="getEmployeeByIdMap">
      <id column="id" property="id"/>
    <result column="emp_name" property="empName"/>
    <result column="gender" property="gender"/>
    <result column="email" property="email"/>
    <!-- property:是employee中的屬性,
       select:dept的select語句的id
       column:查找到的部門的id,傳到dept的select中
     -->
    <association property="dept" select="selectDept" column="dept_id"/>
</resultMap>

<select id="getEmployeeById" resultMap="getEmployeeByIdMap">
      SELECT e.id,e.emp_name,e.gender,e.email,e.dept_id
      from emp e
      where e.id = #{id}
</select>
修改:
因爲上個方法中有兩個select
一個針對employee,另外一個針對department
因此另寫一個DepartmentMapper,存放針對 department 的 select
在 DepartmentMapper 中:
<mapper namespace="com.neuedu.mybatis.mapper.TblDepartmentMapper">

      <select id="selectDept" resultType="com.neuedu.mybatis.entity.TblDepartment">
            select d.id,d.dept_name
            from dept d
            where d.id = #{id}
      </select>

</mapper>

以前的 association 中的select是寫 id,如今寫 DepartmentMapper 的全類名+ id

<resultMap type="com.neuedu.mybatis.entity.TblEmployee" id="getEmployeeByIdMap">
      <id column="id" property="id"/>
    <result column="emp_name" property="empName"/>
    <result column="gender" property="gender"/>
    <result column="email" property="email"/>
    <!-- property:是employee中的屬性,
       select:select語句的id
       column:查找到的部門的id,傳到查找dept的select中
     -->
    <association property="dept" select="com.neuedu.mybatis.mapper.TblDepartmentMapper.selectDept" column="dept_id"/>
</resultMap>

<select id="getEmployeeById" resultMap="getEmployeeByIdMap">
      SELECT e.id,e.emp_name,e.gender,e.email,e.dept_id
      from emp e
      where e.id = #{id}
</select>

 


 

懶加載機制【按需加載】:

咱們只須要在分步查詢的基礎之上,在mybatis的全局配置文件中加入兩個屬性:

<!-- 開啓懶加載機制 ,默認值爲false-->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 開啓的話,每一個屬性都會直接所有加載出來;禁用的話,只會按需加載出來 -->
<setting name="aggressiveLazyLoading" value="false"/>

 

private ApplicationContext ioc = new ClassPathXmlApplicationContext("bean.xml");
@Test
public void test() {
      TblEmployeeMapper bean = ioc.getBean(TblEmployeeMapper.class);
      TblEmployee employee = bean.getEmployeeById(1);
      System.out.println(employee.getEmpName());
}
此時:能夠看到這裏只發送了一條SQL語句。
 
懶加載機制,是針對第三種映射的,由於只有第三種映射有兩個select語句
 
注意:若是關聯的是一個對象,可使用association標籤
 
映射對多的關聯關係
查詢部門的時候,將部門對應的全部員工信息也查詢出來,註釋在DepartmentMapper.xml中
 
第一種:
1.修改Department實體類【添加Employee集合,併爲該集合提供getter/setter方法】
private List<TblEmployee> list;
public List<TblEmployee> getList() {
      return list;
}
public void setList(List<TblEmployee> list) {
      this.list = list;
}

 創建DepartmentMapper接口文件,並添加以下方法:

public TblDepartment selectDeptAndEmp(Integer id);

 2.sql映射文件中的內容爲:【collection:嵌套結果集的方式:使用collection標籤訂義關聯的集合類型元素的封裝規則】

<resultMap type="com.neuedu.mybatis.entity.TblDepartment" id="selectDeptAndEmpMap">
      <id column="id" property="id"/>
      <result column="dept_name" property="deptName"/>
      <!-- property:Department中的屬性名,ofType集合中存放的類型 -->
      <collection property="list" ofType="com.neuedu.mybatis.entity.TblEmployee">
            <id column="eid" property="id"/>
            <result column="emp_name" property="empName"/>
            <result column="gender" property="gender"/>
            <result column="email" property="email"/>
      </collection>
</resultMap>
<select id="selectDeptAndEmp" resultMap="selectDeptAndEmpMap">
      select d.id,d.dept_name,e.id eid,e.emp_name,e.gender,e.email,e.dept_id
      from dept d
      LEFT JOIN emp e
      ON d.id = e.dept_id
      WHERE d.id = #{id}
</select>

 3.測試方法爲:

@Test
public void TestselectDeptAndEmp(){
      TblDepartmentMapper bean = ioc.getBean(TblDepartmentMapper.class);
      TblDepartment dept = bean.selectDeptAndEmp(1);
      List<TblEmployee> list = dept.getList();
      for (TblEmployee tblEmployee : list) {
            System.out.println(tblEmployee);
      }
}

 

第二種:使用分步查詢結果集

1.在DepartmentMapper接口文件中添加方法,以下所示:

public TblDepartment selectDeptAndEmp(Integer id);

 2.再從EmployeeMapper接口中添加一個方法,以下所示:

public List<TblEmployee> getEmps(Integer deptId);

 3.並在響應的sql映射文件中添加相應的sql語句

<select id="getEmps" resultType="com.neuedu.mybatis.entity.TblEmployee">
      SELECT e.id,e.emp_name,e.gender,e.email,e.dept_id
      FROM emp e
      WHERE e.dept_id = #{id}
</select>

 4.在DepartmentMapper映射文件中:

<resultMap type="com.neuedu.mybatis.entity.TblDepartment" id="selectDeptAndEmpMap">
      <id column="id" property="id"/>
      <result column="dept_name" property="deptName"/>
      <!-- property:Department中的屬性名,ofType集合中存放的類型 -->
      <collection property="list" select="com.neuedu.mybatis.mapper.TblEmployeeMapper.getEmps" column="id"/>
</resultMap>

<select id="selectDeptAndEmp" resultMap="selectDeptAndEmpMap">
      SELECT d.id,d.dept_name
      FROM dept d
      WHERE d.id = #{id}
</select>

 5.測試類:

@Test
public void TestselectDeptAndEmp(){
      TblDepartmentMapper bean = ioc.getBean(TblDepartmentMapper.class);
      TblDepartment dept = bean.selectDeptAndEmp(1);
      List<TblEmployee> list = dept.getList();
      for (TblEmployee tblEmployee : list) {
            System.out.println(tblEmployee);
      }
}

 

映射(一)對多、(多)對多的關聯關係=======》【映射"對多"的關聯關係】
1.必須使用collection節點進行映射
2.基本示例:
注意:
1). ofType指定集合中的元素類型
2). collection標籤:映射多的一端的關聯關係,使用ofType指定集合中的元素類型
     column:傳要查找的項,如按 id 查找就傳 id
     prefix:指定列的前綴
     使用情境:若關聯的數據表和以前的數據表有相同的列名,此時就須要給關聯的列其"別名".
     如有多個列須要起別名,能夠爲全部關聯的數據表的列都加上相同的前綴,而後再映射時指定前綴。
相關文章
相關標籤/搜索