一、一对一关联

1.1、提出需求

  根据班级id查询班级信息(带老师的信息)

1.2、创建表和数据

  创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关系。

  1. CREATE TABLE teacher(
  2. t_id INT PRIMARY KEY AUTO_INCREMENT,
  3. t_name VARCHAR(20)
  4. );
  5. CREATE TABLE class(
  6. c_id INT PRIMARY KEY AUTO_INCREMENT,
  7. c_name VARCHAR(20),
  8. teacher_id INT
  9. );
  10. ALTER TABLE class ADD CONSTRAINT fk_teacher_id FOREIGN KEY (teacher_id) REFERENCES teacher(t_id);
  11.  
  12. INSERT INTO teacher(t_name) VALUES('teacher1');
  13. INSERT INTO teacher(t_name) VALUES('teacher2');
  14.  
  15. INSERT INTO class(c_name, teacher_id) VALUES('class_a', 1);
  16. INSERT INTO class(c_name, teacher_id) VALUES('class_b', 2);

表之间的关系如下:

1.3、创建项目如下Web Project项目(导入jar包)如下:

1.4、定义实体类

  1、Teacher类,Teacher类是teacher表对应的实体类。

  1. package com.myl.entity;
  2. /**
  3. * teacher实体类
  4. * @author myl
  5. * @date 2018年5月3日 上午7:06:07
  6. */
  7. public class Teacher {
  8.  
  9. //定义实体类的属性,与teacher表中的字段对应
  10. private int id; //id===>t_id
  11. private String name; //name===>t_name
  12.  
  13. public int getId() {
  14. return id;
  15. }
  16. public void setId(int id) {
  17. this.id = id;
  18. }
  19. public String getName() {
  20. return name;
  21. }
  22. public void setName(String name) {
  23. this.name = name;
  24. }
  25. @Override
  26. public String toString() {
  27. return "Teacher [id=" + id + ", name=" + name + "]";
  28. }
  29.  
  30. }

2、Classes类,Classes类是class表对应的实体类

  1. package com.myl.entity;
  2.  
  3. /**
  4. * class的实体类
  5. * @author myl
  6. * @date 2018年5月3日 上午7:07:14
  7. */
  8. public class Classes {
  9.  
  10. //定义实体类的属性,与class表中的字段对应
  11. private int id; //id===>c_id
  12. private String name; //name===>c_name
  13.  
  14. /**
  15. * class表中有一个teacher_id字段,所以在Classes类中定义一个teacher属性,
  16. * 用于维护teacher和class之间的一对一关系,通过这个teacher属性就可以知道这个班级是由哪个老师负责的
  17. */
  18. private Teacher teacher;
  19.  
  20. public int getId() {
  21. return id;
  22. }
  23. public void setId(int id) {
  24. this.id = id;
  25. }
  26. public String getName() {
  27. return name;
  28. }
  29. public void setName(String name) {
  30. this.name = name;
  31. }
  32.  
  33. public Teacher getTeacher() {
  34. return teacher;
  35. }
  36. public void setTeacher(Teacher teacher) {
  37. this.teacher = teacher;
  38. }
  39.  
  40. @Override
  41. public String toString() {
  42. return "Classes [id=" + id + ", name=" + name + ", teacher=" + teacher + "]";
  43. }
  44.  
  45. }

