MyBatis保姆级理解与使用学习关联关系

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="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="true"/>

</settings>

 

<environments default="development">

<!-- environment表示配置Mybaits的一个具体的环境 -->

<environment id="development">

<!-- Mybaits的内置的事务管理器 -->

<transactionManager type="JDBC" />

<!-- 配置数据源,这里使用的是Mybaits内置的数据源-->

<dataSource type="POOLED">

<!-- 建立数据库连接的具体信息 -->

<property name="driver" value="${mybatis03.dev.driver}" />

<property name="url" value="${mybatis03.dev.url}" />

<property name="username" value="${mybatis03.dev.username}" />

<property name="password" value="${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>

 

posted @ 2022-08-25 14:12  雾里看瓜  阅读(92)  评论(0编辑  收藏  举报