主頁 > 軟體設計 > MyBatis保姆級理解與使用學習關聯關系

MyBatis保姆級理解與使用學習關聯關系

2022-08-26 11:49:56 軟體設計

1. 關聯關系

1.1 關聯關系概念說明

表與表之間的關系    1 1  1對多  多對多關系  ,通過主外鍵來實作,

外鍵在多的一方,比如員工和部門: 1個員工對應一個部門,一個部門可以有多個員工

要將表與表之間的關系:映射稱為  類與類之間的關系(準確的說應該是 物件和物件之間的關系 

 

一對一

夫妻關系,人和身份證號的關系

 

一對多

部門 員工

 

多對多:一般都是引入第三張表來解決,

學生 課程  成績

 

老師  學生

 

2. 創建模型

create database mybatisdb03

default charset = utf8;

 

use mybatisdb03;

 

drop table sys_emp;

drop table sys_dept;

 

create table sys_dept(

dept_id   bigint auto_increment,

dept_name varchar(20),

dept_createdate varchar(20),

dept_tel varchar(20) unique,

dept_status enum('y','n') default 'y',

primary key(dept_id)

);

 

INSERT INTO `sys_dept` VALUES (null, '學術部', '2011-1-1', '0710-312345',default);

INSERT INTO `sys_dept` VALUES (null, '市場部', '2012-3-1', '0710-394566',default);

INSERT INTO `sys_dept` VALUES (null, '教質部', '2012-1-1', '0710-335667',default);

INSERT INTO `sys_dept` VALUES (null, '就業部', '2015-2-3', '0710-393568',default);

 

 

create table sys_emp(

emp_id   bigint auto_increment,

emp_name varchar(20),

emp_pwd  varchar(20),

emp_gender enum('m','f'),

    emp_salary double(10,5),

emp_status enum('y','n') default 'y',

dept_id bigint comment '外鍵',

primary key(emp_id)

);

 

INSERT INTO `sys_emp` VALUES (null, '范冰冰', 'fbb', 'f', 100.5,default,1);

INSERT INTO `sys_emp` VALUES (null, '李冰冰', 'lbb', 'f', 300,default,2);

INSERT INTO `sys_emp` VALUES (null, '張彬彬', 'zbb', 'm', 599,default,3);

INSERT INTO `sys_emp` VALUES (null, '萬茜', 'wq', 'm', 4000,default,1);

INSERT INTO `sys_emp` VALUES (null, '李若彤', 'lrt', 'm', 5000.8,default,1);

 

select * from `sys_dept`;

select * from `sys_emp`;

 

現在一般外面做專案,如果資料量過大,只建立外鍵,但是不建立外鍵約束,

 

 

package com.hy.bean;

 

import java.util.Date;

import java.util.List;

 

import lombok.AllArgsConstructor;

import lombok.Getter;

import lombok.NoArgsConstructor;

import lombok.Setter;

 

 

@Setter

@Getter

@NoArgsConstructor

@AllArgsConstructor

public class Dept {

private Long deptId;

private String deptName;

private Date deptCreatedate;

private String deptTel;

private String deptStatus;

 

//體現對多的關系

private List<Emp> empList;

 

//ID,去關系的

public Dept(String deptName, Date deptCreatedate, String deptTel, String deptStatus) {

super();

this.deptName = deptName;

this.deptCreatedate = deptCreatedate;

this.deptTel = deptTel;

this.deptStatus = deptStatus;

}

 

@Override

public String toString() {

return "Dept [deptId=" + deptId + ", deptName=" + deptName + ", deptCreatedate=" + deptCreatedate + ", deptTel="

+ deptTel + ", deptStatus=" + deptStatus + ", empList=" + empList + "]";

}

}

 

 

 

package com.hy.bean;

 

import lombok.AllArgsConstructor;

import lombok.Getter;

import lombok.NoArgsConstructor;

import lombok.Setter;

 

@Setter

@Getter

@NoArgsConstructor

@AllArgsConstructor

public class Emp {

private Long empId;

private String empName;

private String empPwd;

private String empGender;

private Double empSalary;

private String empStatus;

private Long deptId;

 

// 體現對一的關系

private Dept dept;

 

public Emp(String empName, String empPwd, String empGender, Double empSalary, String empStatus, Long deptId) {

super();

this.empName = empName;

this.empPwd = empPwd;

this.empGender = empGender;

this.empSalary = empSalary;

this.empStatus = empStatus;

this.deptId = deptId;

}

 

@Override

public String toString() {

return "Emp [empId=" + empId + ", empName=" + empName + ", empPwd=" + empPwd + ", empGender=" + empGender

+ ", empSalary=" + empSalary + ", empStatus=" + empStatus + ", deptId=" + deptId + ", dept=" + dept

+ "]";

}

}

 

2. 演示[一對多]關系,聯接查詢

關聯關系的方法,主要體現在Java物體類的物件中:

單向:雙方中只有一方能夠訪問到對方

Dept類的物件中empList屬性為null

Emp 類的物件中的dept的屬性為null

雙向:雙方都可以訪問到對方

Dept類的物件中empList屬性不為null,并且包含了該部門的員工物件

Emp 類的物件中的dept的屬性為不為null,指向了該員工物件的部門物件

 

3.1 對一的關系(單向)

我們希望查出Emp類的物件的時候,將其關聯的Dept資訊也查詢出來,并且填充進去,

3.1.1 創建EmpMapper介面

package com.hy.mapper;

 

import org.apache.ibatis.annotations.Param;

 

import com.hy.bean.Emp;

 

public interface EmpMapper {

abstract public Emp selectByIdWithDept(@Param("empId") long empId);

}

 

 

3.1.2 創建EmpMapper.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.hy.mapper.EmpMapper">

<resultMap id="empResultMap" type="com.hy.bean.Emp" >

<!-- 映射Emp本身的屬性  -->

<!-- property屬性:給Emp物件中的哪一個屬性設定資料 -->

<id column="emp_id" property="empId"/>

<result column="emp_name" property="empName"/>

<result column="emp_pwd" property="empPwd"/>

<result column="emp_gender" property="empGender"/>

<result column="emp_salary" property="empSalary"/>

<result column="emp_status" property="empStatus"/>

<result column="dept_id" property="deptId"/>

 

<!-- association標簽,映射對一關聯關系:給Empdept屬性填充資料 -->

<!-- javaType屬性:property屬性的型別,可省略 -->

<association property="dept" javaType="com.hy.bean.Dept">

<id column="dept_id" property="deptId"/>

<result column="dept_name" property="deptName"/>

<result column="dept_createdate" property="deptCreatedate"/>

<result column="dept_tel" property="deptTel"/>

<result column="dept_status" property="deptStatus"/>

</association>

</resultMap>

 

<!-- 注意,這里不能用resultType,否則無法將查詢出來的sys_dept表中的欄位映射到,映射Emp類的物件中-->

<select id="selectByIdWithDept" resultMap="empResultMap">

select * from sys_emp emp 

inner join sys_dept dept 

on emp.dept_id = dept.dept_id

where emp.emp_id = #{empId}

</select>

</mapper>

 

 

3.1.3 測驗類:

 

@Test

public void testSelectByIdWithDept() throws IOException {

// 5. 通過sqlSession物件通過反射機制,直接生成一個EmpMapper介面的匿名類的物件

EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);

 

// 6. 執行陳述句,列印結果

Emp emp = empMapper.selectByIdWithDept(1L);

System.out.println(emp);

System.out.println(emp.getDept());

}

 

