1. 程式人生 > >Mybatis3.1-[tp_32-33]-_對映檔案_select_resultMap關聯查詢_association分步查詢_延遲載入

Mybatis3.1-[tp_32-33]-_對映檔案_select_resultMap關聯查詢_association分步查詢_延遲載入

筆記要點
出錯分析與總結

工程組織

1.定義介面

  DepartmentMapper

package com.dao;

import com.bean.Department;

public interface DepartmentMapper {
    public Department getDeptById(Integer id);
}
View Code

  EmployeeMapperPlus

package com.dao;
import com.bean.*;
public interface
EmployeeMapperPlus { public Employee getEmpByIdStep(Integer id); //分步查詢 public Employee getEmpAndDept(Integer id);//關聯查詢 public Employee getEmpAndDept2(Integer id); //關聯查詢 ,使用association }
View Code


2.定義XML對映檔案

DepartmentMapper.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.dao.DepartmentMapper">
    <!--public
Department getDeptById(Integer id);--> <select id="getDeptById" resultType="com.bean.Department"> select id,dept_name departmentName from tbl_dept where id=#{id} </select> <!-- public class Department { private Integer id; private String departmentName;
private List<Employee> emps; public Department getDeptByIdPlus(Integer id); --> <select id="getDeptByIdPlus" resultMap=""> select id,dept_name departmentName from tbl_dept where id=#{id} </select> </mapper>
View Code
EmployeeMapperPlus.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.dao.EmployeeMapperPlus">
   <!--ResultMap ;自定義結果集對映規則;
        type: 自定義規則的Java型別;id: 唯一的標識,方便引用-->
    <resultMap id="MySimpleEmp" type="com.bean.Employee">
        <!--指定主鍵列的封裝規則,id定義主鍵,底層會有優化規則;
        column : 指定結果集的具體的那一列; property:指定的JavaBean對應的屬性-->
        <id column="id" property="id"/>
        <!--定義普通列的封裝規則-->
        <result column="last_name" property="lastName"/>
        <!--,其他不指定的列會自動封裝;但是, 我們只要寫ResultMap,就把剩下的對映全部都寫上-->
        <result column="email" property="email"/>
        <result column="gender" property="gender"/>
    </resultMap>

    <!--public Employee getEmpById(Integer id);   注意進行更改為resultMap-->
    <select id="getEmpById" resultMap="MySimpleEmp">
        select * from tbl_employee where id=#{id}
    </select>

    <!--場景1,方法1:使用級聯屬性的方式
        查詢Employee的同時查詢員工對應的部門Employee.dept=Department.id;
        輸出員工對應的部門的全部資訊:
                 id  last_name  gender   did  dept_name
    -->
    <resultMap id="MyDifEmp" type="com.bean.Employee">
        <!--column : 指定結果集的具體的那一列; property:指定的JavaBean對應的屬性-->
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <result column="email" property="email"/>
        <result column="did" property="dept.id"/>
        <result column="dept_name" property="dept.departmentName"/>
    </resultMap>
    <!--public Employee getEmpAndDept2(Integer id); //association 定義封裝規則!-->

    <select id="getEmpAndDept" resultMap="MyDifEmp">
          SELECT e.id id,e.last_name last_name,e.`gender` gender,e.`d_id` d_id,
            d.id did,d.`dept_name` dept_name,email
            FROM tbl_employee e,tbl_dept d
            WHERE e.`d_id`=d.`id` AND e.id=#{id};
    </select>

    <!--方法2:-使用association可以指定聯合的javaBean的物件
     -->
    <resultMap id="MyDifEmp2" type="com.bean.Employee">
        <!--column : 指定結果集的具體的那一列; property:指定的JavaBean對應的屬性-->
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <result column="email" property="email"/>

    <!--使用association可以指定聯合的javaBean的物件;(定義單個物件的封裝規則!)
        property="dept";指定那個屬性是聯合的物件;javaType="dept";指定那個屬性物件的型別;-->
        <association property="dept" javaType="com.bean.Department">
            <id column="did" property="id"/>
            <result column="dept_name" property="departmentName"/>
        </association>

    </resultMap>
    <!--public Employee getEmpAndDept2(Integer id);   //關聯查詢-->
    <select id="getEmpAndDept2" resultMap="MyDifEmp2">
          SELECT e.id id,e.last_name last_name,e.`gender` gender,e.`d_id` d_id,
            d.id did,d.`dept_name` dept_name,email
            FROM tbl_employee e,tbl_dept d
            WHERE e.`d_id`=d.`id` AND e.id=#{id};
    </select>

    <!--使用association進行分步查詢,
                 1.先按照員工的id查詢員工資訊;
                 2.根據查詢員工資訊中的d_id值去部門表查出部門資訊;
                 3;,部門設定到員工中
    -->
    <!--id  last_name   gender  email      d_id-->
    <resultMap id="MyEmpByStep" type="com.bean.Employee">
        <id column="id" property="id" />
        <result column="last_name" property="lastName"/>
        <!--association 定義關聯物件的封裝規則
            select : 表明當前屬性是呼叫select總置頂的方法查出的結果!
          總的流程: 使用select 指定的方法(傳入)查出物件,並封裝給property
         -->
        <association column="d_id" property="dept"
                     select="com.dao.DepartmentMapper.getDeptById">
        </association>
    </resultMap>

    <!--public Employee getEmpByIdStep(Integer id);-->
    <select id="getEmpByIdStep" resultMap="MyEmpByStep">
        select * from tbl_employee
        where id=#{id}
    </select>

    <!--可以使用延遲載入,(按需載入,或者叫做懶載入)
        Employee==>dept:
        我們可以每次查詢Employee物件的時候,都將一起查詢出來;
        部門資訊在我們需要使用的時候再去查詢,分段查詢的基礎之上加兩個配置;
    -->
    <!-- 場景2: 查詢部門的時候將部門對應的所有員工的資訊也全部查詢出來

    -->

</mapper>
View Code

 


3.編寫測試關聯查詢的 程式碼

public SqlSessionFactory getSqlSessionFactory() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream=Resources.getResourceAsStream(resource);
        return new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void test06() throws Exception {

        SqlSession openSession = getSqlSessionFactory().openSession();
        try {
            EmployeeMapperPlus mapper = openSession.getMapper(EmployeeMapperPlus.class);
            System.out.println("---tp_30---多表關聯查詢,級聯屬性的封裝結果!--------");
            Employee employee = mapper.getEmpAndDept(1);
            System.out.println(employee);
            System.out.println("---tp_31--多表關聯查詢,使用association進行連線!--------");
            Employee employee2 = mapper.getEmpAndDept2(1);
            System.out.println(employee2);
            openSession.commit();//預設是不自動提交資料的,需要我們自己手動提交
        } finally {
            openSession.close();
        }
    }

測試結果

---tp_30---多表關聯查詢,級聯屬性的封裝結果!--------
DEBUG 12-01 15:13:43,362 ==>  Preparing: SELECT e.id id,e.last_name last_name,e.`gender` gender,e.`d_id` d_id, d.id did,d.`dept_name` dept_name,email FROM tbl_employee e,tbl_dept d WHERE e.`d_id`=d.`id` AND e.id=?;   (BaseJdbcLogger.java:145) 
DEBUG 12-01 15:13:43,380 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:145) 
DEBUG 12-01 15:13:43,391 <==      Total: 1  (BaseJdbcLogger.java:145) 
Employee{id=1, lastName='jerry', email='[email protected]', gender='1', dept=Department{id=1, departmentName='開發部'}}
---tp_31--多表關聯查詢,使用association進行連線!--------
DEBUG 12-01 15:13:43,391 ==>  Preparing: SELECT e.id id,e.last_name last_name,e.`gender` gender,e.`d_id` d_id, d.id did,d.`dept_name` dept_name,email FROM tbl_employee e,tbl_dept d WHERE e.`d_id`=d.`id` AND e.id=?;   (BaseJdbcLogger.java:145) 
DEBUG 12-01 15:13:43,392 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:145) 
DEBUG 12-01 15:13:43,393 <==      Total: 1  (BaseJdbcLogger.java:145) 
Employee{id=1, lastName='jerry', email='[email protected]', gender='1', dept=Department{id=1, departmentName='開發部'}}

