【MyBatis】自定义映射resultMap

时间:2021-05-08 01:01:30


目录

1.使用全局配置处理字段名和属性名不一致的情况

2.resultMap处理字段和属性的映射关系

1.处理一对一映射

2.多对一映射处理

级联方式处理映射关系

使用association处理映射关系

分步查询

3.一对多映射处理

1.collection

2.分步查询


前期准备:

 建立 t_emp 表,并添加数据:

【MyBatis】自定义映射resultMap

 建立 t_dept 表,并添加数据:

【MyBatis】自定义映射resultMap

实体类:Emp

package com.atguigu.mybatis.pojo;

public class Emp {
private Integer empId;
private String empName;
private Integer age;
private String gender;
private Dept dept;

public Emp() {
}

public Emp(Integer empId, String empName, Integer age, String gender, Dept dept) {
this.empId = empId;
this.empName = empName;
this.age = age;
this.gender = gender;
this.dept = dept;
}

public Integer getEmpId() {
return empId;
}

public void setEmpId(Integer empId) {
this.empId = empId;
}

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 getGender() {
return gender;
}

public void setGender(String gender) {
this.gender = gender;
}

public Dept getDept() {
return dept;
}

public void setDept(Dept dept) {
this.dept = dept;
}

@Override
public String toString() {
return "Emp{" +
"empId=" + empId +
", empName='" + empName + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", dept=" + dept +
'}';
}
}

实体类:Dept

package com.atguigu.mybatis.pojo;

public class Dept {
private Integer deptId;
private String deptName;

public Dept() {
}

public Dept(Integer deptId, String deptName) {
this.deptId = deptId;
this.deptName = deptName;
}

public Integer getDeptId() {
return deptId;
}

public void setDeptId(Integer deptId) {
this.deptId = deptId;
}

public String getDeptName() {
return deptName;
}

public void setDeptName(String deptName) {
this.deptName = deptName;
}

@Override
public String toString() {
return "Dept{" +
"deptId=" + deptId +
", deptName='" + deptName + '\'' +
'}';
}
}

  接口:

public interface EmpMapper {
Emp getEmpById(@Param("empId") Integer empId);
}

SQL:

select * from t_emp where emp_id = #{empId};

测试:

public void test(){
SqlSessionUtils sqlSessionUtils = new SqlSessionUtils();
SqlSession sqlSession = sqlSessionUtils.getSqlSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp empById = mapper.getEmpById(1);
System.out.println(empById.toString());

}

运行结果:

【MyBatis】自定义映射resultMap

原因:JAVA中属性名 与 数据库中字段名不一致

1.使用全局配置处理字段名和属性名不一致的情况

若字段名和实体类中的属性名不一致,但是字段名符合数据库的规则(使用_),实体类中的属性

名符合Java的规则(使用驼峰)

此时也可通过以下两种方式处理字段名和实体类中的属性的映射关系:

1.可以通过为字段起别名的方式,保证和实体类中的属性名保持一致

select emp_id empId,emp_name empName,age,gender from t_emp where emp_id = #{empId};

【MyBatis】自定义映射resultMap

2.可以在MyBatis的核心配置文件中设置一个全局配置信息mapUnderscoreToCamelCase,可

以在查询表中数据时,自动将_类型的字段名转换为驼峰

【MyBatis】自定义映射resultMap

<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

例如:字段名user_name,设置了mapUnderscoreToCamelCase,此时字段名就会转换为

userName

2.resultMap处理字段和属性的映射关系

1.处理一对一映射

<resultMap  type="Emp">
<id property="empId" column="emp_id"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="gender" column="gender"></result>
</resultMap>

<select resultMap="empResultMap">
select * from t_emp where emp_id = #{empId};
</select>

resultMap:设置自定义映射

  • 属性:
  • id:表示自定义映射的唯一标识
  • type:查询的数据要映射的实体类的类型
  • 子标签:
  • id:设置主键的映射关系
  • result:设置普通字段的映射关系
  • association :设置多对一的映射关系
  • collection:设置一对多的映射关系
  • 属性:
  • property:设置映射关系中实体类中的属性名
  • column:设置映射关系中表中的字段名

2.多对一映射处理

级联方式处理映射关系

<resultMap  type="Emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="age" property="age"></result>
<result column="gender" property="gender"></result>

<!--部门中的字段dept_id与Emp实体类中的属性dept中的deptId相对应 -->
<!--部门中的字段dept_name与Emp实体类中的属性dept中的deptName相对应 -->
<result column="dept_id" property="dept.deptId"></result>
<result column="dept_name" property="dept.deptName"></result>
</resultMap>



<select resultMap="empAndDeptResultMap">
SELECT t_emp.*,t_dept.* FROM t_emp
LEFT JOIN t_dept
ON t_emp.dept_id=t_dept.dept_id
where t_emp.emp_id=#{empId}
</select>

接口:

Emp getEmpAndDeptById(@Param("empId") Integer empId);

测试:

