Mybaits笔记框架:https://blog.csdn.net/qq_43751200/article/details/128154837
Mybatis中文官方文档: https://mybatis.org/mybatis-3/zh/index.html
创建数据库表
-- 创建t_emp表
create table t_emp(
eid int NOT NULL PRIMARY KEY,
emp_name varchar(20),
age int,
sex char,
email varchar(20),
did int
)
-- 向t_emp表中插入数据
insert into t_emp(eid, emp_name, age, sex, email, did)
values(1, 'lsm', 23, '男', '1234@qq.com', 1),
(2, 'yxy', 23, '男', '1234@qq.com', 2),
(3, 'lxy1', 23, '男', '1234@qq.com', 3),
(4, 'yxy_lsm', 23, '男', '1234@qq.com', 2),
(5, 'lxy', 23, '男', '1234@qq.com', 1)
-- 创建t_dept表
create table t_dept(
did int,
dept_name varchar(20)
)
-- 向t_dept表中插入数据
insert into t_dept(did, dept_name) values(1, 'A'),(2, 'B'),(3, 'C')


在maven项目中创建对应的实体类(Empt类 和 Dept类)
Emp类
package com.atguigu.pojo;
/**
* @Author Mr.Lu
* @Date 2022/12/2 19:08
* @ClassName Emp
* @Version 1.0
*/
public class Emp {
private Integer eid;
// t_emp表该列名为emp_name
private String empName;
private Integer age;
private String sex;
private String email;
public Emp() {
}
public Emp(Integer eid, String empName, Integer age, String sex, String email) {
this.eid = eid;
this.empName = empName;
this.age = age;
this.sex = sex;
this.email = email;
}
public Integer getEid() {
return eid;
}
public void setEid(Integer eid) {
this.eid = eid;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "Emp{" +
"eid=" + eid +
", empName='" + empName + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", email='" + email + '\'' +
'}';
}
}
Dept类
package com.atguigu.pojo;
/**
* @Author Mr.Lu
* @Date 2022/12/2 19:07
* @ClassName Dept
* @Version 1.0
*/
public class Dept {
private Integer did;
// t_dept表该列名为dept_name
private String deptName;
public Dept() {
}
public Dept(Integer did, String deptName) {
this.did = did;
this.deptName = deptName;
}
public Integer getDid() {
return did;
}
public void setDid(Integer did) {
this.did = did;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
@Override
public String toString() {
return "Dept{" +
"did=" + did +
", deptName='" + deptName + '\'' +
'}';
}
}
项目结构

DeptMapper接口
/**
* 获取表t_Emp的所有信息
* @return
*/
List<Emp> getEmpAll();
DeptMapper接口对应的DeptMapper.xml配置文件
<!--List<Emp> getEmpAll();-->
<select id="getEmpAll" resultType="Emp">
select * from t_emp
</select>
测试方法
@Test
public void testGetEmpAll(){
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> empAll = empMapper.getEmpAll();
for(Emp emp : empAll){
System.out.println(emp);
}
sqlSession.close();
}

问题描述:经过上图发现empName对应的值都为null,但是t_emp表中的emp_name是存在值的,这是为什么呐?。经过分析产生这种情况的原因在于表中的字段名和对应类的属性名不一致,这个要如何解决呐?
在EmpMapper.xml中为字段起别名
<select id="getEmpAll" resultType="Emp">
select eid, emp_name empName, age, sex, email from t_emp
select>
测试方法测试:

可以在MyBatis的核心配置文件中的setting标签中,设置一个全局配置信息mapUnderscoreToCamelCase,可以在查询表中数据时,自动将_类型的字段名转换为驼峰,例如:字段名user_name,设置了mapUnderscoreToCamelCase,此时字段名就会转换为userName。
在mybatis-config.xml核心配置文件中加入对应的setting标签
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
settings>
测试方法测试:

resultMap:设置自定义映射
属性:
id:表示自定义映射的唯一标识,不能重复
type:查询的数据要映射的实体类的类型, 例如User、Emp等实体类型
子标签:
id:设置主键的映射关系
result:设置普通字段的映射关系
子标签属性:
property:设置映射关系中实体类中的属性名
column:设置映射关系中表中的字段名
若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射,即使字段名和属性名一致的属性也要映射,也就是全部属性都要列出来
<resultMap id="empResultMap" type="Emp">
<id property="eid" column="eid"/>
<result property="empName" column="emp_name"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<result property="email" column="email"/>
resultMap>
<select id="getEmpAll" resultMap="empResultMap">
select * from t_emp
select>
测试方法测试:

多个员工对应一个部门:多对一
一个部门对应多个员工:一对多
需求:查询员工信息以及员工所对应的部门信息
public class Emp {
private Integer eid;
private String empName;
private Integer age;
private String sex;
private String email;
private Dept dept; // 该员工所属的部门
//...构造器、get、set方法等
}
EmpMapper接口
/**
* 根据t_emp表的eid查询emp和dept表,最后封装成Emp对象返回
* @param eid
* @return
*/
Emp getEmpAndDeptById(Integer eid);
EmpMapper接口对应的EmpMapper.xml配置文件
<resultMap id="empAndDeptResultMap" type="Emp">
<id property="eid" column="eid"/>
<result property="empName" column="emp_name"/>
<result property="empName" column="emp_name"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<result property="email" column="email"/>
<result property="dept.did" column="did"/>
<result property="dept.deptName" column="dept_name"/>
resultMap>
<select id="getEmpAndDeptById" resultMap="empAndDeptResultMap">
select * from t_emp left join t_dept on t_emp.did = t_dept.did where t_emp.eid = #{eid}
select>
测试方法
@Test
public void testGetEmpAndDeptById(){
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
Emp emp = empMapper.getEmpAndDeptById(1);
System.out.println(emp);
sqlSession.close();
}

EmpMapper接口
/**
* 根据t_emp表的eid查询emp和dept表,最后封装成Emp对象返回
* @param eid
* @return
*/
Emp getEmpAndDeptById(Integer eid);
EmpMapper接口对应的EmpMapper.xml配置文件
<resultMap id="empAndDeptResultMap" type="Emp">
<id property="eid" column="eid"/>
<result property="empName" column="emp_name"/>
<result property="empName" column="emp_name"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<result property="email" column="email"/>
<association property="dept" javaType="Dept">
<id property="did" column="did"/>
<result property="deptName" column="dept_name"/>
association>
resultMap>
<select id="getEmpAndDeptById" resultMap="empAndDeptResultMap">
select * from t_emp left join t_dept on t_emp.did = t_dept.did where t_emp.eid = #{eid}
select>
测试方法
@Test
public void testGetEmpAndDeptById(){
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
Emp emp = empMapper.getEmpAndDeptById(3);
System.out.println(emp);
sqlSession.close();
}

查询员工信息
EmpMapper接口
/**
* 分布查询,员工及所对应的部门信息
* 查询员工信息
* @param eid
* @return
*/
Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);
EmpMapper接口对应的EmpMapper.xml配置文件
<resultMap id="getEmpAndDeptByStepOneResultMap" type="Emp">
<id property="eid" column="eid"/>
<result property="empName" column="emp_name"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<result property="email" column="email"/>
<association property="dept"
select="com.atguigu.mapper.DeptMapper.getEmpAndDeptByStepTwo"
column="did"/>
resultMap>
<select id="getEmpAndDeptByStepOne" resultMap="getEmpAndDeptByStepOneResultMap">
select * from t_emp where eid = #{eid}
select>
查询部门信息
DeptMapper接口
/**
* 根据did查询部门信息
* @param did
* @return
*/
Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);
DeptMapper接口对应的DeptMapper.xml配置文件
<resultMap id="getEmpAndDeptByStepTwoResultMap" type="Dept">
<id property="did" column="did"/>
<result property="deptName" column="dept_name"/>
resultMap>
<select id="getEmpAndDeptByStepTwo" resultMap="getEmpAndDeptByStepTwoResultMap">
select * from t_dept where did = #{did}
select>
测试方法
@Test
public void testGetEmpAndDeptByStepTwoAndOne(){
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
Emp emp = empMapper.getEmpAndDeptByStepOne(4);
System.out.println(emp);
sqlSession.close();
}

