文章目录
失败,是正因你在距成功一步之遥的时候停住了脚步。
8、自定义映射resultMap
8.1、环境
在mybatis库下创建两个表
1 t_emp表
CREATE TABLE IF NOT EXISTS t_emp(
`emp_id` int PRIMARY KEY AUTO_INCREMENT,
`emp_name` varchar(20),
`age` int NULL,
`gender` char(1),
`dept_id` int
);
INSERT INTO t_emp VALUES
(1, '张三', 20, '男', 1),
(2, '李四', 22, '男', 2),
(3, '王五', 23, '男', 3),
(4, '赵六', 26, '男', 1);
2 t_dept表
CREATE TABLE IF NOT EXISTS t_dept(
`dept_id` int PRIMARY KEY AUTO_INCREMENT,
`dept_name` varchar(20)
);
INSERT INTO t_dept VALUES
(1, 'A'),
(2, 'B'),
(3, 'C'),
(4, 'D');
3 Emp.java
public class Emp {
private Integer empId;
private String empName;
private Integer age;
private String gender;
}
4 Dept.java
public class Dept {
private Integer deptId;
private String deptName;
}
8.2、使用SQL或全局配置
1 方式一
可以通过为字段起别名的方式,保证和实体类中的属性名保持一致。
若字段名和实体类中的属性名不一致,但是字段名符合数据库的规则(使用_),实体类中的属性名符合Java的规则(使用驼峰),可以使用方式二。
2 方式二
在MyBatis的核心配置文件中设置一个全局配置信息mapUnderscoreToCamelCase,可以在查询表中数据时,自动将_类型的字段名转换为驼峰。
例如:字段名user_name,设置了mapUnderscoreToCamelCase,此时字段名就会转换为userName。
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
3 EmpMapper.java
// 根据员工Id查询员工
Emp getEmpByEmpId(@Param("empId") int empId);
4 EmpMapper.xml
<!--Emp getEmpByEmpId(@Param("empId") int empId);-->
<select id="getEmpByEmpId" resultType="Emp">
<!--select emp_id empId, emp_name empName, age, gender
from t_emp
where emp_id = #{empId}-->
select emp_id, emp_name, age, gender, dept_id
from t_emp
where emp_id = #{empId};
</select>
5 测试
@Test
public void testGetEmpByEmpId() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp emp = mapper.getEmpByEmpId(1);
sqlSession.close();
System.out.println(emp);
}
8.3、resultMap处理字段和属性的映射关系
若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射
- resultMap:设置自定义映射
- 属性:
- id:表示自定义映射的唯一标识
- type:查询的数据要映射的实体类的类型
- 子标签:
- id:设置主键的映射关系
- result:设置普通字段的映射关系
- association:设置多对一的映射关系
- collection:设置一对多的映射关系
- 属性:
- property:设置映射关系中实体类中的属性名
- column:设置映射关系中表中的字段名
1 EmpMapper.xml
<resultMap id="empResultMap" 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>
<!--Emp getEmpByEmpId(@Param("empId") int empId);-->
<select id="getEmpByEmpId" resultMap="empResultMap">
select * from t_emp where emp_id = #{empId}
</select>
8.4、多对一映射处理
1 映射关系
多个员工对应一个部门
多对一:对应的是一个对象
2 Student.java
public class Emp {
private Integer empId;
private String empName;
private Integer age;
private String gender;
private Dept dept;
}
3 Dept.java
public class Dept {
private Integer deptId;
private String deptName;
}
4 级联方式处理映射关系
查询员工信息以及员工所对应的部门信息
EmpMapper.java
// 获取员工以及所有对应部门的信息
Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);
EmpMapper.xml
<resultMap id="empAndDept" 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>
<result property="dept.deptId" column="dept_id"></result>
<result property="dept.deptName" column="dept_name"></result>
</resultMap>
<!--Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);-->
<select id="getEmpAndDeptByEmpId" resultMap="empAndDept">
select t1.emp_id, t1.emp_name, t1.age, t1.gender, t1.dept_id, t2.dept_id, t2.dept_name
from t_emp t1
left join t_dept t2
on t1.dept_id = t2.dept_id
where t1.emp_id = #{empId};
</select>
测试
@Test
public void testGetEmpAndDeptByEmpId() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp emp = mapper.getEmpAndDeptByEmpId(1);
sqlSession.close();
System.out.println(emp);
}
5 使用association处理映射关系
- association:处理多对一映射关系(处理实体类类型的属性)
- property:设置需要处理映射关系的属性的属性名
- javaType:设置要处理的属性的类型
EmpMapper.xml
<resultMap id="empAndDeptResult" type="Emp">
<id property="empName" column="emp_name"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="gender" column="gender"></result>
<association property="dept" javaType="Dept">
<id property="deptId" column="dept_id"></id>
<result property="deptName" column="dept_name"></result>
</association>
</resultMap>
<!--Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);-->
<select id="getEmpAndDeptByEmpId" resultMap="empAndDeptResult">
select t1.emp_id, t1.emp_name, t1.age, t1.gender, t1.dept_id, t2.dept_id, t2.dept_name
from t_emp t1
left join t_dept t2
on t1.dept_id = t2.dept_id
where t1.emp_id = #{empId};
</select>
测试
@Test
public void testGetEmpAndDeptByEmpId() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp emp = mapper.getEmpAndDeptByEmpId(1);
sqlSession.close();
System.out.println(emp);
}
6 分步查询
property:设置需要处理映射关系的属性的属性名
select:设置分布查询的SQL的唯一表示,(namespace.SQLId或者mapper接口的全类名.方法名)
column:设置分步查询的条件
①查询员工信息
EmpMapper.java
// 获取员工以及所有对应部门的信息
Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);
EmpMapper.xml
<resultMap id="empAndDeptByStepResultMap" 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>
<association property="dept"
select="pers.tianyu.mapper.DeptMapper.getEmpAndDeptByStepTow"
column="dept_id">
</association>
</resultMap>
<!--Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);-->
<select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">
select emp_id, emp_name, age, gender, dept_id
from t_emp
where emp_id = #{empId};
</select>
②根据员工所对应的部门id查询部门信息
DeptMapper.java
// 查询部门信息
Dept getEmpAndDeptByStepTow(@Param("deptId") Integer deptId);
DeptMapper.xml
<!--Dept getEmpAndDeptByStepTow(@Param("deptId") Integer deptId);-->
<select id="getEmpAndDeptByStepTow" resultType="Dept">
select dept_id, dept_name
from t_dept
where dept_id = #{deptId};
</select>
测试
@Test
public void testGetEmpAndDeptByStepOne() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp emp = mapper.getEmpAndDeptByStepOne(1);
sqlSession.close();
System.out.println(emp);
}
8.5、延迟加载
- 分步查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息(下滑线转驼峰)。
- lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。
- aggressiveLazyLoading:按需加载的全局开关,当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载。
- 当开启全局的延迟加载之后,可通过association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载, fetchType=“lazy(延迟加载)|eager(立即加载)”。
1 mybatis-config.xml
<!--延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--按需加载-->
<setting name="aggressiveLazyLoading" value="false"/>
2 EmpMapper.xml
在resultMap标签下association标签写设置fetchType=“eager”,可以单个查询不使用延迟加载。
8.6、一对多映射处理
一对多:对应的是一个集合
注意:当设置了部门中有员工信息,就不能设置员工中有部门信息,都设置会出现套娃。
1 collection
- collection:处理一对多的映射关系(处理集合类型的属性)
- ofType:设置collection标签所处理的集合属性中存储数据的类型
Dept.java
public class Dept {
private Integer deptId;
private String deptName;
private List<Emp> emps;
}
DeptMapper.xml
<resultMap id="deptEmpMap" type="Dept">
<id property="deptId" column="dept_id"></id>
<result property="deptName" column="dept_name"></result>
<collection property="emps" ofType="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>
</collection>
</resultMap>
<!--Dept getDeptEmpByDid(@Param("deptId") Integer deptId);-->
<select id="getDeptEmpByDid" resultMap="deptEmpMap">
select t1.dept_id, t1.dept_name, t2.emp_id, t2.emp_name, t2.age, t2.gender, t2.dept_id
from t_dept t1
left join t_emp t2
on t1.dept_id = t2.dept_id
where t1.dept_id = #{deptId}
</select>
2 分布查询
①查询部门信息
DeptMapper.java
// 分布查询部门和部门中的员工
Dept getDeptByStep(@Param("deptId") Integer deptId);
DeptMapper.xml
<resultMap id="deptEmpStep" type="Dept">
<id property="deptId" column="dept_id"></id>
<result property="deptName" column="dept_name"></result>
<collection property="emps"
select="pers.tianyu.mapper.EmpMapper.getEmpListByDeptId"
column="dept_id">
</collection>
</resultMap>
<!--Dept getDeptByStep(@Param("deptId") Integer deptId);-->
<select id="getDeptByStep" resultMap="deptEmpStep">
select dept_id, dept_name
from t_dept
where dept_id = #{deptId};
</select>
②根据部门id查询部门中的所有员工
EmpMapper.java
// 根据部门id查询员工信息
List<Emp> getEmpListByDeptId(@Param("deptId") Integer deptId);
EmpMapper.xml
<!--List<Emp> getEmpListByDeptId(@Param("deptId") Integer deptId);-->
<select id="getEmpListByDeptId" resultType="Emp">
select emp_id, emp_name, age, gender, dept_id *
from t_emp
where dept_id = #{deptId};
</select>