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。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章