详解Mybatis一对多、多对一、多对多
1、什么是关系型数据库?
这个东西我仿佛在大学的《数据库原理》中学过,好吧,我不记得了,来整理一下。
是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。简单说来就是关系型数据库用了选择、投影、连接、并、交、差、除、增删查改等数学方法来实现对数据的存储和查询。可以用SQL语句方便的在一个表及其多个表之间做非常复杂的数据查询。安全性高。
所谓的关系模型指用二维表的形式表示实体和实体间联系的数据模型
关系型数据库的优势:
- 复杂查询可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。
- 事务支持使得对于安全性能很高的数据访问要求得以实现。
2、实例详解 一对多关系
实际情况:比如一个部门有很多员工,一个班级有很多学生
这里我们接着前几篇的内容,所以用班级与学生来举例
新建教室表:classroom
use demo;
create table classroom(
cid int NOT NULL AUTO_INCREMENT,
cname varchar(30) DEFAULT NULL,
PRIMARY KEY (cid)
)AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
删除原有的学生表,新建一个:student
use demo;
create table student(
id int NOT NULL AUTO_INCREMENT,
sname varchar(30) DEFAULT NULL,
age int,
cid int NOT NUll,
PRIMARY KEY (id)
)AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
插入数据:
use demo;
INSERT INTO classroom VALUES (1,"班级一");
INSERT INTO classroom VALUES (2,"班级二");
INSERT INTO student VALUES (1,'学生 a', 10, 1);
INSERT INTO student VALUES (2,'学生 b', 10, 1);
INSERT INTO student VALUES (3,'学生 c', 9, 1);
INSERT INTO student VALUES (4,'学生 x', 11, 2);
INSERT INTO student VALUES (5,'学生 y', 12, 2);
INSERT INTO student VALUES (6,'学生 z', 11, 2);
新建教室类:
public class Classroom {private Integer cid;private String cname;private Set<Student> students;geeter... seeter...@Overridepublic String toString() {return "Classroom{" +"cid=" + cid +", cname='" + cname + '\'' +'}';}
}
学生类不变,上一篇有,这里不赘述,直通车:Mybatis系列记录(一)—— 别划走,来看看这篇Mybatis CRUD吧!_LoneWalker、的博客-CSDN博客
新建mapper:
public interface ClassroomMapper {List<Classroom> listClassroom();
}
新建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.test.demo.mapper.ClassroomMapper">
<resultMap id="ClassroomResult" type="com.test.demo.domain.Classroom"><id column="cid" property="cid" /><result column="cname" property="cname" /><!-- 一对多的关系 --><!-- property: 指的是集合属性的值,对应类中的属性名 ofType:指的是集合中元素的类型 --><collection property="students" ofType="com.test.demo.domain.Student"><id column="id" property="id" /><result column="sname" property="sname" /><result column="age" property="age" /></collection>
</resultMap><select id="listClassroom" resultMap="ClassroomResult">select c.*,s.* from classroom c left join student s on c.cid = s.cid</select>
</mapper>
新建Controller: 新建一个页面,有无内容都可,数据输出在控制台
@RequestMapping("/classManage")
@Controller
public class ClassroomController {@AutowiredClassroomMapper classroomMapper;@RequestMapping("/listClassroom")public String listClassroom(){List<Classroom> classrooms = classroomMapper.listClassroom();for (Classroom c : classrooms) {System.out.println(c);Set<Student> students = c.getStudents();for (Student s : students) {System.out.println("\t"+s);}}return "views/listClassroom";}
}
访问:http://localhost:8080/classManage/listClassroom 查看控制台数据:
注意点:该注意的也就是XML中加了注释的部分,文末会总结一下
3、实例详解 多对一关系
到这里应该也很清楚了,教室对学生是一对多,那反过来,学生对教室就是多对一关系。
首先学生类新增属性Classroom
private Classroom classroom;public Classroom getClassroom() {return classroom;}public void setClassroom(Classroom classroom) {this.classroom = classroom;}
修改StudentController中查询学生的接口
@RequestMapping("/listStudent")public String toStudentView(Model model){List<Student> students = studentMapper.findAll();for (Student s : students) {System.out.println(s+" 对应的班级是 \t "+ s.getClassroom());}// model.addAttribute("students",students);return "views/listStudent";}
修改StudentMapper.xml
<resultMap id="studentResult" type="com.test.demo.domain.Student"><id column="id" property="id"/><result column="sname" property="sname"/><result column="age" property="age"/><!-- 多对一的关系 --><!-- property: 指的是属性名称, javaType:指的是属性的类型 --><association property="classroom" javaType="com.test.demo.domain.Classroom"><id column="cid" property="cid"/><result column="cname" property="cname"/></association></resultMap><select id="findAll" resultMap="studentResult">select c.*,s.* from classroom c left join student s on c.cid = s.cid</select>
访问http://localhost:8080/studentManage/listStudent 后查看控制台数据
4、实例解析 多对多关系
一个教师可以教很多班级,一个班级可以有很多老师,也就形成了多对多的关系
新建教师表:
create table teacher (tid int(11) NOT NULL AUTO_INCREMENT,tname varchar(32) DEFAULT NULL,PRIMARY KEY (tid)
) AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
新建教师与班级关联表:
create table order_item_(id int(11) NOT NULL AUTO_INCREMENT, oid int ,pid int ,PRIMARY KEY(id)
)AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
插入数据:
INSERT INTO teacher VALUES (1,'英语老师');
INSERT INTO teacher VALUES (2,'数学老师');INSERT INTO teacher_class VALUES (null, 1, 1);
INSERT INTO teacher_class VALUES (null, 1, 2);
INSERT INTO teacher_class VALUES (null, 2, 2);
INSERT INTO teacher_class VALUES (null, 2, 1);
新增教师类:
public class Teacher {private Integer tid;private String tname;private List<TeacherClass> teacherClasses;getter... setter...
}
新增教师与班级关联类:
public class TeacherClass {private Integer id;private Teacher teacher;private Classroom classroom;getter... setter...
}
新增mapper:
public interface TeacherMapper {List<Teacher> listTeacher();
}
新增XML: teacherMapper.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.test.demo.mapper.TeacherMapper"><resultMap id="teacherResult" type="com.test.demo.domain.Teacher"><id column="tid" property="tid"/><result column="tname" property="tname"/><collection property="teacherClasses" ofType="com.test.demo.domain.TeacherClass"><id column="id" property="id"/><association property="classroom" javaType="com.test.demo.domain.Classroom"><id column="cid" property="cid"/><result column="cname" property="cname"/></association></collection></resultMap><select id="listTeacher" resultMap="teacherResult">select t.*,c.* from teacher t left join teacher_class tc on t.tid = tc.tidleft join classroom c on tc.cid = c.cid</select>
</mapper>
新增Controller:
@Controller
@RequestMapping("/teacherManage")
public class TeacherController {@AutowiredTeacherMapper teacherMapper;@RequestMapping("/listTeacher")@ResponseBodypublic List<Teacher> listTeacher() {List<Teacher> teachers = teacherMapper.listTeacher();for (Teacher t : teachers) {System.out.println(t.getTname());List<TeacherClass> tcs = t.getTeacherClasses();for (TeacherClass tc : tcs) {System.out.format("\t%d\t%s\t%n", tc.getClassroom().getCid(), tc.getClassroom().getCname());}}return teachers;}
}
访问:http://localhost:8080/teacherManage/listTeacher 控制台数据:
解析:
查询出所有的老师,再遍历查询该老师所教的班级;查询结果把tid、tname放在Teacher 对象里
然后通过一对多的<collection>标签把id放在TeacherClass对象里
最后把cid、cname放到Classroom对象里
注意:
多对多时不存在修改关系的做法,基本上都是把旧的关系删除,再插入新的关系
JavaType和ofType都是用来指定对象类型的,但是JavaType是用来指定pojo中属性的类型,而ofType指定的是映射到list集合属性中pojo的类型
详解Mybatis一对多、多对一、多对多相关推荐
- Mybatis系列全解(五):全网最全!详解Mybatis的Mapper映射文件
封面:洛小汐 作者:潘潘 若不是生活所迫,谁愿意背负一身才华. 前言 上节我们介绍了 < Mybatis系列全解(四):全网最全!Mybatis配置文件 XML 全貌详解 >,内容很详细( ...
- java批量执行查询sql语句_详解MyBatis直接执行SQL查询及数据批量插入
一.直接执行SQL查询: 1.mappers文件节选 ${paramSQL} 2.DAO类节选 public interface SomeDAO{ List getInstanceModel(@Par ...
- java mysbatis select_java相关:详解Mybatis中的select方法
java相关:详解Mybatis中的select方法 发布于 2020-7-3| 复制链接 摘记: selectById方法根据id,查询记录 ```java public void updateRe ...
- 详解mybatis映射配置文件
一 mybatis 映射文件结构 mybatis映射配置文件存在如下顶级元素,且这些元素按照如下顺序被定义. cache – 给定命名空间的缓存配置. cache-ref – 其他命名空间缓存配置的 ...
- 一文详解Mybatis动态SQL,建议收藏
一文详解Mybatis动态SQL,建议收藏 1.动态 SQL 2.IF 3.choose.when.otherwise 4.where 5.set 6.trim 7.SQL片段 8.foreach 1 ...
- 详解MyBatis的Dao层实现和配置文件深入
这篇文章主要为大家详细介绍了MyBatis的Dao层实现和配置文件深入,文中的示例代码讲解详细,感兴趣的小伙伴快来跟随小编一起学习一下 目录 [Mybatis的Dao层实现] [传统开发方式] [代理 ...
- mapper命名规范_Mybatis系列全解(五):全网最全!详解Mybatis的Mapper映射文件
封面:洛小汐 作者:潘潘 若不是生活所迫,谁愿意背负一身才华. 前言 上节我们介绍了 < Mybatis系列全解(四):全网最全!Mybatis配置文件 XML 全貌详解 >,内容很详细( ...
- mysql映射mapper_这下够清楚了吧!详解Mybatis的Mapper映射文件
前言 上节我们介绍了 < Mybatis系列全解(四):全网最全!Mybatis配置文件 XML 全貌详解 >,内容很详细( 也很枯燥),由于篇幅实在过于冗长,我预计大家想看完得花上两段上 ...
- 深入浅出 万字详解 MyBatis看这一篇就够了!
三层架构 界面层 Controller -> SpringMVC User interface layer,表示层,视图层,接受用户数据显示请求结果.使用web页面和用户交互,如jsp.html ...
最新文章
- Java中JDK,JRE和JVM之间的关系
- 调用torchtext报错OSError: libtorch_cpu.so: cannot open shared object file: No such file or directory
- 【译】如何停止使用console.log()转而使用浏览器debugger
- 第 30 章 lvs-rrd
- 基于android的lbs技术,基于Android的LBS应用研究
- java刘保_[SSH] Eclipse+Struts2的简单应用
- 小程序如何将wx.request里的数据传出去
- 工作162:选择日期自传父
- Android Studio1.4.x JNI开发基础 - 简单实例
- numpy linspace
- java实验报告2013_java实验报告4
- linux pci带宽,Linux查看PCIe版本及速率
- 《SQL必知必会阅读思维导图》PART1
- 行政区划简称(包括别称)
- StackOverflow 推出程序员身价计算器,看看自己值多少钱?
- Linux内核移植之DM9000网卡驱动
- 互联网金融涌动下的冲动与借债
- mysql5.7导出数据提示–secure-file-priv选项问题的解决方法
- 第十六届全国大学生智能车竞赛线上比赛监督裁判培训演练
- Storm集成HBase、JDBC、Kafka、Hive
热门文章
- 喉咙肿痛险些死掉!33岁程序员经历生死5小时,别不把嗓子疼当回事
- 介绍好用的远程控制软件
- Failed to reconcile etcd plane: Failed to add etcd member [etcd-server05] to etcd cluster
- 骨传导耳机和气传导哪个对听力好?不伤耳骨传导耳机了解一下
- 4.2 手机模拟操作初步尝试(获取登录页面的源代码)
- A5年终盘点:整理2013站长圈里的N多个盘点 N多个热点
- 喜欢一个人,是一种感觉。
- 中小企业留住人才的十一个绝招
- 计算机辅助技术英语,计算机辅助跟踪技术,computer-aided tracking technology,音标,读音,翻译,英文例句,英语词典...
- 使用git提交代码的流程