11 关联、集合

在MySQL中,我们经常需要处理一对多的情况,使用MyBatis中的高级映射就能够很好地处理这种情况。

11.1 数据库中创建测试表

创建学生表student和教师表teacher,并插入测试数据,在这里学生和老师是多对一的关系:

CREATE TABLE `teacher` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8INSERT 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=utf8INSERT 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');

11.2 创建新的模块

  1. 在resources下创建配置文件mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><properties resource="db.properties" /><settings><setting name="logImpl" value="STDOUT_LOGGING"/></settings><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 resource="com/cap/dao/TeacherMapping.xml" ></mapper><mapper resource="com/cap/dao/StudentMapping.xml" ></mapper></mappers></configuration>

这里需要引用到db.properties,里面存放连接数据库的相关信息

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis
username=root
password=mysql
  1. 编写工具类,通过SqlSessionFactoryBuilder读取mybatis-config.xml配置文件后,构建SqlSessionFactory,再编写一个获取·SqlSession·的方法
public class MyBatisUtils {private static SqlSessionFactory sqlSessionFactory;static {try {String resource = "mybatis-config.xml";InputStream is = Resources.getResourceAsStream(resource);sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);} catch (IOException e) {e.printStackTrace();}}public static SqlSession getSqlSession(){return sqlSessionFactory.openSession();}
}
  1. 创建实体类StudentTeacher
public class Student {private int id;private String name;//关联老师的idprivate Teacher teacher;
}
public class Teacher {private int id;private String name;
}
  1. 编写dao层的相关接口
public interface TeacherMapping {}
public interface StudentMapping {}
  1. 在resources下创建同样的层级包结构,编写相应的Mapping.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.cap.dao.StudentMapping"></mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cap.dao.TeacherMapping"></mapper>

整个的层级结构如下
6. 简单测试一下,利用注解在TeacherMapping接口编写一个通过id查询Teacher的方法

public interface TeacherMapping {@Select("SELECT * FROM teacher WHERE id = #{id}")Teacher getTeacherById(int id);
}

编写测试方法

public class Test {@org.junit.Testpublic void test(){SqlSession sqlSession = MyBatisUtils.getSqlSession();TeacherMapping mapper = sqlSession.getMapper(TeacherMapping.class);Teacher teacher = mapper.getTeacherById(1);System.out.println(teacher);sqlSession.close();}
}/**Teacher{id=1, name='秦老师'}*/

11.3 关联的嵌套 Select 查询

现在我们需要查询所有学生的信息,并且还要查询对应的老师的信息

public interface StudentMapping {/*** <p>获取学生的信息,以及对应的老师的信息</p>* @return*/List<Student> getStudent();
}

查询出来的结大概是这样子:
首先我们来讲解一下第一个思路——嵌套SELECT查询:
先查询所有学生的信息,再根据学生的tid,去寻找对应的老师

    <!--思路:1. 查询所有的学生信息2. 根据查询出来的学生的id,寻找对应的老师--><select id="getStudent" resultMap="StudentTeacher">SELECT * FROM student;</select><resultMap id="StudentTeacher" type="student"><result column="id" property="id" /><result column="name" property="name" /><!-- 复杂属性需要单独处理对象:association集合:collection--><association property="teacher" column="tid" javaType="teacher" select="getTeacher" /></resultMap><select id="getTeacher" resultType="teacher">SELECT * FROM teacher WHERE id = #{tid};</select>

resultMap结果集映射其他都能明白,关键在于如何处理Student中含有的Teacher对象,这里我们需要使用<association>标签来处理,它将查询得到的字段tid对应到Teacher对象上,再通过引用另一个SELECT查询,得到该tid所对应的Teacher对象。

注意typejavaType,他们用了别名studentteacher,分别代表实体类StudentTeacher,这个可以在mybatis-config.xml中配置

    <!-- 给pojo包取别名,默认为类名(首字母变小写,其他不变) --><typeAliases><package name="com.cap.pojo"/></typeAliases>

编写一个测试方法

    @org.junit.Testpublic void test1(){SqlSession sqlSession = MyBatisUtils.getSqlSession();StudentMapping mapper = sqlSession.getMapper(StudentMapping.class);List<Student> list = mapper.getStudent();for(Student student : list){System.out.println(student);}sqlSession.close();}

查询结果如下:

Student{id=1, name='小明', teacher=Teacher{id=1, name='秦老师'}}
Student{id=2, name='小红', teacher=Teacher{id=1, name='秦老师'}}
Student{id=3, name='小张', teacher=Teacher{id=1, name='秦老师'}}
Student{id=4, name='小李', teacher=Teacher{id=1, name='秦老师'}}
Student{id=5, name='小王', teacher=Teacher{id=1, name='秦老师'}}

11.4 关联的嵌套结果映射

    <resultMap id="StudentTeacher" type="student" ><result property="id" column="sid" /><result property="name" column="sname" /><association property="teacher" javaType="teacher"><result property="name" column="tname" /></association></resultMap>

测试方法得到:

Student{id=1, name='小明', teacher=Teacher{id=0, name='秦老师'}}
Student{id=2, name='小红', teacher=Teacher{id=0, name='秦老师'}}
Student{id=3, name='小张', teacher=Teacher{id=0, name='秦老师'}}
Student{id=4, name='小李', teacher=Teacher{id=0, name='秦老师'}}
Student{id=5, name='小王', teacher=Teacher{id=0, name='秦老师'}}

11.5 集合的嵌套结果映射

集合和关联非常相似,也是有嵌套 Select 查询和嵌套结果映射,这里只举嵌套结果映射的例子。
首先我们先修改实体类