1.5、定义sql映射文件classMapper.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3.  
  4. <!-- 为这个mapper指定一个唯一的namespace,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证namespace的值是唯一的
  5. 例如namespace="me.myl.mapping.classMapper"就是me.myl.mapping(包名)+classMapper(classMapper.xml文件去除后缀)
  6. -->
  7. <mapper namespace="com.myl.mapping.classMapper">
  8. <!--
  9. 根据班级id查询班级信息(带老师的信息)
  10. ##1. 联表查询
  11. SELECT * FROM class c,teacher t WHERE c.teacher_id=t.t_id AND c.c_id=1;
  12.  
  13. ##2. 执行两次查询
  14. SELECT * FROM class WHERE c_id=1; //teacher_id=1
  15. SELECT * FROM teacher WHERE t_id=1;//使用上面得到的teacher_id
  16. -->
  17.  
  18. <select id="getClass" parameterType="int" resultMap="ClassResultMapper">
  19. select * from class c,teacher t where c.teacher_id = t.t_id and c_id = #{id}
  20. </select>
  21.  
  22. <!-- 使用resultMap映射实体类和字段之间的一一对应关系 -->
  23. <resultMap type="com.myl.entity.Classes" id="ClassResultMapper">
  24. <id property="id" column="c_id"/>
  25. <result property="name" column="c_name"/>
  26. <association property="teacher" javaType="com.myl.entity.Teacher">
  27. <id property="id" column="t_id"/>
  28. <result property="name" column="t_name"/>
  29. </association>
  30. </resultMap>
  31.  
  32. <!--
  33. 方式二:嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型
  34. SELECT * FROM class WHERE c_id=1;
  35. SELECT * FROM teacher WHERE t_id=1 //1 是上一个查询得到的teacher_id的值
  36. -->
  37.  
  38. <select id="getClass2" parameterType="int" resultMap="ClassResultMap2">
  39. select * from class where c_id=#{id}
  40. </select>
  41. <!-- 使用resultMap映射实体类和字段之间的一一对应关系 -->
  42. <resultMap type="com.myl.entity.Classes" id="ClassResultMap2">
  43. <id property="id" column="c_id"/>
  44. <result property="name" column="c_name"/>
  45. <association property="teacher" column="teacher_id" select="getTeacher"/>
  46. </resultMap>
  47.  
  48. <select id="getTeacher" parameterType="int" resultType="com.myl.entity.Teacher">
  49. SELECT t_id id, t_name name FROM teacher WHERE t_id=#{id}
  50. </select>
  51.  
  52. </mapper>

数据库连接db.properties配置

  1. driver=com.mysql.jdbc.Driver
  2. url=jdbc:mysql://127.0.0.1:3306/mybatis
  3. username=root
  4. password=

在mybatisConf.xml文件中注册classMapper.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
  3.  
  4. <configuration>
  5. <!-- 引用db.properties配置文件 -->
  6. <properties resource="db.properties" />
  7.  
  8. <environments default="development">
  9. <environment id="development">
  10. <transactionManager type="JDBC" />
  11. <!-- 配置数据库连接信息 -->
  12. <dataSource type="POOLED">
  13. <!-- value属性值引用db.properties配置文件中配置的值 -->
  14. <property name="driver" value="${driver}"/>
  15. <property name="url" value="${url}"/>
  16. <property name="username" value="${username}"/>
  17. <property name="password" value="${password}"/>
  18. </dataSource>
  19. </environment>
  20. </environments>
  21.  
  22. <mappers>
  23. <!--
  24. 注册userMapper.xml文件,
  25. userMapper.xml位于me.myl.mapping这个包下,所以resource写成me/myl/mapping/userMapper.xml
  26. -->
  27. <mapper resource="com/myl/mapping/classMapper.xml"/>
  28. </mappers>
  29. </configuration>

1.6、编写单元测试代码

  1. package com.myl;
  2.  
  3. import org.apache.ibatis.session.SqlSession;
  4. import org.junit.Test;
  5.  
  6. import com.myl.entity.Classes;
  7. import com.myl.util.MybatisUtil;
  8.  
  9. /**
  10. * 单元测试查询
  11. * @author myl
  12. * @date 2018年5月3日 上午6:58:51
  13. */
  14.  
  15. public class Test1 {
  16.  
  17. @Test
  18. public void testGetClass() {
  19. SqlSession sqlSession = MybatisUtil.getSession();
  20. //执行查询操作,将查询结果自动封装成Classes对象返回
  21. Classes clazz = sqlSession.selectOne("getClass",1); //查询class表中id为1的记录
  22.  
  23. //使用SqlSession执行完SQL之后需要关闭SqlSession
  24. sqlSession.close();
  25. System.out.println(clazz);
  26. }
  27.  
  28. @Test
  29. public void testGetClass2() {
  30. SqlSession sqlSession = MybatisUtil.getSession();
  31. //执行查询操作,将查询结果自动封装成Classes对象返回
  32. Classes clazz = sqlSession.selectOne("getClass2",1); //查询class表中id为1的记录
  33.  
  34. //使用SqlSession执行完SQL之后需要关闭SqlSession
  35. sqlSession.close();
  36. System.out.println(clazz);
  37. }
  38.  
  39. }

