Mybatis自定义映射
对于字段名和实体类的属性不一样的情况 我们在映射配置文件中的select标签中是不能用ResultType
我们有以下的几种处理方法:
- a>起别名
- b>设置全局配置,将下划线映射为驼峰
* <setting name="mapUnderscoreToCamelCase" value="true"/>
- c>使用resultMap实现自定义映射
- 自定义映射详解如下
<?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">
<!--
resultMap:设置自定义映射
属性:
id:设置唯一标识
type:设置自定义映射要处理的类型
子标签:
id:设置主键的映射关系
result:设置普通字段的映射关系
association:处理多对一的映射关系,即实体类类型的属性
collection:处理一对多的映射关系,即list集合类型的属性
子标签中的属性:
column:设置映射关系中的字段名
property:设置映射关系中的属性名
-->
<mapper namespace="com.guigu.mybatis.mapper.StudentMapper">
<resultMap id="sdtResultMap" type="Student">
<id column="sdt_id" property="sdtId"></id>
<result column="sdt_name" property="sdtName"></result>
<result column="sdt_age" property="sdtAge"></result>
<result column="sdt_gender" property="sdtGender"></result>
<result column="sdt_gender" property="sdtGender"></result>
<result column="bj_id" property="bjId"></result>
</resultMap>
<select id="findStudentById" resultMap="sdtResultMap">
select *from student where sdt_id=#{id}
</select>
</mapper>
涉及两张表时 我们设置如下两个实体类的关系
班级表和学生表
一对多即是把班级设置为学生的一个属性
多对一即使在班级表中设置一个学生的LIst(推荐)这样在自定义映射时设置标签时就可以访问到属性
多对一(实体类类型的属性)的处理方式:
1、级联
2、association
3、分步查询
1.级联
package com.guigu.mybatis.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BanJi {
private Integer bjId;
private String bjName;
private List<Student> students;
}
```java
package com.guigu.mybatis.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private Integer sdtId;
private String sdtName;
private Integer sdtAge;
private String sdtGender;
private BanJi banJi;
}
测试类放在最后面
<?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">
<!--
多对一(实体类类型的属性)的处理方式:
1、级联
2、association
3、分步查询
一对多(list集合类型的属性)的处理方式:
1、collection
2、分步查询
-->
<!--
resultMap:设置自定义映射
属性:
id:设置唯一标识
type:设置自定义映射要处理的类型
子标签:
id:设置主键的映射关系
result:设置普通字段的映射关系
association:处理多对一的映射关系,即实体类类型的属性
collection:处理一对多的映射关系,即list集合类型的属性
子标签中的属性:
column:设置映射关系中的字段名
property:设置映射关系中的属性名
-->
<mapper namespace="com.guigu.mybatis.mapper.StudentMapper">
<resultMap id="sdtResultMap" type="Student">
<id column="sdt_id" property="sdtId"></id>
<result column="sdt_name" property="sdtName"></result>
<result column="sdt_age" property="sdtAge"></result>
<result column="sdt_gender" property="sdtGender"></result>
<result column="sdt_gender" property="sdtGender"></result>
<result column="bj_id" property="banJi.bjId"></result>
<result column="bj_name" property="banJi.bjName"></result>
</resultMap>
<select id="findStudentById" resultMap="sdtResultMap">
select *from student left join banji on student.bj_id=banji.bj_id where student.bj_id=#{id}
<!--select *from student where sdt_id=#{id}-->
</select>
</mapper>
2.association标签
<!--association-->
<resultMap id="sdtResultMapTwo" type="Student">
<id column="sdt_id" property="sdtId"></id>
<result column="sdt_name" property="sdtName"></result>
<result column="sdt_age" property="sdtAge"></result>
<result column="sdt_gender" property="sdtGender"></result>
<result column="sdt_gender" property="sdtGender"></result>
<association property="banJi" javaType="BanJi">
<id column="bj_id" property="bjId"></id>
<result column="bj_name" property="bjName"></result>
</association>
</resultMap>
<select id="findStudentByIdTwo" resultMap="sdtResultMapTwo">
select *from student left join banji on student.bj_id=banji.bj_id where student.sdt_id=#{id}
</select>
3.分步查询
先根据id查询学生信息,然后就可以根据学生的班级id查询班级信息
第一步写在学生类接口的映射文件
第二步写在班级接口的映射文件
注意
select:设置分步查询下一步SQL语句的唯一标识(namespace.SQLId 简单理解就是方法的全类名 就是包名一直…到.方法)
column:将某个字段设置为下一步SQL执行的条件( 第一步查询信息的某一字段设为第二步查询的条件)
<!--分步查询1-->
<resultMap id="sdtResultMapThree" type="Student">
<id column="sdt_id" property="sdtId"></id>
<result column="sdt_name" property="sdtName"></result>
<result column="sdt_age" property="sdtAge"></result>
<result column="sdt_gender" property="sdtGender"></result>
<association property="banJi" select="com.guigu.mybatis.mapper.BanjiMapper.findStudentByIdThrees" column="bj_id"></association>
</resultMap>
<select id="findStudentByIdThree" resultMap="sdtResultMapThree">
select * from student where student.sdt_id=#{id}
</select>
<!--分步查询第二(写为resultType更加方面没有必要设置map)-->
<select id="findStudentByIdThrees" resultType="BanJi">
select *from banji where bj_id=#{banJiId}
</select>
一对多的表关系
1、collection
2、分步查询
此时在班级表中学生就是一个集合
collection
<resultMap id="banJiresultMap" type="BanJi">
<id column="bj_id" property="bjId"></id>
<result column="bj_name" property="bjName"></result>
<collection property="students" ofType="Student">
<id column="sdt_id" property="sdtId"></id>
<result column="sdt_name" property="sdtName"></result>
<result column="sdt_age" property="sdtAge"></result>
<result column="sdt_gender" property="sdtGender"></result>
</collection>
</resultMap>
<select id="findBanJiById" resultMap="banJiresultMap">
select *from banji left join student on banji.bj_id=student.bj_id where banji.bj_id=#{banJiId}
</select>
分步查询
<!--是否开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--
property:设置处理的集合类型的属性的属性名
ofType:设置集合中存储的数据的类型
-->
<resultMap id="banJiresultStep" type="BanJi">
<id column="bj_id" property="bjId"></id>
<result column="bj_name" property="bjName"></result>
<collection property="students" select="com.guigu.mybatis.mapper.StudentMapper.findBanJiByIdTwos" column="bj_id"></collection>
</resultMap>
<select id="findBanJiByIdTwo" resultMap="banJiresultStep">
select *from banji where bj_id=#{banJiId}
</select>
<select id="findBanJiByIdTwos" resultType="Student">
select *from student where bj_id=#{bId}
</select>
package com.guigu.mybatis.test;
import com.guigu.mybatis.mapper.BanjiMapper;
import com.guigu.mybatis.mapper.StudentMapper;
import com.guigu.mybatis.pojo.BanJi;
import com.guigu.mybatis.pojo.Student;
import com.guigu.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
public class StudentTest {
@Test
public void testfindEmpById(){
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student = mapper.findStudentById(1);
System.out.println(student);
}
@Test
public void testfindStudentByIdTwo(){
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student = mapper.findStudentById(1);
System.out.println(student);
}
@Test
public void testfindStudentByIdThree(){
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student = mapper.findStudentByIdThree(1);
System.out.println(student);
}
@Test
public void testfindBanJiById(){
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
BanjiMapper mapper = sqlSession.getMapper(BanjiMapper.class);
BanJi banJi = mapper.findBanJiById(1);
System.out.println(banJi);
}
@Test
public void testfindBanJiByIdTwo(){
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
BanjiMapper mapper = sqlSession.getMapper(BanjiMapper.class);
BanJi banJiByIdTwo = mapper.findBanJiByIdTwo(1);
System.out.println(banJiByIdTwo);
}
}
// 如果开启了延迟加载 此时输出班级id时不会执行下一句sql System.out.println(banJiByIdTwo.getBjId());