public class Student {private int id;private String name;private int tid;}
public class Teacher {private int id;private String name;private List<Student> students;

在接口TeacherMapping中添加一个方法,用于查询指定idTeacher

public interface TeacherMapping {Teacher getTeacherById(@Param("tid") int tid);
}
<mapper namespace="com.cap.dao.TeacherMapping"><!-- 按结果嵌套 --><select id="getTeacherById" resultMap="TeacherStudent">SELECTs.id   sid,s.name sname,t.name tname,t.id   tidFROM student s, teacher tWHERE s.tid = t.id AND t.id = #{tid};</select><resultMap id="TeacherStudent" type="teacher"><result property="id" column="tid" /><result property="name" column="tname" /><!--复杂的属性,我们需要单独处理对象:association集合:collectionjavaType : 指定属性的类型集合中的泛型信息,使用ofType获取--><collection property="students" ofType="com.cap.pojo.Student"><result property="id" column="sid" /><result property="name" column="sname" /><result property="tid" column="tid" /></collection></resultMap></mapper>
  • ofType:用于指定集合中的类型

【MyBatis从入门到入土】6 - 关联、集合相关推荐

  1. J2EE从入门到入土04.Map集合

    回顾:J2EE从入门到入土03.Set集合 目录 Map接口 Map实现类介绍 HashMap 遍历实例 输出结果 基本原理 HashTable ConcurrentHashMap TreeMap L ...

  2. 15、mybatis一对多关联查询 collection定义关联集合封装规则及懒加载

    文章目录 1.collection定义关联集合封装规则单步查询 1).Dept增加集合属性 2).DeptMapper增加查询接口 3).DeptMapper.xml增加collection配置 4) ...

  3. Java学习路线从入门到入土

    Java学习路线从入门到入土 Java学习路线从入门到入土 Java学习路线从入门到入土 简介 Java基础课程 第一阶段 第一部分:Java开发介绍 第二部分:Java数组 第三部分:Java面向对 ...

  4. 狭义相对论从入门到入土(建议初一及以上)

    欢迎来到HowardZhangdqs的劝退小课堂.这是狭义相对论从入门到入土(建议初一以上)系列的第二个集合版,修订了大量之前未发现的错误,如果大家在阅读时发现了错误欢迎联系我 zjh@shangha ...

  5. Java学习指南从入门到入土

    Java学习指南从入门到入土 本身其实只是刚刚入门,只是经历了两年时间的风吹雨打,经历了各种bug的折磨和学习各种框架的辛酸,才有得现有的 刚刚入门.有句老话说的好叫做 从入门到放弃,人生不易要及时放 ...

  6. MyBatis从入门到精通(1):MyBatis入门

    作为一个自学Java的自动化专业211大学本科生,在学习和实践过程中"趟了不少雷",所以有志于建立一个适合同样有热情学习Java技术的参考"排雷手册". 最近在 ...

  7. Redis从入门到入土

    Redis从入门到入土 概述 应用场景 redis相关知识 常用五大数据类型 Redis-key String List list数据结构 Set Set数据结构 Zset 命令 Zset数据结构 R ...

  8. Mybatis简单入门

    1 mybatis简单介绍 MyBatis是一个ORM的数据库持久化框架. Mybatis是一个支撑框架,它以映射sql语句orm方式来数据库持久化操作. ORM:对象关系映射(Object Rela ...

  9. 视频教程-mybatis快速入门到精通-Java

    mybatis快速入门到精通 十年项目开发经验,主要从事java相关的开发,熟悉各种mvc开发框架. 王振伟 ¥18.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 A ...

最新文章

  1. 如何利用 nbconvert将 IPYNB文档转换 Markdown文档?
  2. 流量暴涨擒凶记(转)
  3. Segment Tree
  4. java按行读取byte_【util】MappedByteBuffer按行读取的方案
  5. HTML5 audio 如何实现播放多个MP3音频
  6. 2015 CALLED THE INTERFACE OF 2014
  7. mysql binlog查看_MySQL--17 配置binlog-server 及中间件
  8. 张朝阳:选校草、跑马拉松、开5G峰会 搜狐最近要干这些事
  9. c++类的嵌套(1)
  10. 我在华为写了13年代码的一些感悟
  11. 如何在html中制作播放按钮,HTML5+CSS3网页实例:制作网页播放器按钮
  12. 如何把Word文档中的数字和字母变成新罗马字体?
  13. win10/ubuntu18.04 双系统开机黑屏,无法通过grub 选择系统,直接进入Ubuntu系统
  14. OpenCV简单实现PhotoShop图层混合
  15. DDOS防御抗D平台方案
  16. 关于gps测量精度的分析
  17. python笔记 基础语法·第10课 【田忌赛马游戏,代码拆分,过程代码】
  18. 计算机毕业设计 Java web物流配送管理系统
  19. 串口的使用-ttyUSB0设备
  20. php 自动下载apk,Android 下载apk 自动 安装

热门文章

  1. EditPlus 横竖转换
  2. vue 使用 cesium 接入 gltf 模型
  3. docker启动mysql闪退问题
  4. 大厂面试题Object object = new Object()
  5. 【ceph】cmake管理Ceph编译+Ceph工程目录+cmake 实战学习
  6. 适配器模式_21世纪的设计模式:适配器模式
  7. 2013年最具技术影响力原创图书TOP10[转]
  8. 【我的Android进阶之旅】 Android Studio 使用小技巧:快速Close Others其他的文件
  9. mysql自定义函数的优缺点_浅谈MySQL创建自定义函数漏洞的利用和防止
  10. MMLAB学习-Gard-CAM可视化方法