一般不會這么設計在1的一端,比如部門,記住所有的員工,但是在多的一端不能記住1的一端,

 

讓姚明 記住 全國人民簡單 還是 讓全國人民記住 姚明簡單,

記住,在多的一端維護1的一端關系,比較簡單,

       1                   *

比如Dept--------------Emp  Emp這邊是多的一端,讓Emp去維護 這個對1的關系,

 

3.2 對多的關系(單向)

“對多”的關聯關系中,有很多配置,但是關鍵的是collection  ofType

3.2.1 創建DeptMapper介面

package com.hy.mapper;

 

import org.apache.ibatis.annotations.Param;

 

import com.hy.bean.Dept;

 

public interface DeptMapper {

abstract public Dept selectByIdWithEmp(@Param("deptId") long deptId);

}

 

3.2.2 創建DeptMapper.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.hy.mapper.DeptMapper">

<resultMap  id="deptResultMap" type="com.hy.bean.Dept">

<id column="dept_id" property="deptId"/>

 

<result column="dept_name" property="deptName"/>

<result column="dept_createdate" property="deptCreatedate"/>

<result column="dept_tel" property="deptTel"/>

<result column="dept_status" property="deptStatus"/>

 

<collection property="empList" ofType="com.hy.bean.Emp">

<id column="emp_id" property="empId"/>

