Mybatis表关系操作(一对一、一对多、多对多)

一、resultMap关键字

Mybatis负责的是Dao层之间的交互,我们都知道表与表之间具有三种关系,一对一,一对多,多对多。我们要想让结果封装到bean中,就要通过resultMap关键字进行映射。

<resultMap type="" id=""></resultMap>

type表示bean的类型。

id表示该resultMap的名称。

在resultMap子标签中,有许多有用的子标签

<id column="" property=""/>
<result column="" property=""/>
<association property="" javaType=""></association>
<collection property="" ofType=""></collection>

id:表示数据表中的主键字段,必须要有。

column:表示表中的字段

property:表示bean中的属性名称

result:表示普通字段

association :通常被用于一对一的关系,通常是外键字段

javaType:被涉及表的bean

collection :通常被用于表示一对多,多对多关系,通常是外键字段

ofType:被涉及表的bean

 

二、一对一关系操作

生活中,我们也经常会遇到一对一事件的关系,像一个一张车票对应一个顾客等等事件。在Mybatis中,我们该如何配置这种映射文件呢?

【1】建表语句

create table people (id int primary key auto_increment, name varchar(20));
create table ticket(id int primary key auto_increment, price int, pid int);

【2】创建实体类

车票类:

public class Ticket {

	private int id;
	private int price;
	private People pl;
    
    setter与getter方法....
}

用户类:

public class People {

	private int id;
	private String name;

    setter与getter.....
}

【3】ticketMapper映射文件(以查询语句为例)

<resultMap type="domain.Ticket" id="sel_tp">
        <id column="tid" property="id"/>
        <result column="tprice" property="price"/>
        <association property="people" javaType="domain.People">
            <id column="pid" property="id"/>
       	    <result column="pname" property="name"/>
        </association>
    </resultMap>
    
    <select id="select" resultMap="sel_tp">
        select 
        	people.id as pid,
        	people.name as pname,
        	ticket.id as tid,
        	ticket.price as tprice
        from people inner join ticket on ticket.pid = people.id
    </select>

在这个案例中,大家应该注意<association property="people" javaType="domain.People">property对应的是该bean类中涉及外表的属性值,javaType则对应该属性对应的实体类。

此外,inner join是内连接查询,用于查询在on的条件下,两张表都有涉及的数据

三、一对多关系操作

生活中,有许多一对多关系的事件,就像一个班级对应多个学生,一个部门对应多个员工等等。

接下来,我们以班级与学生的关系为例,介绍Mybatis如何实现一对多。

【1】建表语句

create table class (id int primary key auto_increment, name varchar(20));
create table student (id int primary key auto_increment, name varchar(20),cid int);
insert into class values(null,'数媒1班');
insert into class values(null,'数媒2班');
insert into student values(null,'张三',1);
insert into student values(null,'李四',2);
insert into student values(null,'王五',2);
insert into student values(null,'赵六',1);

【2】实体类创建

学生类创建

public class Student {

	private int id;
	private String name;
	private ClassStu cls;

	setter与getter方法
    toString方法

}

教室类创建

public class ClassStu {

	private int id;
	private String name;
	private List<Student> list;
    
    setter与getter方法
    toString方法

}

【3】映射文件配置

(1)以学生为主体

<resultMap type="domain.Student" id="clastu">
        <id column="sid" property="id"/>
        <result column="sname" property="name"/>
        <!-- 一位学生对应一个班级,所以选用association标签 -->
        <association property="cls" javaType="domain.ClassStu">
            <id column="cid" property="id"/>
       		<result column="cname" property="name"/>
        </association>
    </resultMap>
    
    <select id="select01" resultMap="clastu">
        select 
        	class.id as cid,
        	class.name as cname,
        	student.id as sid,
        	student.name as sname
        from class inner join student on class.id = student.cid
    </select>

因为,一位学生就对应一个班级,所以说,采用association 标签,用来进行关系映射。

(2)以班级为主体

<resultMap type="domain.ClassStu" id="clastu2">
        <id column="cid" property="id"/>
       	<result column="cname" property="name"/>
        <collection property="list" ofType="domain.ClassStu">
            <id column="sid" property="id"/>
        	<result column="sname" property="name"/>
        </collection>  
    </resultMap>

因为,一个班级对应多个学生,所以说采用collection标签,进行关系映射。注意collectionassocation标签中的字段数据类型,一个是ofType,一个·是javaType。

四、多对多关系操作

我们生活中也有许多,多对多关系的情况,像老师与学生的关系。医生与病人的关系等等。接下来,我就以医生与病人的关系进行阐述。

【1】建表语句

多对多的关系需要三张表进行操作。其中,有一张表,表示其他两张表的对应关系。

insert into docter values(null, '王医生');
insert into docter values(null, '李护士');
insert into docter values(null, '张医生');

insert into patient values(null, '张三');
insert into patient values(null, '李四');

insert into relation values(null, 1,1);
insert into relation values(null, 2,1);
insert into relation values(null, 2,2);
insert into relation values(null, 3,2);

【2】实体类

医生类

public class Docter {

	private int id;
	private String name;
	private List<Patient> patient;

    setter与getter方法
    toString方法
    .....
}

病人类

public class Patient {
	private int id;
	private String name;
	private List<Docter> docter;

    .....
    setter与getter方法
    toString方法
    .....
}

【3】映射文件配置

<resultMap type="domain.Docter" id="docpat">
        <id column="did" property="id"/>
       	<result column="dname" property="name"/>
        <collection property="patient" ofType="domain.Patient">
            <id column="pid" property="id"/>
        	<result column="pname" property="name"/>
        </collection>  
    </resultMap>
    
    <select id="select01" resultMap="docpat">
        select 
        	docter.id as did,
        	docter.name as dname,
        	patient.id as pid,
        	patient.name as pname
        from docter inner join relation on docter.id = relation.did
        inner join patient on relation.pid = patient.id
    </select>

因为每个对象都有多个对应的对象,所以采用collection标签。

其次,因为涉及三表查询,所以使用两次内连接查询,用以过滤掉不符合条件的信息字段。

同理,如果以病人为主体,只需要修改resultMap中的少许信息即可。

 

五、resultMap标签的其他用法

表中的字段与实体类名称不一致的时候,可以使用resultMap标签,进行对应。

<resultMap type="domain.People" id="people">
        <id column="id" property="pid"/>
        <result column="name" property="pname"/>
    </resultMap>
    
    <select id="select01" resultMap="people">
        select 
        	id,name
        from people
    </select>

其中,people表的字段,与实体类的属性名称不能一一对应,所以就不能自动封装数据。故可以使用resultMap标签进行关系映射。

id       ->  pid

name ->  pname

大家要注意,此时返回值的标签不在是resultType,而是resultMap。

 

 

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值