Process finished with exit code 0

 

在全域性配置檔案中 開啟延遲載入 (按需載入,或者叫做懶載入)

 <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <setting name="jdbcTypeForNull" value="NULL"/>
        <!--顯示地指定每個我們需要更改的配置的值,及時他是預設的;防止版本替換帶來的問題-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>

    </settings>

 

程式碼1   (仍使用上面的環境配置資訊, 此程式碼不呼叫到Department 資料庫 )

@Test
    public void test07() throws Exception{
        SqlSession openSession = getSqlSessionFactory().openSession();
        try {
            EmployeeMapperPlus mapper = openSession.getMapper(EmployeeMapperPlus.class);
            System.out.println("---tp_32---多表關聯查詢,使用association進行分佈查詢-----");
            Employee employee = mapper.getEmpByIdStep(1);
            System.out.println(employee.getEmail());
    //        System.out.println(employee.getDept());

            openSession.commit();//預設是不自動提交資料的,需要我們自己手動提交

        }finally {
            openSession.close();
        }
    }

 

結果1 (沒有進行Dept 上資料庫的關聯查詢)

---tp_32---多表關聯查詢,使用association進行分佈查詢-----
DEBUG 12-01 15:18:57,230 ==>  Preparing: select * from tbl_employee where id=?   (BaseJdbcLogger.java:145) 
DEBUG 12-01 15:18:57,249 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:145) 
DEBUG 12-01 15:18:57,308 <==      Total: 1  (BaseJdbcLogger.java:145) 
[email protected]163.com

 

程式碼2  (仍使用上面的環境配置資訊, 此程式碼可以呼叫到Department 資料庫 )

  EmployeeMapperPlus mapper = openSession.getMapper(EmployeeMapperPlus.class);
            System.out.println("---tp_32---多表關聯查詢,使用association進行分佈查詢-----");
            Employee employee = mapper.getEmpByIdStep(1);
      //      System.out.println(employee.getEmail());
            System.out.println(employee.getDept());

            openSession.commit();//預設是不自動提交資料的,需要我們自己手動提交

 

結果2

---tp_32---多表關聯查詢,使用association進行分佈查詢-----
DEBUG 12-01 15:19:50,044 ==>  Preparing: select * from tbl_employee where id=?   (BaseJdbcLogger.java:145) 
DEBUG 12-01 15:19:50,066 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:145) 
DEBUG 12-01 15:19:50,129 <==      Total: 1  (BaseJdbcLogger.java:145) 
DEBUG 12-01 15:19:50,129 ==>  Preparing: select id,dept_name departmentName from tbl_dept where id=?   (BaseJdbcLogger.java:145) 
DEBUG 12-01 15:19:50,130 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:145) 
DEBUG 12-01 15:19:50,131 <==      Total: 1  (BaseJdbcLogger.java:145) 
Department{id=1, departmentName='開發部'}