<result column="emp_name" property="empName"/>

<result column="emp_pwd" property="empPwd"/>

<result column="emp_gender" property="empGender"/>

<result column="emp_salary" property="empSalary"/>

<result column="emp_status" property="empStatus"/>

<result column="dept_id" property="deptId"/>

</collection>

</resultMap>

 

<select id="selectByIdWithEmp" resultMap="deptResultMap">

select * from sys_emp emp 

left join sys_dept dept 

on emp.dept_id = dept.dept_id

where dept.dept_id = #{deptId}

</select>

</mapper>

 

3.2.3 測驗類

package com.hy.mybatis.test;

 

import java.io.IOException;

 

import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

 

import com.hy.bean.Dept;

import com.hy.mapper.DeptMapper;

 

public class TestDeptMapperPro {

private SqlSession sqlSession;

 

// junit會在每一個@Test方法前, 執行@Before方法

@Before

public void init() throws IOException {

//1,2,3,4

sqlSession = new SqlSessionFactoryBuilder().build(

Resources.getResourceAsStream("mybatis-config.xml")

)

.openSession();

 

}

 

@Test

public void testSelectByIdWithEmp() throws IOException {

// 5. 通過sqlSession物件通過反射機制,直接生成一個EmpMapper介面的匿名類的物件

DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);

 

// 6. 執行陳述句,列印結果

Dept dept = deptMapper.selectByIdWithEmp(1);

System.out.println(dept);

System.out.println(dept.getEmpList());

}

 

// junit會在每一個@Test方法后, 執行@After方法

@After

public void clear() throws IOException {

// 7. 提交事務

sqlSession.commit();

 

// 8. 關閉sqlSession

sqlSession.close();

}

}

Dept [deptId=1, deptName=學術部, deptCreatedate=Sun Sep 29 00:00:00 CST 110, deptTel=0710-312345, deptStatus=y,

empList=[Emp [empId=1, empName=范冰冰, empPwd=fbb, empGender=f, empSalary=100.5, empStatus=y, deptId=1, dept=null], Emp [empId=4, empName=萬茜, empPwd=wq, empGender=m, empSalary=4000.0, empStatus=y, deptId=1, dept=null], Emp [empId=5, empName=李若彤, empPwd=lrt, empGender=m, empSalary=5000.8, empStatus=y, deptId=1, dept=null]]]

 

 

[Emp [empId=1, empName=范冰冰, empPwd=fbb, empGender=f, empSalary=100.5, empStatus=y, deptId=1, dept=null], Emp [empId=4, empName=萬茜, empPwd=wq, empGender=m, empSalary=4000.0, empStatus=y, deptId=1, dept=null], Emp [empId=5, empName=李若彤, empPwd=lrt, empGender=m, empSalary=5000.8, empStatus=y, deptId=1, dept=null]]

3.3 一對多的關系(雙向)

3.3.1 DeptMapper介面中的方法

package com.hy.mapper;

 

import org.apache.ibatis.annotations.Param;

 

import com.hy.bean.Dept;

 

public interface DeptMapper {

abstract public Dept selectByIdWithEmp(@Param("deptId") long deptId);

 

abstract public Dept selectByIdWithEmpBoth(@Param("deptId") long deptId);

}

 

3.3.2 DeptMapper.xml

<!-- 分割線,雙線連接查詢 -->

<resultMap  id="deptWithEmpListResultMapBoth" type="com.hy.bean.Dept">

<id column="dept_id" property="deptId"/>

 

