resultmap复杂映射问题
association
:关联(多对一的情况)collection
: 集合(一对多的情况)javatype
: 用来指定实体类中属性的类型。oftype
: 用来指定映射到list或集合中pojo的类型,泛型的约束类型。
ⅰ 多对一查询:学生——老师
数据库表:
create table `teacher` ( `id` int(10) not null, `name` varchar(30) default null, primary key (`id`) ) engine=innodb default charset=utf8; insert into teacher(`id`, `name`) values (1, '王老师'); create table `student` ( `id` int(10) not null, `name` varchar(30) default null, `tid` int(10) default null, primary key (`id`), key `fktid` (`tid`), constraint `fktid` foreign key (`tid`) references `teacher` (`id`) ) engine=innodb default charset=utf8; insert into `student` (`id`, `name`, `tid`) values ('1', '小明', '1'); insert into `student` (`id`, `name`, `tid`) values ('2', '小红', '1'); insert into `student` (`id`, `name`, `tid`) values ('3', '小张', '1'); insert into `student` (`id`, `name`, `tid`) values ('4', '小李', '1'); insert into `student` (`id`, `name`, `tid`) values ('5', '小王', '1');
(1) 创建实体类pojo
@data public class student { private int id; private string name; private teacher teacher; }
@data public class teacher { private int id; private string name; }
(2) 创建学生实体类对应的接口
public interface studentmapper { //查询所有学生的信息 list<student> getstudent(); list<student> getstudent2(); }
(3) 编写学生接口对应的mapper.xml
为了达到和接口在同一个包中的效果,在resource文件夹下新建包结构com.glp.dao:
<?xml version="1.0" encoding="utf-8" ?> <!doctype mapper public "-//mybatis.org//dtd config 3.0//en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.glp.dao.studentmapper"> <!--按照结果查询——联表查询--> <select id="getstudent2" resultmap="studentmap2"> select s.id sid,s.name sname,t.name tname from student s, teacher t where s.tid=t.id; </select> <resultmap id="studentmap2" type="student"> <result property="id" column="sid"/> <result property="name" column="sname"/> <association property="teacher" javatype="teacher"> <result property="name" column="tname"/> </association> </resultmap> <!--按照查询嵌套处理——子查询--> <select id="getstudent" resultmap="studentmap" > select * from student; </select> <resultmap id="studentmap" type="student"> <result property="id" column="id"/> <result property="name" column="name"/> <!--复杂属性:对象association, 集合collection--> <association property="teacher" column="tid" javatype="teacher" select="getteacher"/> </resultmap> <select id="getteacher" resulttype="teacher"> select * from teacher where id = #{id}; </select> </mapper>
在多对一查询中,需要用到teacher这个表,每个学生都对应着一个老师。而property只能处理单个属性,像teacher这种复杂属性(内含多个属性)需要进行处理。处理复杂对象要用association 。
方式一:
- 联表查询(直接查出所有信息,再对结果进行处理)
<resultmap id="studentmap2" type="student"> <result property="id" column="sid"/> <result property="name" column="sname"/> <association property="teacher" javatype="teacher"> <result property="name" column="tname"/> </association> </resultmap>
直接查询出学生和老师,然后用association
去取老师里面的属性property。
方式二:
- 子查询(先查出学生信息,再拿着学生中的tid,去查询老师的信息)
<resultmap id="studentmap" type="student"> <result property="id" column="id"/> <result property="name" column="name"/> <!--复杂属性:对象association--> <association property="teacher" column="tid" javatype="teacher" select="getteacher"/> </resultmap> <select id="getteacher" resulttype="teacher"> select * from teacher where id = #{id}; </select>
在resultmap中引入属性association
,通过javatype指定property="teacher"的类型,javatype="teacher"
。通过select引入子查询
(嵌套查询)。
这里是拿到学生中的tid,去查找对应的老师。
(4)在核心配置类中引入mapper
db.properties:数据库连接参数配置文件
driver = com.mysql.jdbc.driver url=jdbc:mysql://localhost:3306/mybatis?usessl=true&useunicode=true&chracterencoding=utf8 username =root password =mysql
mybatis.xml:
<?xml version="1.0" encoding="utf-8" ?> <!doctype configuration public "-//mybatis.org//dtd config 3.0//en" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties resource="db.properties"> <property name="username" value="root"/> <property name="password" value="mysql"/> </properties> <settings> <setting name="logimpl" value="stdout_logging"/> </settings> <typealiases> <typealias type="com.glp.pojo.student" alias="student"/> <typealias type="com.glp.pojo.teacher" alias="teacher"/> </typealiases> <environments default="development"> <environment id="development"> <transactionmanager type="jdbc"/> <datasource type="pooled"> <property name="driver" value="${driver}"/> <property name="url" value="${url}}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </datasource> </environment> </environments> <mappers> <mapper class="com.glp.dao.studentmapper"/> <mapper class="com.glp.dao.teachermapper"/> </mappers> </configuration>
注意:
要保证接口和mapper.xml都在同一个包中。
(5) 测试
public class userdaotest { @test public void getstudent(){ sqlsession sqlsession = myutils.getsqlsession(); studentmapper mapper = sqlsession.getmapper(studentmapper.class); list<student> list = mapper.getstudent(); for (student stu:list ) { system.out.println(stu); } sqlsession.close(); } @test public void getstudent2(){ sqlsession sqlsession = myutils.getsqlsession(); studentmapper mapper = sqlsession.getmapper(studentmapper.class); list<student> list = mapper.getstudent2(); for (student stu:list ) { system.out.println(stu); } sqlsession.close(); } }
ⅱ 一对多查询:老师——学生
(1)实体类
@data public class student { private int id; private string name; private int tid; }
@data public class teacher { private int id; private string name; private list<student> students; }
(2) 接口
package com.glp.dao; public interface teachermapper { teacher getteacher(@param("tid") int id); teacher getteacher2(@param("tid") int id); }
(3)接口对应的mapper.xml
<?xml version="1.0" encoding="utf-8" ?> <!doctype mapper public "-//mybatis.org//dtd config 3.0//en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.glp.dao.teachermapper"> <!--方式一 ======================= --> <select id="getteacher" resultmap="teacherstudent"> select s.id sid, s.name sname, t.name tname, t.id tid from student s ,teacher t where s.tid = t.id and t.id = #{tid}; </select> <resultmap id="teacherstudent" type="teacher"> <result property="id" column="tid"/> <result property="name" column="tname"/> <collection property="students" oftype="student"> <result property="id" column="sid"/> <result property="name" column="sname"/> <result property="tid" column="tid"/> </collection> </resultmap> <!--方式二 ======================= --> <select id="getteacher2" resultmap="teacherstudent2"> select * from teacher where id = #{tid}; <!--这里的tid和接口中指定的属性名相同--> </select> <resultmap id="teacherstudent2" type="teacher"> <result property="id" column="id"/> <result property="name" column="name"/> <!--上面的两个可以省略--> <collection property="students" column="id" javatype="arraylist" oftype="student" select="getstubyid"/> </resultmap> <select id="getstubyid" resulttype="student"> select * from student where tid=#{tid}; <!--查询老师对应的学生,#{tid}--> </select> </mapper>
方式一:
- 联表查询,需要写复杂sql
- collection 用来处理集合,oftype用来指定集合中的约束类型
- 联合查询时,查询出所以结果,然后再解析结果中的属性,将属性property赋予到collection中。
方式二:
- 子查询,需要写复杂映射关系
查询学生时,需要拿着老师的id去查找,column用来给出老师的id。
(4)测试:
package com.glp.dao; public class userdaotest { @test public void getteacher(){ sqlsession sqlsession = myutils.getsqlsession(); teachermapper mapper = sqlsession.getmapper(teachermapper.class); teacher teacher = mapper.getteacher(1); system.out.println(teacher); sqlsession.close(); } @test public void getteacher2(){ sqlsession sqlsession = myutils.getsqlsession(); teachermapper mapper = sqlsession.getmapper(teachermapper.class); teacher teacher = mapper.getteacher2(1); system.out.println(teacher); sqlsession.close(); } }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论