这段时间在学mybatis,到今天刚好是第五节课 关联关系映射,我记得先前学hibernate时,也有接触到映射一对多,多对一,多对多,虽说mybatis和hibernate均为持久层框架,但他们之间也有较大区别,比如说mybatis 属于轻量级,且半自动化,用sql,而hibernate数据重量级,且全自动化,用hql,个人感觉mybatis要高级点,也比较适用mybatis啦啦啦~
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 | 使用另一个查询封装的结果 |
这里bean层会发生变化 这个classes的被bean层会多一个Teacher的属性,并且增加的get,set方法。
resultType和resultMap实现一对一查询小结
实现一对一查询:
a.resultType:使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射。
b.如果没有查询结果的特殊要求建议使用resultType。
c.resultMap:需要单独定义resultMap,实现有点麻烦,如果对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo的属性中。
d.resultMap可以实现延迟加载,resultType无法实现延迟加载。
==============================================================================================
Second (一对多)and (多对一)
一对多又是怎么样理解呢?
其实也很容易,一个顾客对应多个订单,而一个订单只能对应一个客户
而反过来也就是多对一的形式了
多个订单表可以对应一个顾客,一个顾客是可以拥有多个订单的
其实说到底就是有点类似多个一对一的情况,所以多对一的配置基本和一对一的配置保持一样
一、顾客表和订单表数据库(mysql)代码:
-- 一对多
-- 客户表(主表)
create table t_customer
(
customer_id int primary key not null auto_increment,
customer_name varchar(50) not null
);
-- 多对一
-- 订单表(从表)
create table t_order
(
order_id int primary key not null auto_increment,
order_no varchar(50) not null unique,
cid int not null,
foreign key(cid) references t_customer(customer_id)
);
-- 初始化代码
delete from t_order;
delete from t_customer;
-- 与mssql不一样,自动增长是可以赋值,也可以不赋值
insert into t_customer(customer_id,customer_name) values(1, 'zs');
insert into t_customer(customer_id,customer_name) values(2, 'ls');
insert into t_customer(customer_id,customer_name) values(3, 'ww');
insert into t_customer(customer_id,customer_name) values(4, 'xm');
insert into t_order(order_no,cid) values('P01',1);
insert into t_order(order_no,cid) values('P02',1);
insert into t_order(order_no,cid) values('P03',1);
insert into t_order(order_no,cid) values('P04',1);
insert into t_order(order_no,cid) values('P05',1);
insert into t_order(order_no,cid) values('P06',2);
insert into t_order(order_no,cid) values('P07',2);
insert into t_order(order_no,cid) values('P08',2);
insert into t_order(order_no,cid) values('P09',3);
insert into t_order(order_no,cid) values('P10',3);
SELECT * FROM t_customer;
SELECT * FROM t_order;
二、因为我用的idea下载了插件,然后model包(有的人是pojo)mapper包,和XxxMapper.xml文件都是自动生成,需要者请参考我的博客<IntelliJ idea中简单配置的插件理解和使用: https://blog.youkuaiyun.com/Fy_Deng/article/details/85985647 >
当生成了我们的一对多,多对一所以需要的model中实体类Customer.jave Order.java
package com.zking.ssm.model;
import com.sun.org.apache.xml.internal.serializer.utils.SerializerMessages_sv;
import lombok.ToString;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@ToString
public class Customer implements Serializable {
private Integer customerId;
private String customerName;
private List<Order> orderList = new ArrayList<Order>();
public Customer(Integer customerId, String customerName) {
this.customerId = customerId;
this.customerName = customerName;
}
public List<Order> getOrderList() {
return orderList;
}
public void setOrderList(List<Order> orderList) {
this.orderList = orderList;
}
public Customer() {
super();
}
public Integer getCustomerId() {
return customerId;
}
public void setCustomerId(Integer customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
}
package com.zking.ssm.model;
import lombok.ToString;
import java.io.Serializable;
@ToString
public class Order implements Serializable {
private Integer orderId;
private String orderNo;
private Integer cid;
private Customer customer;
public Order(Integer orderId, String orderNo, Integer cid) {
this.orderId = orderId;
this.orderNo = orderNo;
this.cid = cid;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public Order() {
super();
}
public Integer getOrderId() {
return orderId;
}