<result column="dept_name" property="deptName"/>

<result column="dept_createdate" property="deptCreatedate"/>

<result column="dept_tel" property="deptTel"/>

<result column="dept_status" property="deptStatus"/>

 

<collection property="empList" ofType="com.hy.bean.Emp"

resultMap="com.hy.mapper.EmpMapper.empResultMapBoth"/>

</resultMap>

 

<select id="selectByIdWithEmpBoth" resultMap="deptWithEmpListResultMapBoth">

select * from sys_dept dept left join sys_emp emp

on dept.dept_id = emp.dept_id

where dept.dept_id = #{deptId}

</select>

 

3.3.3 EmpMapper.xml

<!-- 雙向關聯 -->

<resultMap id="empResultMapBoth" type="com.hy.bean.Emp" >

<!-- 映射Emp本身的屬性  -->

<!-- property屬性:給Emp物件中的哪一個屬性設定資料 -->

<id column="emp_id" property="empId"/>

<result column="emp_name" property="empName"/>

<result column="emp_pwd" property="empPwd"/>

<result column="emp_gender" property="empGender"/>

<result column="emp_salary" property="empSalary"/>

<result column="emp_status" property="empStatus"/>

<result column="dept_id" property="deptId"/>

 

<!-- association標簽,映射對一關聯關系:給Empdept屬性填充資料 -->

<!-- javaType屬性:property屬性的型別,可省略 -->

<association property="dept" javaType="com.hy.bean.Dept"

resultMap="com.hy.mapper.DeptMapper.deptWithEmpListResultMapBoth" />

</resultMap>

 

3.3.4 測驗類:

@Test

public void selectByIdWithEmpBoth() throws IOException {

// 5. 通過sqlSession物件通過反射機制,直接生成一個EmpMapper介面的匿名類的物件

DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);

 

// 6. 執行陳述句,列印結果

Dept dept = deptMapper.selectByIdWithEmpBoth(1L);

System.out.println(dept);

System.out.println(dept.getEmpList());

}

 

 

 

4. 演示[1對多],分步查詢

上面不論是從DeptEmp,還是從EmpDept,都是通過一條連接查詢的SQL陳述句來完成的,將deptemp的資訊一起查出來了,然后通過mybatis組裝起來,此時就有一個問題,查詢出來的關聯物件不一定會被用到,查詢dept的時候,不管emp用不用,都會將emp查詢出來,并封裝起來,此時如果查詢出來,但是暫時又用不上,然后你又裝配起來了,此時就會造成記憶體你的浪費,但是如果你不查出來,但是萬一又用了,此時又沒有,

此時,我希望既能維持關聯關系,又希望在用的時候才將其查詢出來,不用的時候,不查,這就叫延遲加載—也叫懶加載,就是到使用的時候才用將其查詢出來,使用場景:

 

 

所以分布查詢是懶加載的基礎,

4.1 實作

為了實作懶加載—延遲加載,對sys_deptsys_emp的查詢必須分開,分成兩步來做,才能夠實作,為此,我們需要單獨查詢sys_dept  sys_empSQL陳述句,

4.2 分布對1的關系:

4.2.1 bean的寫法

package com.hy.bean;

 

import java.util.Date;

import java.util.List;

 

import lombok.AllArgsConstructor;

import lombok.Getter;

import lombok.NoArgsConstructor;

import lombok.Setter;

 

 

@Setter

@Getter

@NoArgsConstructor

@AllArgsConstructor

public class Dept {

private Long deptId;

private String deptName;

private Date deptCreatedate;

private String deptTel;

private String deptStatus;

 

//體現對多的關系

private List<Emp> empList;

 

//ID,去關系的

public Dept(String deptName, Date deptCreatedate, String deptTel, String deptStatus) {

super();

this.deptName = deptName;

this.deptCreatedate = deptCreatedate;

this.deptTel = deptTel;

this.deptStatus = deptStatus;

}

 

@Override

public String toString() {

return "Dept [deptId=" + deptId + ", deptName=" + deptName + ", deptCreatedate=" + deptCreatedate + ", deptTel="

+ deptTel + ", deptStatus=" + deptStatus;// + ", empList=" + empList + "]";

}

}

 

 

