Mybatis【多表连接】

我们在学习Hibernate的时候,如果表涉及到两张的话,那么我们是在映射文件中使用<set>..<many-to-one>等标签将其的映射属性关联起来的...那么在我们Mybatis中又怎么做呢???

先来回顾一下我们SQL99的语法:


一)内连接(等值连接):查询客户姓名,订单编号,订单价格---------------------------------------------------select c.name,o.isbn,o.pricefrom customers c inner join orders owhere c.id = o.customers_id;---------------------------------------------------select c.name,o.isbn,o.pricefrom customers c join orders owhere c.id = o.customers_id; ---------------------------------------------------select c.name,o.isbn,o.pricefrom customers c,orders owhere c.id = o.customers_id;---------------------------------------------------select c.name,o.isbn,o.pricefrom customers c join orders oon c.id = o.customers_id;---------------------------------------------------注意:内连接(等值连接)只能查询出多张表中,连接字段相同的记录二)外连接:按客户分组,查询每个客户的姓名和订单数---------------------------------------------------左外连接:select c.name,count(o.isbn)from  customers c left outer join orders oon c.id = o.customers_idgroup by c.name; ---------------------------------------------------右外连接:select c.name,count(o.isbn)from  orders o right outer join customers c   on c.id = o.customers_idgroup by c.name; ---------------------------------------------------注意:外连接既能查询出多张表中,连接字段相同的记录;又能根据一方,将另一方不符合相同记录强行查询出来三)自连接:求出AA的老板是EE---------------------------------------------------内自连接:select users.ename,boss.enamefrom emps users inner join emps boss on users.mgr = boss.empno;---------------------------------------------------外自连接:select users.ename,boss.enamefrom emps users left outer join emps boss on users.mgr = boss.empno;---------------------------------------------------注意:自连接是将一张表,通过别名的方式,看作多张表后,再进行连接。这时的连接即可以采用内连接,又可以采用外连接

由于我们Mybatis中并没有像Hibernate这样全自动化的,因此我们是没有<set>..<many-to-one>等标签的,我们还是使用手写SQL语句来使我们的关联属性连接起来...

一对一

需求:

  • 学生和身份证

设计表:

--mysqlcreate table cards(cid int(5) primary key,cnum varchar(10)
);create table students(sid int(5) primary key,sname varchar(10),scid int(5),constraint scid_fk foreign key(scid) references cards(cid)
);insert into cards(cid,cnum) values(1,'111');
insert into students(sid,sname,scid) values(1,'哈哈',1);select * from cards;
select * from students;

实体

/*** 身份证(单方)* @author AdminTC*/
public class Card {private Integer id;private String num;public Card(){}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getNum() {return num;}public void setNum(String num) {this.num = num;}
}

/*** 学生(单方)* @author AdminTC*/
public class Student {private Integer id;private String name;private Card card;//关联属性public Student(){}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Card getCard() {return card;}public void setCard(Card card) {this.card = card;}
}

映射文件

由于我们有两个实体,因此我们会有两个映射文件

Student映射文件


<?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 namespace="studentNamespace"><resultMap type="zhongfucheng2.Student" id="studentMap"><id property="id" column="sid"/><result property="name" column="sname"/></resultMap>
</mapper>

Card映射文件

<?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 namespace="cardNamespace"><resultMap type="zhongfucheng2.Card" id="cardMap"><id property="id" column="cid"/><result property="num" column="cnum"/></resultMap>    </mapper>

DAO层

现在我想根据学生的编号查询学生的信息和身份证信息

由于该查询着重是查询学生的信息,于是我们在学生的映射文件中写SQL语句

按照需求,我们写出来的SQL语句是这样子的。

select * from zhongfucheng.students s,zhongfucheng.cards c where c.cid = s.scid and sid=1;

我来看一下查询结果:

我们的实体与映射表中,Student实体是没有关联其他的字段的,仅仅是写出了该实体的自带的属性

<resultMap type="zhongfucheng2.Student" id="studentMap"><id property="id" column="sid"/><result property="name" column="sname"/></resultMap>

明显地,我们Student是不能封装返回的结果,因此我们需要将关联属性进行关联起来!

<resultMap type="zhongfucheng2.Student" id="studentMap"><id property="id" column="sid"/><result property="name" column="sname"/><!--property写的是在Student实体中写关联字段的属性变量名称resultMap写的是映射文件中的命名空间.id--><association property="card" resultMap="cardNamespace.cardMap"/></resultMap>

