且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Mybatis【关联映射】(一)

更新时间:2022-10-03 14:15:02

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语句来使我们的关联属性连接起来…

一对一

需求:

  • 学生和身份证

这里写图片描述

设计表:

--mysql
create 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;

我来看一下查询结果:

Mybatis【关联映射】(一)

我们的实体与映射表中,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());
    }

Mybatis【关联映射】(一)