package com.hy.bean;

 

import lombok.AllArgsConstructor;

import lombok.Getter;

import lombok.NoArgsConstructor;

import lombok.Setter;

 

@Setter

@Getter

@NoArgsConstructor

@AllArgsConstructor

public class Emp {

private Long empId;

private String empName;

private String empPwd;

private String empGender;

private Double empSalary;

private String empStatus;

private Long deptId;

 

// 體現對一的關系

private Dept dept;

 

//ID的,去關系

public Emp(String empName, String empPwd, String empGender, Double empSalary, String empStatus, Long deptId) {

super();

this.empName = empName;

this.empPwd = empPwd;

this.empGender = empGender;

this.empSalary = empSalary;

this.empStatus = empStatus;

this.deptId = deptId;

}

 

 

 

@Override

public String toString() {

return "Emp [empId=" + empId + ", empName=" + empName + ", empPwd=" + empPwd + ", empGender=" + empGender

+ ", empSalary=" + empSalary + ", empStatus=" + empStatus + ", deptId=" + deptId ; 

// "+ , dept=" + dept + "]";

}

}

 

4.2.2 mapper介面的寫法

 

package com.hy.mapper;

 

import org.apache.ibatis.annotations.Param;

 

import com.hy.bean.Dept;

 

public interface DeptMapper {

abstract public Dept selectByIdWithTwoStep(@Param("deptId") long deptId);

}

 

package com.hy.mapper;

 

import org.apache.ibatis.annotations.Param;

 

import com.hy.bean.Emp;

 

public interface EmpMapper {

abstract public Emp selectByIdWithDeptTwoStep(@Param("empId") long empId);

}

 

 

4.2.3 映射的檔案的寫法

<?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.hy.mapper.DeptMapper">

<!-- 定位到當前SQL陳述句的方式:com.hy.mapper.DeptMapper.selectById -->

<!-- 這條陳述句僅僅是根據id查詢部門 -->

<select id="selectById" resultType="com.hy.bean.Dept">

select dept_id,dept_name,dept_createdate,dept_tel,dept_status from sys_dept

where dept_id = #{deptId}

</select>

 

 

<!-- 兩步 -->

<resultMap type="com.hy.bean.Dept" id="deptResultMapBoth">

<id column="dept_id" property="deptId"/>

 

<result column="dept_name" property="deptName"/>

<result column="dept_createdate" property="deptCreatedate"/>

<result column="dept_tel" property="deptTel"/>

<result column="dept_status" property="deptStatus"/>

 

<collection property="empList" column="dept_id" ofType="com.hy.bean.Emp"

select="com.hy.mapper.EmpMapper.selectByFid"/>

 

</resultMap>

<select id="selectByIdWithTwoStep" resultMap="deptResultMapBoth">

select dept_id,dept_name,dept_createdate,dept_tel,dept_status from sys_dept

where dept_id = #{deptId}

</select>

</mapper>

 

<?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.hy.mapper.EmpMapper">

<resultMap id="empResultMap" type="com.hy.bean.Emp" >

<!-- 映射Emp本身的屬性  -->

<!-- property屬性:給Emp物件中的哪一個屬性設定資料 -->

<id column="emp_id" property="empId"/>

<result column="emp_name" property="empName"/>

<result column="emp_pwd" property="empPwd"/>

<result column="emp_gender" property="empGender"/>

<result column="emp_salary" property="empSalary"/>

<result column="emp_status" property="empStatus"/>

<result column="dept_id" property="deptId"/>

 

<!-- association標簽,映射對一關聯關系:給Empdept屬性填充資料 -->

<!-- select屬性:定位到另外一條專門查詢deptSQL陳述句-->

<!-- column屬性:指定用來給查詢 sys_dept SQL陳述句傳參的欄位-->

<association

property="dept"

column="dept_id"

select="com.hy.mapper.DeptMapper.selectById" />

</resultMap>

 

<select id="selectByIdWithDeptTwoStep" resultMap="empResultMap">

select * from sys_emp where emp_id = #{empId}

</select>

 

<select id="selectByFid" resultType="com.hy.bean.Emp">