public void test2(){
SqlSessionUtils sqlSessionUtils = new SqlSessionUtils();
SqlSession sqlSession = sqlSessionUtils.getSqlSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp empAndDeptById = mapper.getEmpAndDeptById(1);
System.out.println(empAndDeptById);

}

【MyBatis】自定义映射resultMap

使用association处理映射关系

<resultMap  type="Emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="age" property="age"></result>
<result column="gender" property="gender"></result>
<association property="dept" javaType="Dept">
<id column="dept_id" property="deptId"></id>
<result column="dept_name" property="deptName"></result>
</association>

</resultMap>

分步查询

①查询员工信息

Emp getEmpAndDeptByStep(@Param("empId") Integer empId);
<resultMap  type="Emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="age" property="age"></result>
<result column="gender" property="gender"></result>
<association property="dept"
select="com.atguigu.mybatis.mapper.DeptMapper.getDeptByStep" column="dept_id">
</association>

</resultMap>

<select resultMap="empAndDeptByStepResultMap">
select * from t_emp where emp_id=#{empId};
</select>

select:设置分步查询,查询某个属性的值的sql的标识(namespace.sqlid)

column:将sql以及查询结果中的某个字段设置为分步查询的条件

②根据员工所对应的部门 id 查询部门信息

Dept getDeptByStep(@Param("deptId") Integer deptId);
<select  resultType="com.atguigu.mybatis.pojo.Dept">
select * from t_dept where dept_id=#{deptId};
</select>

测试:

public void test3(){
SqlSessionUtils sqlSessionUtils = new SqlSessionUtils();
SqlSession sqlSession = sqlSessionUtils.getSqlSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp empAndDeptByStep = mapper.getEmpAndDeptByStep(1);
System.out.println(empAndDeptByStep);

}

【MyBatis】自定义映射resultMap

分步查询的优点:可以实现延迟加载

但是必须在核心配置文件中设置全局配置信息:

  • lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载
  • aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载

此时就可以实现按需加载,获取的数据是什么,就只会执行相应的 sql 。

此时可通   association和 collection 中的   fetchType 属性设置当前的分步查询是否使用延迟加载, fetchType="lazy(延迟加载)   |  eager(立即加载)"


 测试:

public void test3(){
SqlSessionUtils sqlSessionUtils = new SqlSessionUtils();
SqlSession sqlSession = sqlSessionUtils.getSqlSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp empAndDeptByStep = mapper.getEmpAndDeptByStep(1);
System.out.println(empAndDeptByStep.getEmpName());

}

未开启延迟加载(执行了2次SQL): 

【MyBatis】自定义映射resultMap

开启延迟加载:

<settings>

<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>

 执行了1次SQL:

【MyBatis】自定义映射resultMap

3.一对多映射处理

1.collection

接口:

Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId);

 实体类中,添加 emps集合:

【MyBatis】自定义映射resultMap

 DeptMapper.xml:

collection :设置一对多的映射关系

ofType :设置 collection 标签所处理的集合属性中存储数据的类型

<resultMap  type="Dept">
<id column="dept_id" property="deptId"></id>
<result column="dept_name" property="deptName"></result>
<collection property="emps" ofType="Emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="age" property="age"></result>
<result column="gender" property="gender"></result>

</collection>



</resultMap>


<select resultMap="DeptAndEmpByDeptIdResultMap">
SELECT t_emp.*,t_dept.* FROM t_dept
LEFT JOIN t_emp
ON t_emp.dept_id=t_dept.dept_id
WHERE t_dept.dept_id=#{deptId}
</select>

测试:

public void test4(){
SqlSessionUtils sqlSessionUtils = new SqlSessionUtils();
SqlSession sqlSession = sqlSessionUtils.getSqlSession();
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
Dept deptAndEmpByDeptId = mapper.getDeptAndEmpByDeptId(1);
System.out.println(deptAndEmpByDeptId);


}

运行结果: 

【MyBatis】自定义映射resultMap

2.分步查询

①查询部门信息

Dept getDeptAndEmpByStepOne(@Param("deptId") Integer deptId);

<resultMap  type="Dept">
<id column="dept_id" property="deptId"></id>
<result column="dept_name" property="deptName"></result>
<collection property="emps"
select="com.atguigu.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"
column="dept_id">

</collection>

</resultMap>

<select resultMap="DeptAndEmpByStepResultMap">
select * from t_dept where dept_id=#{deptId}
</select>

②根据部门 id 查询部门中的所有员工

List<Emp> getDeptAndEmpByStepTwo(@Param("deptId") Integer deptId);
<select  resultType="Emp">
select * from t_emp where dept_id=#{deptId}
</select>

测试:

public void test5(){
SqlSessionUtils sqlSessionUtils = new SqlSessionUtils();
SqlSession sqlSession = sqlSessionUtils.getSqlSession();
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
Dept deptAndEmpByStepOne = mapper.getDeptAndEmpByStepOne(1);
System.out.println(deptAndEmpByStepOne);


}

【MyBatis】自定义映射resultMap