测试结果

1.7、MyBatis一对一关联查询总结

  MyBatis中使用association标签来解决一对一的关联查询,association标签可用的属性如下:

  • property:对象属性的名称
  • javaType:对象属性的类型
  • column:所对应的外键字段名称
  • select:使用另一个查询封装的结果

-----------

二、一对多关联

2.1、需求

  根据classId查询对应的班级信息,包括学生,老师

2.2、创建表和数据

  上面的一对一关联查询演示中,我们已经创建了班级表和教师表,这里再创建一张学生表

  1. CREATE TABLE student(
  2. s_id INT PRIMARY KEY AUTO_INCREMENT,
  3. s_name VARCHAR(20),
  4. class_id INT
  5. );
  6. INSERT INTO student(s_name, class_id) VALUES('student_A', 1);
  7. INSERT INTO student(s_name, class_id) VALUES('student_B', 1);
  8. INSERT INTO student(s_name, class_id) VALUES('student_C', 1);
  9. INSERT INTO student(s_name, class_id) VALUES('student_D', 2);
  10. INSERT INTO student(s_name, class_id) VALUES('student_E', 2);
  11. INSERT INTO student(s_name, class_id) VALUES('student_F', 2);

2.3、定义实体类

  1、Student类

  1. package com.myl.entity;
  2.  
  3. /**
  4. * 学生实体类
  5. * @author myl
  6. * @date 2018年5月4日 上午7:01:01
  7. */
  8. public class Student {
  9.  
  10. //定义student属性 和student表中的字段对应
  11. private int id; //id ==>s_id
  12. private String name; //name ==>s_name
  13.  
  14. public int getId() {
  15. return id;
  16. }
  17. public void setId(int id) {
  18. this.id = id;
  19. }
  20. public String getName() {
  21. return name;
  22. }
  23. public void setName(String name) {
  24. this.name = name;
  25. }
  26. @Override
  27. public String toString() {
  28. return "Student [id=" + id + ", name=" + name + "]";
  29. }
  30.  
  31. }

2、修改Classes类,添加一个List<Student> students属性,使用一个List<Student>集合属性表示班级拥有的学生,如下:

  1. package com.myl.entity;
  2.  
  3. import java.util.List;
  4.  
  5. /**
  6. * class的实体类
  7. * @author myl
  8. * @date 2018年5月3日 上午7:07:14
  9. */
  10. public class Classes {
  11.  
  12. //定义实体类的属性,与class表中的字段对应
  13. private int id; //id===>c_id
  14. private String name; //name===>c_name
  15.  
  16. /**
  17. * class表中有一个teacher_id字段,所以在Classes类中定义一个teacher属性,
  18. * 用于维护teacher和class之间的一对一关系,通过这个teacher属性就可以知道这个班级是由哪个老师负责的
  19. */
  20. private Teacher teacher;
  21.  
  22. //使用一个List<Student>集合属性表示班级拥有的学生
  23. private List<Student> students;
  24.  
  25. public int getId() {
  26. return id;
  27. }
  28. public void setId(int id) {
  29. this.id = id;
  30. }
  31. public String getName() {
  32. return name;
  33. }
  34. public void setName(String name) {
  35. this.name = name;
  36. }
  37.  
  38. public Teacher getTeacher() {
  39. return teacher;
  40. }
  41. public void setTeacher(Teacher teacher) {
  42. this.teacher = teacher;
  43. }
  44.  
  45. public List<Student> getStudents() {
  46. return students;
  47. }
  48. public void setStudents(List<Student> students) {
  49. this.students = students;
  50. }
  51. @Override
  52. public String toString() {
  53. return "Classes [id=" + id + ", name=" + name + ", teacher=" + teacher + ", students=" + students + "]";
  54. }
  55.  
  56. }