select * from sys_emp where dept_id = #{deptId}

</select>

</mapper>

 

4.2.4 mybaits-config.xml全域組態檔中注意

<settings>

<setting name="mapUnderscoreToCamelCase" value=https://www.cnblogs.com/lijili/archive/2022/08/25/"true"/>

</settings>

 

<?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 resource="jdbc.properties"/>

 

<settings>

<setting name="mapUnderscoreToCamelCase" value=https://www.cnblogs.com/lijili/archive/2022/08/25/"true"/>

</settings>

 

<environments default="development">

<!-- environment表示配置Mybaits的一個具體的環境 -->

<environment id="development">

<!-- Mybaits的內置的事務管理器 -->

<transactionManager type="JDBC" />

<!-- 配置資料源,這里使用的是Mybaits內置的資料源-->

<dataSource type="POOLED">

<!-- 建立資料庫連接的具體資訊 -->

<property name="driver" value=https://www.cnblogs.com/lijili/archive/2022/08/25/"${mybatis03.dev.driver}" />

<property name="url" value=https://www.cnblogs.com/lijili/archive/2022/08/25/"${mybatis03.dev.url}" />

<property name="username" value=https://www.cnblogs.com/lijili/archive/2022/08/25/"${mybatis03.dev.username}" />

<property name="password" value=https://www.cnblogs.com/lijili/archive/2022/08/25/"${mybatis03.dev.password}" />

</dataSource>

</environment>

</environments>

<!-- 設定映射檔案的路徑,還沒有寫 -->

<mappers>

<mapper resource="mappers/EmpMapper.xml" />

<mapper resource="mappers/DeptMapper.xml" />

</mappers>

</configuration>

 

4.2.5 測驗類

package com.hy.mybatis.test;

 

import java.io.IOException;

 

import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

 

import com.hy.bean.Dept;

import com.hy.bean.Emp;

import com.hy.mapper.DeptMapper;

 

public class TestDeptMapperPro {

private SqlSession sqlSession;

 

// junit會在每一個@Test方法前, 執行@Before方法

@Before

public void init() throws IOException {

//1,2,3,4

sqlSession = new SqlSessionFactoryBuilder().build(

Resources.getResourceAsStream("mybatis-config.xml")

)

.openSession();

 

}

 

@Test

public void testSelectByIdWithTwoStep() throws IOException {

// 5. 通過sqlSession物件通過反射機制,直接生成一個EmpMapper介面的匿名類的物件

DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);

 

// 6. 執行陳述句,列印結果

Dept dept = deptMapper.selectByIdWithTwoStep(1L);

System.out.println(dept);

System.out.println(dept.getEmpList());

}

 

// junit會在每一個@Test方法后, 執行@After方法

@After

public void clear() throws IOException {

// 7. 提交事務

sqlSession.commit();

 

// 8. 關閉sqlSession

sqlSession.close();

}

}

 

package com.hy.mybatis.test;

 

import java.io.IOException;

 

import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

 

import com.hy.bean.Emp;

import com.hy.mapper.EmpMapper;

 

public class TestEmpMapperPro {

private SqlSession sqlSession;

 

// junit會在每一個@Test方法前, 執行@Before方法

@Before

public void init() throws IOException {

//1,2,3,4

sqlSession = new SqlSessionFactoryBuilder().build(

Resources.getResourceAsStream("mybatis-config.xml")

)

.openSession();

 

}

 

@Test

public void testSelectByIdWithDept() throws IOException {

// 5. 通過sqlSession物件通過反射機制,直接生成一個EmpMapper介面的匿名類的物件

EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);

 

// 6. 執行陳述句,列印結果

Emp emp = empMapper.selectByIdWithDeptTwoStep(1);

System.out.println(emp);

System.out.println(emp.getDept());

}

 

// junit會在每一個@Test方法后, 執行@After方法

@After

public void clear() throws IOException {

// 7. 提交事務

sqlSession.commit();

 

// 8. 關閉sqlSession

sqlSession.close();

}

}

 

4.3 圖解:

 

 

 

4.4 懶查詢