多个员工对应一个部门:多对一
一个部门对应多个员工:一对多
Dept类
public class Dept {
private Integer did;
private String deptName;
private List<Emp> empList; // 多对一:使用集合的形式
//...构造器、get、set方法等
// 注意要重写toString方式
}
DeptMapper接口
/**
* 根据did查询部门信息以及其所包含的员工信息
* @param did
* @return
*/
Dept getDeptAndEmp(@Param("did") Integer did);
DeptMapper接口对应的DeptMapper.xml配置文件
<resultMap id="getDeptAndEmpResultMap" type="Dept">
<id property="did" column="did"/>
<result property="deptName" column="dept_name"/>
<collection property="empList" ofType="Emp">
<id property="eid" column="eid"/>
<result property="empName" column="emp_name"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<result property="email" column="email"/>
collection>
resultMap>
<select id="getDeptAndEmp" resultMap="getDeptAndEmpResultMap">
select * from t_dept left join t_emp on t_dept.did = t_emp.did where t_dept.did = #{did}
select>
测试方法
@Test
public void testGetDeptAndEmp(){
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
Dept dept = deptMapper.getDeptAndEmp(1);
System.out.println(dept);
sqlSession.close();
}

查询部分信息
DeptMapper接口
/**
* 根据部分的did查询属于该部分的所有员工信息
* @param did
* @return
*/
Dept getDeptAndEmpOne(@Param("did") Integer did);
DeptMapper接口对应的DeptMapper.xml配置文件
<resultMap id="getDeptAndEmpOneResultMap" type="Dept">
<id property="did" column="did"/>
<result property="deptName" column="dept_name"/>
<collection property="empList"
select="com.atguigu.mapper.EmpMapper.getDeptAndEmpTwo"
column="did"/>
resultMap>
<select id="getDeptAndEmpOne" resultMap="getDeptAndEmpOneResultMap">
select * from t_dept where t_dept.did = #{did}
select>
查询员工信息
EmpMapper接口
/**
* 根据did查询员工集合
* @param did
* @return
*/
List<Emp> getDeptAndEmpTwo(@Param("did") Integer did);
EmpMapper接口对应的EmpMapper.xml配置文件
<!--List<Emp> getDeptAndEmpTwo(@Param("did") Integer did);-->
<resultMap id="getDeptAndEmpTwoResultMap" type="Emp">
<id property="eid" column="eid"/>
<result property="empName" column="emp_name"/>
<result property="age" column="age"/>
<result property="email" column="email"/>
<result property="sex" column="sex"/>
</resultMap>
<select id="getDeptAndEmpTwo" resultMap="getDeptAndEmpTwoResultMap">
select * from t_emp where t_emp.did = #{did}
</select>
测试方法
@Test
public void testGetDeptAndEmpOne(){
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
Dept dept = deptMapper.getDeptAndEmpOne(1);
System.out.println(dept);
sqlSession.close();
}

<settings>
<setting name="lazyLoadingEnabled" value="true"/>
settings>
@Test
public void testGetEmpAndDeptByStepTwoAndOne(){
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
Emp emp = empMapper.getEmpAndDeptByStepOne(4);
System.out.println(emp.getEmpName());
sqlSession.close();
}
关闭延迟加载,两条SQL语句都运行了

开启延迟加载,只运行获取emp的SQL语句

@Test
public void testGetEmpAndDeptByStepTwoAndOne(){
SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
Emp emp = empMapper.getEmpAndDeptByStepOne(4);
System.out.println(emp.getEmpName());
System.out.println("===============================");
System.out.println(emp.getDept());
sqlSession.close();
}
开启后,需要用到查询dept的时候才会调用相应的SQL语句

fetchType:当开启了全局的延迟加载之后,可以通过该属性手动控制延迟加载的效果,fetchType=“lazy(延迟加载)|eager(立即加载)”
<resultMap id="empAndDeptByStepResultMap" type="Emp">
<id property="eid" column="eid">id>
<result property="empName" column="emp_name">result>
<result property="age" column="age">result>
<result property="sex" column="sex">result>
<result property="email" column="email">result>
<association property="dept"
select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
column="did"
fetchType="lazy">association>
resultMap>