7.mybatis一对多关联查询
和第5节一对一查询类似,但是不同的是,一对一使用的是association,而一对多使用collection。
实例:
1个班级Class,对应1个老师Teacher,对应多个学生Student

1.建表如下:
class[cid, cname, tid]
teacher[tid, tname]
student[sid, sname, cid]
插入数据:
class:
insert into class values(1,'一年级',1);
insert into class values(2,'二年级',2); teacher:
insert into teacher values(1,'老师A');
insert into teacher values(2,'老师B'); student:
INSERT INTO `mybatis`.`student`(`sid`,`sname`,`cid`) VALUES ( 1,'学生A',1);
INSERT INTO `mybatis`.`student`(`sid`,`sname`,`cid`) VALUES ( 2,'学生B',1);
INSERT INTO `mybatis`.`student`(`sid`,`sname`,`cid`) VALUES ( 3,'学生C',1);
INSERT INTO `mybatis`.`student`(`sid`,`sname`,`cid`) VALUES ( 4,'学生D',2);
INSERT INTO `mybatis`.`student`(`sid`,`sname`,`cid`) VALUES ( 5,'学生E',2);
2.新建Java实体类:
Clazz类:
public class Clazz {
    private int id;
    private String name;
    private Teacher teacher;
    private List<Student> stuList;
    public Clazz() {
        super();
    }
    public Clazz(int id, String name, Teacher teacher, List<Student> stuList) {
        super();
        this.id = id;
        this.name = name;
        this.teacher = teacher;
        this.stuList = stuList;
    }
    public List<Student> getStuList() {
        return stuList;
    }
    public void setStuList(List<Student> stuList) {
        this.stuList = stuList;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Teacher getTeacher() {
        return teacher;
    }
    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }
    @Override
    public String toString() {
        return "Clazz [id=" + id + ", name=" + name + ", teacher=" + teacher
                + ", stuList=" + stuList + "]";
    }
}
Teacher:
public class Teacher {
    private int id;
    private String name;
    public Teacher() {
        super();
    }
    public Teacher(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Teacher [id=" + id + ", name=" + name + "]";
    }
}
Teacher类:
public class Student {
    private int id;
    private String name;
    public Student(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    public Student() {
        super();
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + "]";
    }
}
3.要获取一个班级Clazz的完整关联信息,写clazzMapper.xml
<?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">
<!--
为了使用mapper的标签,在此要在Window-Preference-Xml Catalog中配置mybatis-3-mapper.dtd,
key=-//mybatis.org//DTD Mapper 3.0//EN
-->
<mapper namespace="com.mlxs.mybatis.test5.clazzMapper"> <!--
一对多 关联查询: 方式一:嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集
SELECT * FROM class c, teacher t, student s WHERE c.tid=t.tid AND c.cid=s.cid AND c.cid=#{id}
-->
<!-- 查询班级及其老师信息 -->
<select id="getClazz" parameterType="int" resultMap="getClazzMap">
SELECT * FROM class c, teacher t, student s WHERE c.tid=t.tid AND c.cid=s.cid AND c.cid=#{id}
</select> <resultMap type="Clazz" id="getClazzMap">
<id property="id" column="cid"/>
<result property="name" column="cname"/>
<!-- 关联查询teacher 一对一 -->
<association property="teacher" javaType="Teacher">
<id property="id" column="tid"/>
<result property="name" column="tname"/>
</association>
<!-- 关联班级对应的student 一对多 ofType代表集合中存放的对象类型-->
<collection property="stuList" ofType="Student">
<id property="id" column="sid"/>
<result property="name" column="sname"/>
</collection>
</resultMap> <!--
一对多 关联查询: 方式二:嵌套查询:使用嵌套结果映射来处理重复的联合结果的子集
SELECT * FROM class WHERE cid=#{id} //查询得到tid、cid用于给下面2条语句使用
SELECT * FROM teacher WHERE tid=#{id} //tid为第一条sql查询后的tid
SELECT * FROM student WHERE cid=#{id} //cid为第一条sql查询后的cid
-->
<!-- 查询班级及其老师信息 -->
<select id="getClazz2" parameterType="int" resultMap="getClazzMap2">
SELECT * FROM class WHERE cid=#{id}
</select>
<!-- 这里必须写成别名形式SELECT tid id, tname name,否则查询结果为null -->
<select id="getTeacher" parameterType="int" resultType="Teacher">
SELECT tid id, tname name FROM teacher WHERE tid=#{id}
</select>
<select id="getStuList" parameterType="int" resultType="Student">
SELECT sid id, sname name FROM student WHERE cid=#{id}
</select> <resultMap type="Clazz" id="getClazzMap2">
<id property="id" column="cid"/>
<result property="name" column="cname"/>
<!-- 关联查询teacher 一对一 -->
<association property="teacher" column="tid" select="getTeacher"/>
<!-- 关联班级对应的student 一对多 ofType代表集合中存放的对象类型-->
<collection property="stuList" column="cid" select="getStuList"/>
</resultMap> </mapper>
4.写测试类:
public class _Test6OneToMany {
    /**
     * 方式一:嵌套结果
     * @author 魅力_小生
     *
     */
    @Test
    public void getClazz1(){
        //创建session,设置事务为true
        SqlSession session = MyBatisUtil.getSessionFactory().openSession(true);
        String statement = "com.mlxs.mybatis.test5.clazzMapper.getClazz";
        Clazz clazz = session.selectOne(statement, "1");
        System.out.println("clazz--->"+clazz);
        session.close();
    }
    /**
     * 方式二:嵌套查询,通过执行另外一个SQL 映射语句来返回预期的复杂类型
         SELECT * FROM class WHERE cid=#{id}   //查询得到tid、cid用于给下面2条语句使用
        SELECT * FROM teacher WHERE tid=#{id} //tid为第一条sql查询后的tid
        SELECT * FROM student WHERE cid=#{id} //cid为第一条sql查询后的cid
     * @author 魅力_小生
     *
     */
    @Test
    public void getClazz2(){
        //创建session,设置事务为true
        SqlSession session = MyBatisUtil.getSessionFactory().openSession(true);
        String statement = "com.mlxs.mybatis.test5.clazzMapper.getClazz2";
        Clazz clazz = session.selectOne(statement, "2");
        System.out.println("clazz--->"+clazz);
        session.close();
    }
}
5.结果:
getClazz1:
clazz--->Clazz [id=1, name=一年级, teacher=Teacher [id=1, name=老师A], stuList=[Student [id=1, name=学生A], Student [id=2, name=学生B], Student [id=3, name=学生C]]] getClazz2:
clazz--->Clazz [id=2, name=二年级, teacher=Teacher [id=2, name=老师B], stuList=[Student [id=4, name=学生D], Student [id=5, name=学生E]]]

7.mybatis一对多关联查询的更多相关文章
- mybatis一对多关联查询+pagehelper->分页错误
		
mybatis一对多关联查询+pagehelper->分页错误. 现象: 网上其他人遇到的类似问题:https://segmentfault.com/q/1010000009692585 解决: ...
 - mybatis一对多关联查询——(九)
		
1.需求: 查询所有订单信息及订单下的订单明细信息. 订单信息与订单明细为一对多关系. 2. sql语句 确定主查询表:订单表 确定关联查询表:订单明细表 在一对一查询基础上添加订单明细表关 ...
 - MyBatis 一对多关联查询
		
sqlxml文件 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC ...
 - Mybatis 一对多 关联查询查询
		
一对多 与 一对一 查询有许多相似之处. 最主要的区别是 查询结果是list,与之对应的标签为collection. 班级和学生,一个班有多个学生,而每个学生只能属于一个班. 此时班级编号作为学生表的 ...
 - MyBatis从入门到放弃四:一对多关联查询
		
前言 上篇学习了一对一关联查询,这篇我们学习一对多关联查询.一对多关联查询关键点则依然是配置resultMap,在resultMap中配置collection属性,别忽略了ofType属性. 搭建开发 ...
 - MyBatis:一对多关联查询
		
MyBatis从入门到放弃四:一对多关联查询 前言 上篇学习了一对一关联查询,这篇我们学习一对多关联查询.一对多关联查询关键点则依然是配置resultMap,在resultMap中配置collecti ...
 - MyBatis关联查询,一对多关联查询
		
实体关系图,一个国家对应多个城市 一对多关联查询可用三种方式实现: 单步查询,利用collection标签为级联属性赋值: 分步查询: 利用association标签进行分步查询: 利用collect ...
 - mybatis collection 一对多关联查询,单边分页的问题总结!
		
若想直接通过sql实现多级关联查询表结构得有2 个必不可少的字段:id ,parentId,levelId id:主键id, parentId:父id levelId:表示第几级(表本身关联查询的时候 ...
 - MyBatis初级实战之六:一对多关联查询
		
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
 
随机推荐
- JavaScript复习笔记——字符串
			
String构造器可以使用new调用,也可以不使用,但是,这两种调用的结果也是完全不一样的.用new调用的时候,String作为构造器函数,创建字符串对象.不使用new的时候,String用作一个常规 ...
 - Delphi 调用 Rest 服务的一些
			
1.关于数据接收的格式 测试发现获取的json源数据中间汉字的地方是乱码,导致引号不配对,引发内存错误. TIdHttp在获取数据之前,要将定义的TStringStream的Encoding设置为UT ...
 - JS调用Java函数--DWR框架
			
(1)dwr与ssh框架整合教程dwr框架介绍. DWR(Direct Web Remoting)是一个用于改善web页面与Java类交互的远程服务器端Ajax开源框架,可以帮助开发人员开发包含AJA ...
 - satis 搭建 Composer 私有库的方法
			
安装 satis 命令行下执行: php create-project composer/satis --stability=dev --keep-vcs . 配置 创建 satis.json 文件, ...
 - Android推送方案分析(MQTT/XMPP/GCM)
			
本文主旨在于,对目前Android平台上最主流的几种消息推送方案进行分析和对比,比较客观地反映出这些推送方案的优缺点,帮助大家选择最合适的实施方案. 方案1. 使用GCM服务(Google Cloud ...
 - Win7家庭版包“已停止工作”
			
在VS2010上依据接口,写了个WiFi共享软件,在Win7旗舰班上正确无误,而在却在Win7家庭版上运行不了,报“已停止工作”错误. 解决方法: 1.下载安装vs2010对应的.Net平台:Micr ...
 - 【转】MYSQL入门学习之七:MYSQL常用函数
			
转载地址:http://www.2cto.com/database/201212/175864.html 一.数学函数 www.2cto.com ABS(x) ...
 - java 同步锁方法
			
方法一:动态同步锁 class Demo_thread implements Runnable{ public static int sum = 0; public synchronized void ...
 - 在Windows Live Writer中插入C# code
			
平时都是用Windows Live Writer写博客,发布博客.遇到需要插入代码都是先在notepad中写好,或者是拷贝到notepad,再从notepad中拷到Windows Live Write ...
 - MSSQL删除字段时出现 服务器: 消息 5074,级别 16,状态 1,行 1 的解决办法
			
有的朋友在做用户维护字段的界面时,肯定发现一个问题,当用脚本:ALTER TABLE 表名 DROP COLUMN 字段名进行删除字段的操作时,会出现“服务器: 消息 5074,级别 16,状态 1, ...