2.4、修改sql映射文件classMapper.xml

  添加如下的SQL映射信息

  1. <!--
  2. 根据classId查询对应的班级信息,包括学生,老师
  3. ##1. 联表查询
  4. -->
  5.  
  6. <select id="getClass3" parameterType="int" resultMap="ClassResultMapper3">
  7. select * from class c,teacher t, student s where c.teacher_id = t.t_id and s.class_id = c.c_id and c_id = #{id}
  8. </select>
  9.  
  10. <!-- 使用resultMap映射实体类和字段之间的一一对应关系 -->
  11. <resultMap type="com.myl.entity.Classes" id="ClassResultMapper3">
  12. <id property="id" column="c_id"/>
  13. <result property="name" column="c_name"/>
  14. <association property="teacher" javaType="com.myl.entity.Teacher">
  15. <id property="id" column="t_id"/>
  16. <result property="name" column="t_name"/>
  17. </association>
  18. <!-- ofType指定students集合中的对象类型 -->
  19. <collection property="students" ofType="com.myl.entity.Student">
  20. <id property="id" column="s_id" />
  21. <result property="name" column="s_name"/>
  22. </collection>
  23. </resultMap>
  24.  
  25. <!--
  26. 方式二:嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型
  27. SELECT * FROM class WHERE c_id=1;
  28. SELECT * FROM teacher WHERE t_id=1 //1 是上一个查询得到的teacher_id的值
  29. SELECT * FROM student WHERE class_id=1 //1是第一个查询得到的c_id字段的值
  30. -->
  31. <select id="getClass4" parameterType="int" resultMap="ClassResultMapper4">
  32. select * from class where c_id = #{id}
  33. </select>
  34. <resultMap type="com.myl.entity.Classes" id="ClassResultMapper4">
  35. <id property="id" column="c_id" />
  36. <result property="name" column="c_name" />
  37. <association property="teacher" column="teacher_id" javaType="com.myl.entity.Teacher" select="getTeacher2">
  38. </association>
  39. <collection property="students" column="c_id" ofType="com.myl.entity.Student" select="getStudent">
  40. </collection>
  41. </resultMap>
  42. <select id="getTeacher2" parameterType="int" resultType="com.myl.entity.Teacher">
  43. select t_id id, t_name name from teacher where t_id = #{id}
  44. </select>
  45. <select id="getStudent" parameterType="int" resultType="com.myl.entity.Student">
  46. select s_id id, s_name name from student where class_id = #{id}
  47. </select>

2.5、编写单元测试代码

  1. package com.myl;
  2.  
  3. import org.apache.ibatis.session.SqlSession;
  4. import org.junit.Test;
  5.  
  6. import com.myl.entity.Classes;
  7. import com.myl.util.MybatisUtil;
  8.  
  9. /**
  10. * 单元测试查询
  11. * @author myl
  12. * @date 2018年5月3日 上午6:58:51
  13. */
  14.  
  15. public class Test1 {
  16.  
  17. @Test
  18. public void testGetClass3() {
  19. SqlSession sqlSession = MybatisUtil.getSession();
  20. //执行查询操作,将查询结果自动封装成Classes对象返回
  21. Classes clazz = sqlSession.selectOne("getClass3",1); //查询class表中id为1的记录
  22.  
  23. //使用SqlSession执行完SQL之后需要关闭SqlSession
  24. sqlSession.close();
  25. System.out.println(clazz);
  26. }
  27.  
  28. @Test
  29. public void testGetClass4() {
  30. SqlSession sqlSession = MybatisUtil.getSession();
  31. //执行查询操作,将查询结果自动封装成Classes对象返回
  32. Classes clazz = sqlSession.selectOne("getClass4",1); //查询class表中id为1的记录
  33.  
  34. //使用SqlSession执行完SQL之后需要关闭SqlSession
  35. sqlSession.close();
  36. System.out.println(clazz);
  37. }
  38.  
  39. }

返回结果:

2.6、MyBatis一对多关联查询总结

  MyBatis中使用collection标签来解决一对多的关联查询,ofType属性指定集合中元素的对象类型。

