1.1. 为什么要使用结果映射
解决表字段名和对象属性名不一样的情况(如:表的多对一,多对多,一对一,一对多).
关联对象查询,在mybatis不会默认查询出来,需要自己查询结果并且通过resultMap来配置
1.2. 关联映射分类
一对一:一个员工只有一个身份证号。随意一方设计一个字段
多对一:多个员工对应一个部门。一般在多方设计一个一方属性 员工里面设计部门字段
一对多:一个部门拥有多个员工。还是在多方维护对象关联关系
多对多: 一个员工有多个角色。一个角色属于多个员工。用中间表来表示
本质上:多对一,一对一是一样的,都只是处理一个关联(association )。而一对多、多对多也是一样处理的都是集合(collection)
1.3. 关联映射处理方式
MyBatis提供两种方式处理我们关联对象,嵌套查询和嵌套结果。
嵌套结果: 发送1条SQL,查询所有的信息(本身+关联对象)
嵌套查询:发送1+N条sql。
接下来,分别使用两种方式对多对一、一对一和一对多、多对多进行处理。
2.1. 多对一、一对一(通过学生找到老师)
2.1.1.准备一个Studen.java学生类,和一个Teacher.java老师类
Studen.java学生类:
/** * 学生类,多方 */ public class Student { private Long id; private String name; private Integer age; private String hobby; /** *老师一方 */ private Teacher teacher; //get和set和tostring...(get和set和tostring是要的,太长了没复制) }
Teacher.java老师类
/** * 老师类 ,一方 */ public class Teacher { private Long id; private String name; private Integer age; //get和set和tostring...(太长没复制) }
2.1.2为学生类写个接口StudenMapper.java
import java.util.List; public interface StudentMapper { //查询所有学生数据和学生对应的老师数据 List<Student> queryBy(); }
2.1.2为学生添加Mapper配置文件StudentMapper.xml(重点来了)
2.1.2.1——2.1.2.3任选一种
2.1.2.1.嵌套结果
<!-- 1.嵌套结果 id="studentMap": 和下面select的resultMap="studentMap"对应,双引号中的值要相同 property:java类里面属性 <id property="id" column="id"></id>:就是主键 column:查询出来列名(写sql时取了别名就用别名如:t.name tname;那column="tname") javaType:javatype指定的是teacher对象的属性的类型(例如id,name,age) --> <resultMap id="studentMap" type="student"> <id property="id" column="id"></id> <result property="name" column="name"></result> <result property="hobby" column="hobby"></result> <association property="teacher" javaType="teacher"> <id property="id" column="tid"></id> <result property="name" column="tname"></result> <result property="age" column="tage"></result> </association> </resultMap> <!-- id:id的值要和你StudenMapper.java接口中的queryBy()方法名一致 resultMap:resultMap的值和上面resultMap的id的值对应的,要一样 --> <select id="queryBy" resultMap="studentMap"> SELECT s.id, s.name, s.hobby, t.id tid, t.name tname, t.age tage FROM t_student s JOIN t_teacher t on s.tid = t.id </select>
2.1.2.2.嵌套结果扩展
<!--1.1嵌套结果-扩展--> <resultMap id="studentMap" type="Student"> <id property="id" column="id"></id> <result property="name" column="name"></result> <result property="hobby" column="hobby"></result> <!-- property="teacher.id":你在Studen.java学生类中有个teacher字段而 teacher的字段是Teacher类, 可以用teacher.teacher的字段来赋值 --> <result property="teacher.id" column="cid"></result> <result property="teacher.name" column="cname"></result> <result property="teacher.age" column="cage"></result> </resultMap> <select id="queryBy" resultMap="studentMap"> SELECT s.id,s.name,s.hobby,t.id cid,t.name cname,t.age cage FROM t_student s JOIN t_teacher t ON s.id = t.id </select>
2.1.2.3嵌套查询
<!--2.1嵌套查询--> <resultMap id="studenMap" type="Student"> <id property="id" column="id"></id> <result property="name" column="name"></result> <result property="hobby" column="hobby"></result> <!-- 属性解释: property:对象所对应的字段 column:表返回的数据,这column会当做参数据传入queryByT方法中 javaType:指定属性的类型! select:查询方法,它的值要和<select id="queryByT" resultType="Teacher">...</select> 的id属性值一致 --> <association property="teacher" column="tid" javaType="Teacher" select="queryByT"></association> </resultMap> <select id="queryBy" resultMap="studenMap"> SELECT id,name,hobby,tid FROM t_student </select> <select id="queryByT" resultType="Teacher"> SELECT id,name,age FROM t_teacher WHERE id = #{id} </select>
还是在说一篇2.1.2.1——2.1.2.3任选一种
2.2测试
MyBataisUtil.MYBATAIS.getSqlSession();的由来可以看下面封装sqlSession
public class StudentMapperTest { @Test public void queryBy() throws Exception{ //MyBataisUtil.MYBATAIS.getSqlSession()自己封装好的sqlSession SqlSession sqlSession = MyBataisUtil.MYBATAIS.getSqlSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); List<Student> students = mapper.queryBy(); for (Student student : students) { System.out.println(student); } } }
封装sqlSession:
创建个MyBataisUtil.java的类
//枚举单例模式实现封装sqlSession public enum MyBataisUtil { MYBATAIS; private static SqlSessionFactory sqlSessionFactory; static { try { //读取配置文件 Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml"); //获取sqlSessionFactory(sql会话工厂) sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); } catch (IOException e) { e.printStackTrace(); } } public SqlSession getSqlSession(){ //获取sqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); return sqlSession; } }