Mybatis 一對一,一對多,多對一,多對多的理解
阿新 • • 發佈:2018-12-13
First (一對一)
首先我來說下一對一的理解,就是一個班主任只屬於一個班級,一個班級也只能有一個班主任。好吧這就是對於一對一的理解
怎麼來實現呢?
這裡我介紹了兩種方式:
一種是:使用巢狀結果對映來處理重複的聯合結果的子集
另一種呢是:通過執行另外一個SQL對映語句來返回預期的複雜型別
<?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,namespace的值習慣上設定成包名+sql對映檔名,這樣保證了namespace的值是唯一的--> <mapper namespace="com.yc.mybatis.test.classMapper"> <!-- 方式一:巢狀結果:使用巢狀結果對映來處理重複的聯合結果的子集 封裝聯表查詢的資料(去除重複的資料) select * from class c, teacher t where c.teacher_id=t.t_id and c.c_id=1 --> <select id="getClass" parameterType="int" resultMap="getClassMap"> select * from class c, teacher t where c.teacher_id = t.t_id and c.teacher_id=#{id} </select> <!-- resultMap:對映實體類和欄位之間的一一對應的關係 --> <resultMap type="Classes" id="getClassMap"> <id property="id" column="c_id"/> <result property="name" column="c_name"/> <association property="teacher" javaType="Teacher"> <id property="id" column="t_id"/> <result property="name" column="t_name"/> </association> </resultMap> <!-- 方式二:巢狀查詢:通過執行另外一個SQL對映語句來返回預期的複雜型別 SELECT * FROM class WHERE c_id=1; SELECT * FROM teacher WHERE t_id=1 //1 是上一個查詢得到的teacher_id的值 property:別名(屬性名) column:列名 --> <!-- 把teacher的欄位設定進去 --> <select id="getClass1" parameterType="int" resultMap="getClassMap1"> select * from class where c_id=#{id} </select> <resultMap type="Classes" id="getClassMap1"> <id property="id" column="c_id"/> <result property="name" column="c_name"/> <association property="teacher" column="teacher_id" select="getTeacher"/> </resultMap> <select id="getTeacher" parameterType="int" resultType="Teacher"> select t_id id,t_name name from teacher where t_id =#{id} </select> </mapper>
這裡對assacation標籤的屬性進行解釋一下:
property | 物件屬性的名稱 |
javaType | 物件屬性的型別 |
column | 所對應的外來鍵欄位名稱 |
select | 使用另一個查詢封裝的結果 |
這裡ben層會發生變化 這個classes的被bean層會多一個Teacher的屬性,並且增加的get,set方法。
Second (一對多)and (多對一)
一對多又是怎麼樣理解呢?
其實也很容易,一個顧客對應多個訂單,而一個訂單隻能對應一個客戶
而反過來也就是多對一的形式了
多個訂單表可以對應一個顧客,一個顧客是可以擁有多個訂單的
其實說到底就是有點類似多個一對一的情況,所以多對一的配置基本和一對一的配置保持一樣
一對多的xml配置:
<?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="com.yc.mapper.CustomerMapper"> <resultMap type="com.yc.m.Customer" id="resultCustomerMap"> <id column="id" jdbcType="INTEGER" property="id" /> <result property="address" column="address"/> <result property="postcode" column="postcode"/> <result property="sex" column="sex"/> <result property="cname" column="cname"/> <collection property="orders" ofType="com.yc.m.Orders"> <id property="id" column="id"/> <result property="code" column="code"/> </collection> </resultMap> <select id="getCustomer" resultMap="resultCustomerMap" parameterType="int"> SELECT * FROM t_customer WHERE id=#{id} </select> </mapper>
在這裡可以明顯的看出多出了一個屬性ofType,這個ofType的含義就是你collection所對應的是那個bean
當然在bean層中也會發生變化 ,這裡在Customer的bean中巢狀一條語句
private List<Orders> orders; //一個Customer 對應N多個Orders
Third (多對多)
多對多又怎麼理解呢?
一個使用者可以屬於多個集體(家人,朋友,同學),當然一個集體也包含了多個使用者
<strong> <!--collection:聚集 用來處理類似User類中有List<Group> group時要修改group的情況 user代表要修改的是Group中的List<user> --></strong>
<?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="com.yc.bean.Group">
<!-- resultMap:結合標準javabean規範,能hashmap或arraylist所不能完成的更復雜的resultType -->
<resultMap type="Group" id="groupMap">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="createTime" column="createdate" />
</resultMap>
<resultMap type="Group" id="groupUserMap" <span style="color:#ff0000;"><strong>extends</strong></span>="groupMap">
<collection property="user" ofType="User">
<!--collection:聚集 用來處理類似User類中有List<Group> group時要修改group的情況 user代表要修改的是Group中的List<user> -->
<id property="id" column="userId" />
<result property="name" column="userName" />
<result property="password" column="password" />
<result property="createTime" column="userCreateTime" />
</collection>
</resultMap>
<select id="selectAllGroup" resultMap="groupMap">
select * from group_info
</select>
<!-- 根據Group表中的id或name查詢組資訊和組內使用者資訊 -->
<select id="selectGroupUser" parameterType="Long"
resultMap="groupUserMap">
select u.id as userId,u.name as userName,
u.password,u.createtime as userCreateTime,
gi.id,gi.name,gi.createdate,gi.state from group_info gi left
join user_group ug on gi.id=ug.group_id left join user u on
ug.user_id=u.id where gi.id = #{id}
</select>
<!-- 刪除組與組內成員之間的對應關係 -->
<delete id="deleteGroupUser" parameterType="UserGroupLink">
delete from user_group
<where>
<if test="user.id != 0">user_id = #{user.id}</if>
<if test="group.id != 0">and group_id = #{group.id}</if>
</where>
</delete>
</mapper>
這裡還需要對user和group這兩個bean之間的對映關係進行描述一下:
package com.yc.deom;
import java.util.Date;
import com.yc.bean.Group;
import com.yc.bean.User;
/**
* @describe: 描述User和Group之間的對映關係
*/
public class UserGroupLink {
private User user;
private Group group;
private Date createTime;
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}