解决多表之间的查询
- 1.什么是resultMap
- 2.使用resultMap
- 3.解决一对一关系的表
- 方式一
- 方式二
- 方式三
- 4.解决一对多关系的表
- 5.解决多对多关系的表
- 6.总结和注意点
1.什么是resultMap
resultMap:结果映射
作用:
1).解决实体类属性名与表中列名不一致的问题
2).解决多表关联查询的问题
2.使用resultMap
表结构
实体类
package com.hr.entity;
public class Student {
//get set 自己提供这里不写了
private Integer sid;
private String sname;
private String sex;
private Integer eid;
}
<!--Student.xml-->
<!--因为表中的name列和实体类的sname属性名不一致,该属性查询时没有值-->
<select id="selectAll" resultType="UserInfo">
select * from userinfo
</select>
<!--解决方案一:取别名-->
<select id="select1" resultType="UserInfo">
select sid,sex,eid,name sname from userinfo
</select>
<!--解决方案二:使用resultMap映射-->
<!--type:类型
id:唯一标识
-->
<resultMap type="UserInfo" id="userInfoResultMap">
<!--
column:数据库的列
property:实体类属性
-->
<!-- id节点用来映射主键属性与之间列的关系 -->
<id column="id" property="id"/>
<!-- result节点用来映射普通属性与普通列的关系 -->
<result column="sid" property="sid"/>
<result column="name" property="sname"/>
<result column="sex" property="sex"/>
<result column="eid" property="eid"/>
</resultMap>
<!--注意点:resultMap对应resultMap节点的id-->
<select id="select2" resultMap="userInfoResultMap">
select * from userinfo
</select>
3.解决一对一关系的表
card表
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210416162942235.png
person表
实体类
package com.hr.entity;
public class Person {
private Integer id;
private String name;
//一个person对应一个card
private Card card;
}
package com.hr.entity;
public class Card {
private Integer id;
private String address;
//一个card对应一个person
private Person person;
}
查person带card
<!--Person.xml-->
<!--提取一个对应自身配置的resultMap-->
<resultMap type="Person" id="personBaseMap">
<id column="id" property="id"/>
<result column="name" property="name"/>
</resultMap>
<!--Card.xml-->
<!--提取一个对应自身配置的resultMap-->
<resultMap type="Card" id="cardBaseMap">
<id column="id" property="id"/>
<result column="address" property="address"/>
</resultMap>
方式一
<!--
一对一方式1:引用外部select(N+1条sql语句)
好处:sql分解了,并且可以复用
坏处:sql执行与表中数据成正比,效率低
-->
<resultMap type="Person" id="personMap1" extends="personBaseMap">
<!--
association节点用来配置关联的对象属性
property:指定关联对象属性名
select:指定另外一个sql的id名,调用该sql查询当前person对应的card信息
column:指定person表的哪个列作为条件值取调用select指定的sql语句
-->
<association property="card" column="id" select="selectCard1"></association>
</resultMap>
<select id="selectCard1" parameterType="int" resultType="Card">
select * from card where id=#{id}
</select>
<select id="select1" resultMap="personMap1">
select * from person
</select>
//PersonDao加
List<Person> select1();
SqlSession session=BaseSession.getSession();
PersonDao dao=session.getMapper(PersonDao.class);
dao.select1();
方式二
<!--
一对一方式2:内嵌resultMap
好处:只有一条sql语句,效率高
坏处:sql语句相对复杂(可能会涉及到列重名),内嵌的resultMap不能重用
-->
<resultMap type="Person" id="personMap2" extends="personBaseMap">
<association property="card" javaType="Card">
<id column="id" property="id"/>
<result column="address" property="address"/>
</association>
</resultMap>
<select id="select2" resultMap="personMap2">
select * from person p,card c where p.id=c.id
</select>
//PersonDao加
List<Person> select2();
SqlSession session=BaseSession.getSession();
PersonDao dao=session.getMapper(PersonDao.class);
dao.select2();
方式三
<!--
一对一方式3:引用外部resultMap
好处:配置可以复用,只有一条sql效率高
坏处:代码配置分散,观看不直观
-->
<resultMap type="Person" id="personMap3" extends="personBaseMap">
<!--使用其他xml中的resultMap时需要加上命名空间-->
<association property="card" resultMap="com.hr.mapper.CardMapper.cardBaseMap"></association>
</resultMap>
<select id="select3" resultMap="personMap3">
select * from person p,card c where p.id=c.id
</select>
//PersonDao加
List<Person> select3();
SqlSession session=BaseSession.getSession();
PersonDao dao=session.getMapper(PersonDao.class);
dao.select3();
4.解决一对多关系的表
author表
book表
实体类
package com.hr.entity;
import java.util.List;
public class Author {
private Integer id;
private String name;
//一个作者有多本书
private List<Book> list;
}
package com.hr.entity;
public class Book {
private Integer id;
private String name;
private Integer aid;
//一本书属于一个作者
private Author author;
}
查author带book
<resultMap type="Author" id="AuthorBase">
<id column="id" property="id"/>
<result column="name" property="name"/>
</resultMap>
<resultMap type="Book" id="BookMap1">
<id column="bid" property="id"/>
<result column="bname" property="name"/>
<result column="authorid" property="aid"/>
</resultMap>
<resultMap type="Author" id="AuthorMap1" extends="AuthorBase">
<!--单个用association 对应 javaType
集合用collection 对应 ofType
-->
<collection property="list" resultMap="BookMap1"></collection>
</resultMap>
<select id="select1" resultMap="AuthorMap1">
select * from author a left join book b on a.id=b.aid
</select>
//AuhorDao加
List<Book> select1();
SqlSession session=BaseSession.getSession();
AuhorDao dao=session.getMapper(AuhorDao.class);
dao.select1();
5.解决多对多关系的表
student表(学生)
teacher表(老师)
t_tea_stu表(中间关系表)
实体类
一个学生有多个老师,一个老师也有多个学生
package com.hr.entity;
import java.util.List;
public class Teacher {
private Integer tid;
private String tname;
//一个老师有多个学生
private List<Student> students;
}
package com.hr.entity;
import java.util.List;
public class Student {
private Integer sid;
private String sname;
//一个学生多个老师
private List<Teacher> teachers;
}
查老师带学生
<resultMap type="Teacher" id="TeacherBase">
<id property="tid" column="tid"/>
<result property="tname" column="tname"/>
</resultMap>
<resultMap type="Teacher" id="TeacherMap1" extends="TeacherBase">
<collection property="students" ofType="Student">
<id property="sid" column="sid"/>
<result property="sname" column="sname"/>
</collection>
</resultMap>
<select id="select1" resultMap="TeacherMap1">
select t.*,s.* from student s,t_tea_stu ts,teacher t
where
s.sid=ts.studentId and t.tid=ts.teacherId
</select>
//TeacherDao加
List<Student> select1();
SqlSession session=BaseSession.getSession();
TeacherDao dao=session.getMapper(TeacherDao.class);
dao.select1();
6.总结和注意点
- resultType不能和resultMap一起使用
resultType:不能使用resultMap的映射
resultMap:不能使用基本数据类型,只能使用映射关系 - 关系是单个对象使用:association,association使用内嵌resultMap时对应 javaType
关系是集合对象使用:collection,collection使用内嵌resultMap时对应 ofType - resultMap要使用外部映射文件,需要加命名空间和id
- 多对多可以理解成两个一对多
- 在一对一时使用了三种方式写,在一对多,多对多都可以写
1)方式一:引用外部select(N+1条sql语句)
好处: sql分解了,并且可以复用
坏处: sql执行与表中数据成正比,效率低
2)方式二:内嵌resultMap
好处: 只有一条sql语句,效率高
坏处: sql语句相对复杂(可能会涉及到列重名),内嵌的resultMap不能重用
3)方式三:引用外部resultMap
好处: 配置可以复用,只有一条sql效率高
坏处: 代码配置分散,观看不直观