MyBatis学习总结(五)——关联表查询的实现的更多相关文章

  1. MyBatis学习总结——实现关联表查询(转)

    原文链接:孤傲苍狼 一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关 ...

  2. Mybatis学习——一对多关联表查询

    1.实体类 public class Student { private int id; private String name; } public class Classes { private i ...

  3. Mybatis源码分析--关联表查询及延迟加载原理(二)

    在上一篇博客Mybatis源码分析--关联表查询及延迟加载(一)中我们简单介绍了Mybatis的延迟加载的编程,接下来我们通过分析源码来分析一下Mybatis延迟加载的实现原理. 其实简单来说Myba ...

  4. MyBatis入门学习教程-实现关联表查询

    一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关 ...

  5. mybatis学习 十二 多表查询

    Mybatis 实现多表查询方式: (1)业务装配.对两个表编写单表查询语句,在业务(Service)把查询的两个结果进行关联. (2)使用Auto Mapping特性,在实现两表联合查询时通过别名完 ...

  6. mybatis深入理解(八)-----关联表查询

    一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关 ...

  7. Mybatis学习笔记之---多表查询(1)

    Mybatis多表查询(1) (一)举例(用户和账户) 一个用户可以有多个账户 一个账户只能属于一个用户(多个账户也可以属于同一个用户) (二)步骤 1.建立两张表:用户表,账户表,让用户表和账户表之 ...

  8. Mybatis学习笔记之---多表查询(2)

    Mybatis多表查询(2) (一)举例 用户和角色 一个用户可以有多个角色,一个角色可以赋予多个用户 (二)步骤 1.建立两张表:用户表,角色表,让用户表和角色表具有多对多的关系.需要使用中间表,中 ...

  9. Mybatis源码分析--关联表查询及延迟加载(一)

    Mybatis提供了关联查询映射的功能. 一.一对一关联

随机推荐

  1. nginx 的安装、优化、服务器集群

    一.安装 下载地址:http://nginx.org  找到 stable 稳定版 安装准备:nginx 依赖于pcre(正则)库,如果没有安装pcre先安装 yum install pcre pcr ...

  2. oracle(enquences & latches )lock (oracle 锁大全)

    资料来自官方文档: https://docs.oracle.com/database/121/CNCPT/consist.htm#CNCPT1333 https://docs.oracle.com/d ...

  3. python中单例模式的创建

    # 单例模式(使用装饰器) def singleton(cls): instance = {} def wrapper(*args,**kwargs): if cls not in instance: ...

  4. 几个垃圾XSS

    遇见帅比厂商就离谱.... 这个厂商就挖了几个反射XSS,幸亏没有浪费太多时间 嗯 有的有waf.有的没有就离谱 可以看见可以解析的,但是他的这个站,遇见关键函数就自己跳转了.然后去寻找下别的标签fu ...

  5. 从门外汉到腾讯Android高级研发——一个半路出家菜鸟的艰难逆袭之路

    我是在去年3月份加入腾讯公司,目前是腾讯公司某技术部门里面的一个小负责人,年薪月薪大税后概30K,谈不上多么厉害,但在回想自己半路出家学习编程,从一个销售到现在终于进入中国互联网顶尖公司,还是有些许感 ...

  6. netty系列之:文本聊天室

    目录 简介 聊天室的工作流程 文本处理器 初始化ChannelHandler 真正的消息处理逻辑 总结 简介 经过之前的系列文章,我们已经知道了netty的运行原理,还介绍了基本的netty服务搭建流 ...

  7. 1~n数字中1出现的个数

    1~n数字中1出现的个数 LeetCode 给定一个整数 n,计算所有小于等于 n 的非负整数中数字 1 出现的个数. 感觉挺有意思 对于一个数,我们先局部分析一下,比如123456,我们考虑百位这个 ...

  8. 线程休眠_sleep

    线程休眠_sleep sleep(时间)指定当前线程阻塞的毫秒数: sleep存在异常InterruptedException: sleep时间到达后线程进入就绪状态: sleep可以模拟网络延时,倒 ...

  9. 如何不耍流氓的做运维之-SHELL脚本

    前言 大家都是文明人,尤其是做运维的,那叫一个斯文啊.怎么能耍流氓呢?赶紧看看,编写SHELL脚本如何能够不耍流氓. 下面的案例,我们以MySQL数据库备份SHELL脚本的案例来进行阐述: 不记录日志 ...

  10. STM32—SPI读写FLASH

    目录 FLASH简介 W25Q64 W25Q64简介 FLASH控制指令 FLASH内部存储结构 代码讲解 读取芯片ID 发送写使能信号 等待FLASH不忙 擦除扇区 写入数据 读取数据 注 FLAS ...