我们关联了以后,Student实体就能够封装返回的结果了

<resultMap type="zhongfucheng2.Student" id="studentMap"><id property="id" column="sid"/><result property="name" column="sname"/><!--property写的是在Student实体中写关联字段的属性变量名称resultMap写的是映射文件中的命名空间.id--><association property="card" resultMap="cardNamespace.cardMap"/></resultMap><select id="findById" parameterType="int" resultMap="studentMap">select * from zhongfucheng.students s,zhongfucheng.cards c where c.cid = s.scid and sid=#{id};</select>

查询编号为1的学生信息【包括身份证编号】

public Student findById(int id) throws Exception {//得到连接对象SqlSession sqlSession = MybatisUtil.getSqlSession();try{return sqlSession.selectOne("studentNamespace.findById", id);/*  sqlSession.commit();*/}catch(Exception e){e.printStackTrace();sqlSession.rollback();throw e;}finally{MybatisUtil.closeSqlSession();}}public static void main(String[] args) throws Exception {StudentDao studentDao = new StudentDao();Student student = studentDao.findById(1);System.out.println(student.getId() + "----" + student.getName() + "----" + student.getCard().getNum());}


一对多

需求:

  • 一个班级有多个学生,查询java学科有哪些学生信息

设计数据库表

create table grades(gid int(5) primary key,gname varchar(10)
);create table students(sid int(5) primary key,sname varchar(10),sgid int(5),constraint sgid_fk foreign key(sgid) references grades(gid)
);insert into grades(gid,gname) values(1,'java');insert into students(sid,sname,sgid) values(1,'哈哈',1);
insert into students(sid,sname,sgid) values(2,'呵呵',1);select * from grades;
select * from students;

实体


package zhongfucheng2;import java.util.ArrayList;
import java.util.List;/*** 学科(单方)* @author AdminTC*/
public class Grade {private Integer id;private String name;private List<Student> studentList = new ArrayList<Student>();//关联属性public Grade(){}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<Student> getStudentList() {return studentList;}public void setStudentList(List<Student> studentList) {this.studentList = studentList;}
}

package zhongfucheng2;/*** 学生(多方)* @author AdminTC*/
public class Student {private Integer id;private String name;private Grade grade;//关联属性public Student(){}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Grade getGrade() {return grade;}public void setGrade(Grade grade) {this.grade = grade;}
}

映射文件SQL语句

<mapper namespace="studentNamespace"><resultMap type="zhongfucheng2.Student" id="studentMap"><id property="id" column="sid"/><result property="name" column="sname"/></resultMap><!--查询选修的java学科有多少位学生--><!--由于我们只要查询学生的名字,而我们的实体studentMap可以封装学生的名字,那么我们返回studentMap即可,并不需要再关联到学科表--><select id="findByGrade" parameterType="string" resultMap="studentMap">select s.sname,s.sid from zhongfucheng.students s,zhongfucheng.grades g WHERE s.sgid=g.gid and g.gname=#{name};</select></mapper><?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 namespace="gradeNamespace"><resultMap type="zhongfucheng2.Grade" id="gradeMap"><id property="id" column="gid"/><result property="name" column="gname"/></resultMap>
</mapper>

DAO


public List<Student> findByGrade(String  grade) throws Exception {//得到连接对象SqlSession sqlSession = MybatisUtil.getSqlSession();try{return sqlSession.selectList("studentNamespace.findByGrade", grade);/*  sqlSession.commit();*/}catch(Exception e){e.printStackTrace();sqlSession.rollback();throw e;}finally{MybatisUtil.closeSqlSession();}}public static void main(String[] args) throws Exception {StudentDao studentDao = new StudentDao();List<Student> student = studentDao.findByGrade("java");for (Student student1 : student) {System.out.println(student1.getName());}}

多对多

需求:

  • 学生和课程

数据库表


create table students(sid int(5) primary key,sname varchar(10)
);create table courses(cid int(5) primary key,cname varchar(10)
);create table middles(msid int(5),mcid int(5),primary key(msid,mcid)
);insert into students(sid,sname) values(1,'哈哈');
insert into students(sid,sname) values(2,'呵呵');insert into courses(cid,cname) values(1,'java');
insert into courses(cid,cname) values(2,'android');insert into middles(msid,mcid) values(1,1);
insert into middles(msid,mcid) values(1,2);
insert into middles(msid,mcid) values(2,1);
insert into middles(msid,mcid) values(2,2);select * from students;
select * from courses;
select * from middles;

实体

package cn.itcast.javaee.mybatis.many2many;import java.util.ArrayList;
import java.util.List;/*** 课程(多方)* @author AdminTC*/
public class Course {private Integer id;private String name;private List<Student> studentList = new ArrayList<Student>();//关联属性public Course(){}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<Student> getStudentList() {return studentList;}public void setStudentList(List<Student> studentList) {this.studentList = studentList;}
}

package cn.itcast.javaee.mybatis.many2many;import java.util.ArrayList;
import java.util.List;/*** 学生(多方)* @author AdminTC*/
public class Student {private Integer id;private String name;private List<Course> courseList = new ArrayList<Course>();//关联属性public Student(){}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<Course> getCourseList() {return courseList;}public void setCourseList(List<Course> courseList) {this.courseList = courseList;}
}

映射文件


<?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 namespace="courseNamespace"><resultMap type="cn.itcast.javaee.mybatis.many2many.Course" id="courseMap"><id property="id" column="cid"/><result property="name" column="cname"/></resultMap>    <!-- 查询哈哈选学了哪些课程 --><select id="findAllByName" parameterType="string" resultMap="courseMap">select c.cid,c.cnamefrom students s inner join middles mon s.sid = m.msidinner join courses con m.mcid = c.cidand s.sname = #{name}</select></mapper>

<?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 namespace="studentNamespace"><resultMap type="cn.itcast.javaee.mybatis.many2many.Student" id="studentMap"><id property="id" column="sid"/><result property="name" column="sname"/></resultMap>    <select id="findAllByCourseName" parameterType="string" resultMap="studentMap">select s.snamefrom students s inner join middles mon s.sid = m.msid inner join courses con m.mcid = c.cidand c.cname = #{name}</select></mapper>

DAO

package cn.itcast.javaee.mybatis.many2many;import java.util.List;
import org.apache.ibatis.session.SqlSession;
import cn.itcast.javaee.mybatis.util.MybatisUtil;/*** 持久层* @author AdminTC*/
public class StudentCourseDao {/*** 查询哈哈选学了哪些课程* @param name 表示学生的姓名*/public List<Course> findAllByName(String name) throws Exception{SqlSession sqlSession = null;try{sqlSession = MybatisUtil.getSqlSession();return sqlSession.selectList("courseNamespace.findAllByName",name);}catch(Exception e){e.printStackTrace();throw e;}finally{MybatisUtil.closeSqlSession();}}/*** 查询java课程有哪些学生选修* @param name 表示学生的课程*/public List<Student> findAllByCourseName(String name) throws Exception{SqlSession sqlSession = null;try{sqlSession = MybatisUtil.getSqlSession();return sqlSession.selectList("studentNamespace.findAllByCourseName",name);}catch(Exception e){e.printStackTrace();throw e;}finally{MybatisUtil.closeSqlSession();}}public static void main(String[] args) throws Exception{StudentCourseDao dao = new StudentCourseDao();List<Course> courseList = dao.findAllByName("哈哈");System.out.print("哈哈选学了" + courseList.size()+"个课程,分别是:");for(Course c : courseList){System.out.print(c.getName()+" ");}System.out.println("\n-----------------------------------------------------");List<Student> studentList = dao.findAllByCourseName("android");System.out.println("选修了android课程的学生有"+studentList.size()+"个,分别是:");for(Student s : studentList){System.out.print(s.getName()+" ");}}
}

总结

对于Mybatis的多表连接就非常简单了,由于SQL语句全是由我们自己写,如果我们返回的数据类型在当前的实体中是不够封装的话,那么我们只要再关联对应的映射属性就行了


如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y

转载于:https://www.cnblogs.com/Java3y/p/8554449.html

Mybatis【一对多、多对一、多对多】知识要点相关推荐

  1. ❤️Mybatis开发中什么是多对一处理、一对多处理?

    ❤️Mybatis开发中什么是多对一处理.一对多处理? 什么是多对一: 对于学生而言,关联-多个学生关联一个老师(多对一) 对于老师而言,集合-一个老师有很多学生(一对多) SQL: CREATE T ...

  2. MyBatis→SqlSession、sqlMapConfig.xml、映射XML文件、OGNL、拼接SQL标签、取值查值、批量SQL、一对多多对一多对多

    官网 https://mybatis.org/mybatis-3/ SqlSession sqlMapConfig.xml OGNL XML拼接SQL标签 参数取值 预编译与直接赋值 编码规范 sel ...

  3. Mybatis一对多及多对多映射查询

    1.数据库准备工作 --删除表 drop table SelectiveInfo; drop table StudentInfo; drop table ClassInfo; drop table T ...

  4. java day55【 Mybatis 连接池与事务深入 、 Mybatis 的动态 SQL 语句、 Mybatis 多表查询之一对多 、 Mybatis 多表查询之多对多】...

    第1章 Mybatis 连接池与事务深入 1.1 Mybatis 的连接池技术 1.1.1 Mybatis 连接池的分类 1.1.2 Mybatis 中数据源的配置 1.1.3 Mybatis 中 D ...

  5. MyBatis的高级映射之多对一

    第五节 MyBatis的高级映射之多对一 2016年3月4日 星期五 09:25 使用传统方式的形式 使用MyBatis的方式 这样会产生两条语句 使用ResultMap的方式,对结果进行映射和转换, ...

  6. MySQL----表的一对多关系和多对多关系

    MySQL----表的一对多关系和多对多关系 1.一对多关系 1.1名词解释: 一对多关系:通过主键外关系,形成一对多关系. 一表:又称之为主表,主表需要提供主键. 多表:又称之为从表,从表需提供外键 ...

  7. Mybatis 一对多 结果集映射 简单入门 易懂

    Mybatis官方文档说明处 Mybatis 一对多 结果集映射 简单入门 易懂 一.搭建数据库环境 二.idea 搭建maven 项目 (mybatis-demo) 2.1.项目结构 2.2.导入依 ...

  8. mybatis 一对多查询 按结果嵌套处理、按查询嵌套处理,以及两者之间的区别

    mybatis 一对多查询 按结果嵌套处理.按查询嵌套处理 最近用到一对多查询,记录一下 实体类 public class RegionEntity implements Serializable { ...

  9. 3.SpringBoot整合Mybatis(一对多)

    前言: Mybatis一对多的处理关系: 一个人有好多本书,每本书的主人只有一个人.当我们查询某个人拥有的所有书籍时,就涉及到了一对多的映射关系. 一.添加数据表: 1 CREATE TABLE `b ...

  10. mybatis一对多查询返回

    mybatis一对多查询返回 定义实体类 Mapper.xml文件 Mapper.java文件 定义实体类 InventoryVO 和InventoryDetailVO是一对多的关系. @Data p ...

最新文章

  1. 【Android游戏开发之七】(游戏开发中需要的样式)再次剖析游戏开发中对SurfaceView中添加组件方案!...
  2. 【Java 注解】自定义注解 ( 元注解 )
  3. 用神经网络的分类行为理解力的相互作用
  4. 三、新手Jupyter不会用,我十招教你盘她
  5. 【公告】服务器升级完成
  6. jquery 动态加载html,jQuery – 动态创建iframe并加载页面
  7. * poj 3159 Candies 最短路 dijkstra堆优化
  8. 修改 “嗨加游-Prefix.pch” 或者 “嗨加游-Info.plist ” 方法
  9. Struts2入门这一篇就够了 1
  10. 【codevs1048】石子归并
  11. 工作所思--IT新人
  12. random随机数类
  13. echarts官网折线图
  14. 共享计算机用户帐户限制怎么办,系统之家Win7系统无法共享提示用户账户限制怎么办...
  15. binance ping pong
  16. c语言一个数平方表示,C语言 - 利用 汇编思想 写一个数的平方
  17. 花洒水龙头加州节水认证CEC
  18. 二向箔-百日打卡writeup16-20
  19. 非暴力沟通——读后感
  20. 世系是家谱的核心,编修家谱过程中我们应该如何编写世系图

热门文章

  1. 为.NET部署应用程序添加个卸载程序
  2. 基于 TensorFlow 的图像识别(R实现)
  3. javacore分析工具_「赵强老师」如何分析Java的内存溢出问题
  4. python开课吧官网_开课吧老师详解 学Python真的可以帮助提高办公效率吗
  5. vi php,linux编辑文件命令vi有什么作用
  6. piczoom兼容性问题_浏览器不兼容原因及解决办法
  7. indesign排版标点挤压_我於\LaTeX 中文直排实践中所感受的排版需求
  8. dnf跨一服务器修复,DNF跨区服务器炸裂:一阶段史诗回档,官方补偿何在
  9. 六、DNS组成与原理
  10. cd命令无法切换路径(Windows下)