博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Mybatis【一对多、多对一、多对多】知识要点
阅读量:6256 次
发布时间:2019-06-22

本文共 12174 字,大约阅读时间需要 40 分钟。

Mybatis【多表连接】

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

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

一)内连接(等值连接):查询客户姓名,订单编号,订单价格    ---------------------------------------------------    select c.name,o.isbn,o.price    from customers c inner join orders o    where c.id = o.customers_id;    ---------------------------------------------------    select c.name,o.isbn,o.price    from customers c join orders o    where c.id = o.customers_id;     ---------------------------------------------------    select c.name,o.isbn,o.price    from customers c,orders o    where c.id = o.customers_id;    ---------------------------------------------------    select c.name,o.isbn,o.price    from customers c join orders o    on c.id = o.customers_id;    ---------------------------------------------------    注意:内连接(等值连接)只能查询出多张表中,连接字段相同的记录二)外连接:按客户分组,查询每个客户的姓名和订单数    ---------------------------------------------------    左外连接:    select c.name,count(o.isbn)    from  customers c left outer join orders o    on c.id = o.customers_id    group by c.name;     ---------------------------------------------------    右外连接:    select c.name,count(o.isbn)    from  orders o right outer join customers c       on c.id = o.customers_id    group by c.name;     ---------------------------------------------------    注意:外连接既能查询出多张表中,连接字段相同的记录;又能根据一方,将另一方不符合相同记录强行查询出来三)自连接:求出AA的老板是EE    ---------------------------------------------------    内自连接:    select users.ename,boss.ename    from emps users inner join emps boss     on users.mgr = boss.empno;    ---------------------------------------------------    外自连接:    select users.ename,boss.ename    from 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映射文件

Card映射文件

DAO层

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

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

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

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

我来看一下查询结果:

这里写图片描述

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

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

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

查询编号为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
studentList = new ArrayList
();//关联属性 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
getStudentList() { return studentList; } public void setStudentList(List
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语句

DAO

public List
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 = 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
studentList = new ArrayList
();//关联属性 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
getStudentList() { return studentList; } public void setStudentList(List
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
courseList = new ArrayList
();//关联属性 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
getCourseList() { return courseList; } public void setCourseList(List
courseList) { this.courseList = courseList; }}

映射文件

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
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
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
courseList = dao.findAllByName("哈哈"); System.out.print("哈哈选学了" + courseList.size()+"个课程,分别是:"); for(Course c : courseList){ System.out.print(c.getName()+" "); } System.out.println("\n-----------------------------------------------------"); List
studentList = dao.findAllByCourseName("android"); System.out.println("选修了android课程的学生有"+studentList.size()+"个,分别是:"); for(Student s : studentList){ System.out.print(s.getName()+" "); } }}

总结

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


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

转载地址:http://dqnsa.baihongyu.com/

你可能感兴趣的文章
POJ 3233 (矩阵)
查看>>
20161220
查看>>
11月27日
查看>>
Java位运算符
查看>>
智能手表ticwatch穿戴体验
查看>>
暑假第五周总结(2018.8.6-8.12)
查看>>
MFC下拉框Combo Box
查看>>
TCP带外数据读写
查看>>
uni-app采坑记录
查看>>
TP方法中打印地址栏中所有的参数:
查看>>
这是一个蒟蒻的计划……QAQ
查看>>
设置局域网共享文件不需要用户名密码
查看>>
raft--分布式一致性协议
查看>>
Solidity notes
查看>>
网上购物系统(Task005)——通用数据库访问函数集SqlHelper类
查看>>
java 单例模式浅析
查看>>
Codeforces Round #389 (Div. 2,) B C
查看>>
python中configparser模块记录
查看>>
IIIDX[九省联考2018]
查看>>
Protobuf3 序列化
查看>>