和第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一对多关联查询的更多相关文章

  1. mybatis一对多关联查询+pagehelper->分页错误

    mybatis一对多关联查询+pagehelper->分页错误. 现象: 网上其他人遇到的类似问题:https://segmentfault.com/q/1010000009692585 解决: ...

  2. mybatis一对多关联查询——(九)

    1.需求: 查询所有订单信息及订单下的订单明细信息. 订单信息与订单明细为一对多关系. 2.      sql语句 确定主查询表:订单表 确定关联查询表:订单明细表 在一对一查询基础上添加订单明细表关 ...

  3. MyBatis 一对多关联查询

    sqlxml文件 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC ...

  4. Mybatis 一对多 关联查询查询

    一对多 与 一对一 查询有许多相似之处. 最主要的区别是 查询结果是list,与之对应的标签为collection. 班级和学生,一个班有多个学生,而每个学生只能属于一个班. 此时班级编号作为学生表的 ...

  5. MyBatis从入门到放弃四:一对多关联查询

    前言 上篇学习了一对一关联查询,这篇我们学习一对多关联查询.一对多关联查询关键点则依然是配置resultMap,在resultMap中配置collection属性,别忽略了ofType属性. 搭建开发 ...

  6. MyBatis:一对多关联查询

    MyBatis从入门到放弃四:一对多关联查询 前言 上篇学习了一对一关联查询,这篇我们学习一对多关联查询.一对多关联查询关键点则依然是配置resultMap,在resultMap中配置collecti ...

  7. MyBatis关联查询,一对多关联查询

    实体关系图,一个国家对应多个城市 一对多关联查询可用三种方式实现: 单步查询,利用collection标签为级联属性赋值: 分步查询: 利用association标签进行分步查询: 利用collect ...

  8. mybatis collection 一对多关联查询,单边分页的问题总结!

    若想直接通过sql实现多级关联查询表结构得有2 个必不可少的字段:id ,parentId,levelId id:主键id, parentId:父id levelId:表示第几级(表本身关联查询的时候 ...

  9. MyBatis初级实战之六:一对多关联查询

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

随机推荐

  1. android 项目学习随笔二十一(IM、语音识别、机器人、统计、扫描二维码、条形码)

    语音识别:科大讯飞语音云 http://www.xfyun.cn/ 语音机器人模拟 public class TalkBean { public String text; public boolean ...

  2. PHP判断客户端是PC web端还是移动手机端方法

    PHP判断客户端是PC web端还是移动手机端方法需要实现:判断手机版的内容加上!c550x260.jpg后缀变成缩略图PHP用正则批量替换Img中src内容,用正则表达式获取图片路径实现缩略图功能 ...

  3. datatables中columns.render的使用

    可直接在columns申明中对应列下方使用render改变该列样式 也可单独在columnsDefs中用targets指定目标. "render":function(data,ty ...

  4. Backup: Array in Perl6

    Array in Perl6 继承List,而List又继承Iterable,Positional,Cool ARRAY.pop ARRAY.shift ARRAY.push: VALUES ARRA ...

  5. XML 解析 -- IE ,Chrome

    通用的method <script type="text/javascript"> //for chrome, attach method to XMLDocument ...

  6. maven打包异常:软件包com.sun.org.apache.xml.internal.security.utils.Base64 不存在

    maven打包异常:软件包com.sun.org.apache.xml.internal.security.utils.Base64 不存在 将jre/lib/rt.jar添加到maven的compi ...

  7. 未知的系统错误(The transaction is no longer active - status: 'Committed'. No further JDBC access is allowed within this transaction.)

    被调用接口处理并发能力太脆弱导致的问题. 重新请求下即可.

  8. Hibernate,get()和load()区别

    最主要区别在于,检索策略不同. 无论get和load,首先都会去session缓存中看有没有现成的数据.没有的话,get会采用立即检索策略.即:将对象从数据库检索出来并返回,不使用代理类.load的话 ...

  9. C# winform 中MessageBox用法大全(附效果图) (转载+说明)

    声明:这篇文章是转载的转载的,由于原作者的博客被关闭 我就不再列出了,提前先说明下,if语句中的判断有些太长,建议提前声明一个变量, DialogResult MsgBoxResult;        ...

  10. SpringMVC项目,启动项目怎么总是报找不到log4j.properties文件

    具体操作:右键项目---->properties--->Java Build Path--->source--->Add Folder --->选择log4.proper ...