配置fetchType=”lazy”

 

 

 

 

 

 

 

 

 

5. 演示多對多關系

5.1 建立模型

create database mybatisdb03

default charset = utf8;

 

use mybatisdb03;

 

create table sys_student(

student_id   bigint auto_increment,

student_name varchar(20),

student_gender enum('m','f'),

primary key(student_id)

);

 

INSERT INTO `sys_student` VALUES (null, '范冰冰', 'f');

INSERT INTO `sys_student` VALUES (null, '李冰冰', 'f');

INSERT INTO `sys_student` VALUES (null, '張彬彬', 'm');

INSERT INTO `sys_student` VALUES (null, '萬茜', 'm');

INSERT INTO `sys_student` VALUES (null, '李若彤', 'm');

 

 

create table `sys_course`(

course_id   bigint auto_increment,

course_name varchar(20) not null unique,

primary key(sys_course)

);

 

INSERT INTO `sys_course` VALUES (null, 'JSP');

INSERT INTO `sys_course` VALUES (null, 'mybatis');

INSERT INTO `sys_course` VALUES (null, 'SpringMVC');

 

create table `sys_student_course`(

student_course_id   bigint auto_increment,

student_id bigint,

course_id bigint,

primary key(student_course_id)

);

 

INSERT INTO `sys_student_course` VALUES (null, 1,1);

INSERT INTO `sys_student_course` VALUES (null, 1,2);

INSERT INTO `sys_student_course` VALUES (null, 2,1);

INSERT INTO `sys_student_course` VALUES (null, 2,2);

INSERT INTO `sys_student_course` VALUES (null, 3,1);

 

select * from sys_student stu

left join sys_student_course sc on stu.student_id = sc.student_id

left join sys_course course on course.course_id = sc.course_id

 

5.2 bean

5.2.1 Course

 

package com.hy.bean;

 

import java.util.List;

 

import lombok.AllArgsConstructor;

import lombok.Getter;

import lombok.NoArgsConstructor;

import lombok.Setter;

 

@Setter

@Getter

@NoArgsConstructor

@AllArgsConstructor

public class Course {

private Long courseId;

private String courseName;

 

//體現多對多關系

private List<Student> studentList;

 

@Override

public String toString() {

return "Course [courseId=" + courseId + ", courseName=" + courseName;// + ", studentList=" + studentList + "]";

}

}

 

5.2.2 Student

package com.hy.bean;

 

import java.util.List;

 

import lombok.AllArgsConstructor;

import lombok.Getter;

import lombok.NoArgsConstructor;

import lombok.Setter;

 

 

@Setter

@Getter

@NoArgsConstructor

@AllArgsConstructor

public class Student {

private Long studentId;

private String studentName;

private String studentGender;

 

//體現對多的關系

private List<Course> courseList;

 

@Override

public String toString() {

return "Student [studentId=" + studentId + ", studentName=" + studentName;// + ", studentGender=" + studentGender+ ", courseList=" + courseList + "]";

}

 

}

 

 

5.2.3 StudentMapper

package com.hy.mapper;

 

import java.util.List;

 

import com.hy.bean.Student;

 

public interface StudentMapper {

abstract public List<Student> selectAll();

}

 

 

5.2.4 StudentMapper.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.hy.mapper.StudentMapper">

<resultMap id="studentResultMapBoth" type="com.hy.bean.Student" >

<!-- 映射Emp本身的屬性  -->

<!-- property屬性:給Emp物件中的哪一個屬性設定資料 -->

<id column="student_id" property="studentId"/>

<result column="student_name" property="studentName"/>

<result column="student_gender" property="studentGender"/>

 

<collection property="courseList" ofType="com.hy.bean.Course">

<id column="course_id" property="courseId"/>

<result column="course_name" property="courseName"/>

</collection>

</resultMap>

 

<select id="selectAll" resultMap="studentResultMapBoth">

select * from sys_student stu

left join sys_student_course sc on stu.student_id = sc.student_id

left join sys_course course on course.course_id = sc.course_id

</select>

</mapper>

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/502766.html

標籤:其他

上一篇:設計模式之責任鏈

下一篇:初識設計模式 - 單例模式

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more