客觀世界中的對(duì)象很少有孤立存在的,例如班級(jí),往往與班級(jí)的學(xué)生存在關(guān)聯(lián)關(guān)系,如果 得到某個(gè)班級(jí)的實(shí)例,那么應(yīng)該可以直接獲取班級(jí)對(duì)應(yīng)的全部學(xué)生。反過(guò)來(lái),如果已經(jīng)得到一 個(gè)學(xué)生的實(shí)例,那么也應(yīng)該可以訪問(wèn)該學(xué)生對(duì)應(yīng)的班級(jí)。這種實(shí)例之間的互相訪問(wèn)就是關(guān)聯(lián)關(guān)系。
關(guān)聯(lián)關(guān)系是面向?qū)ο蠓治觥⒚嫦驅(qū)ο笤O(shè)計(jì)最重要的知識(shí),MyBatis完全可以理解這種關(guān)聯(lián) 關(guān)系,如果映射得當(dāng),MyBatis的關(guān)聯(lián)映射將可以大大簡(jiǎn)化持久層數(shù)據(jù)的訪問(wèn)。關(guān)聯(lián)關(guān)系大致有如下分類。
- 一對(duì)一
- 一對(duì)多
- 多對(duì)多
一對(duì)一
在實(shí)際項(xiàng)目開(kāi)發(fā)中,經(jīng)常存在一對(duì)一關(guān)系,比如一個(gè)人只能有一個(gè)身份證,一個(gè)身份證只 能給一個(gè)人使用,這就是一對(duì)一的關(guān)系。一對(duì)一關(guān)系推薦使用唯一主外鍵關(guān)聯(lián),即兩張表使用 外鍵關(guān)聯(lián)關(guān)系,由于是一對(duì)一關(guān)聯(lián),因此還需要給外鍵列增加unique唯一約束。下面我們就用一個(gè)簡(jiǎn)單示例來(lái)看看MyBatis怎么處理一對(duì)一關(guān)系。
首先,給之前創(chuàng)建的mybatis數(shù)據(jù)庫(kù)創(chuàng)建兩個(gè)表tb_card和tb_person,并插入測(cè)試數(shù)據(jù)。 SQL腳本如下:
`
CREATE TABLE tb_card(
id INT PRIMARY KEY AUTO_INCREMENT,
CODE VARCHAR(18)
);
INSERT INTO tb_card(CODE) VALUES('432801198009191038');
CREATE TABLE tb_person(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(18),
sex VARCHAR(18),
age INT,
card_id INT UNIQUE,
FOREIGN KEY (card_id) REFERENCES tb_card(id)
);
INSERT INTO tb_person(NAME,sex,age,card_id) VALUES('jack','男',23,1)
`
tb_person表的card_id作為外鍵參照tb_card表的主鍵id,因?yàn)槭且粚?duì)一關(guān)系,: 即一個(gè)card只能讓一個(gè)person使用,所以cardjd做成了唯一鍵約束。如此一來(lái),| 當(dāng)一個(gè)person使用了一個(gè)card之后,其他的person就不能使用該card 了。
代碼如下:Card
`
package org.fkit.domain;
import java.io.Serializable;
public class Card implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id; // 主鍵id
private String code; // 身份證編號(hào)
public Card() {
super();
// TODO Auto-generated constructor stub
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public String toString() {
return "Card [id=" + id + ", code=" + code + "]";
}
}
`
代碼如下:Person
`
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id; // 主鍵id
private String name; // 姓名
private String sex; // 性別
private Integer age; // 年齡
// 人和身份證是一對(duì)一的關(guān)系,即一個(gè)人只有一個(gè)身份證
private Card card;
public Person() {
super();
// TODO Auto-generated constructor stub
}
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 String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Card getCard() {
return card;
}
public void setCard(Card card) {
this.card = card;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", sex=" + sex
+ ", age=" + age + "]";
}
}
`
一對(duì)多
在實(shí)際項(xiàng)目開(kāi)發(fā)中,一對(duì)多是非常常見(jiàn)的關(guān)系,比如,一個(gè)班級(jí)可以有多個(gè)學(xué)生,一個(gè)學(xué) 生只能屬于一個(gè)班級(jí),班級(jí)和學(xué)生是一對(duì)多的關(guān)系,而學(xué)生和班級(jí)是多對(duì)一的關(guān)系。數(shù)據(jù)庫(kù)中 一對(duì)多關(guān)系通常使用主外鍵關(guān)聯(lián),外鍵列應(yīng)該在多方,即多方維護(hù)關(guān)系。下面我們就用一個(gè)簡(jiǎn)單本例來(lái)看看MyBatis怎么處理一對(duì)多關(guān)系。
首先,給之前創(chuàng)建的mybatis數(shù)據(jù)庫(kù)創(chuàng)建兩個(gè)表tb_clazz和tb_student,并插入測(cè)試數(shù)據(jù)。 SQL腳本如下:
`
CREATE TABLE tb_clazz(
id INT PRIMARY KEY AUTO_INCREMENT,
CODE VARCHAR(18),
NAME VARCHAR(18)
);
INSERT INTO tb_clazz(CODE,NAME) VALUES('j1601','aaa');
CREATE TABLE tb_student(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(18),
sex VARCHAR(18),
age INT,
clazz_id INT,
FOREIGN KEY (clazz_id) REFERENCES tb_clazz(id)
);
INSERT INTO tb_student(NAME,sex,age,clazz_id) VALUES('jack','男',23,1);
INSERT INTO tb_student(NAME,sex,age,clazz_id) VALUES('rose','女',18,1);
INSERT INTO tb_student(NAME,sex,age,clazz_id) VALUES('tom','男',21,1);
INSERT INTO tb_student(NAME,sex,age,clazz_id) VALUES('alice','女',20,1);
`
tb_student表的clazz_id作為外鍵參 照tb_clazz表的主鍵id。
Clazz實(shí)體:
`
public class Clazz implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id; // 班級(jí)id,主鍵
private String code; // 班級(jí)編號(hào)
private String name; // 班級(jí)名稱
// 班級(jí)和學(xué)生是一對(duì)多的關(guān)系,即一個(gè)班級(jí)可以有多個(gè)學(xué)生
private List<Student> students;
public Clazz() {
super();
// TODO Auto-generated constructor stub
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "Clazz [id=" + id + ", code=" + code + ", name=" + name + "]";
}
}
`
Student實(shí)體:
`
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id; // 學(xué)生id,主鍵
private String name; // 姓名
private String sex; // 性別
private Integer age; // 年齡
// 學(xué)生和班級(jí)是多對(duì)一的關(guān)系,即一個(gè)學(xué)生只屬于一個(gè)班級(jí)
private Clazz clazz;
public Student() {
super();
// TODO Auto-generated constructor stub
}
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 String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Clazz getClazz() {
return clazz;
}
public void setClazz(Clazz clazz) {
this.clazz = clazz;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", sex=" + sex
+ ", age=" + age + "]";
}
}
`
多對(duì)多
在實(shí)際項(xiàng)目開(kāi)發(fā)中,多對(duì)多關(guān)系也是非常常見(jiàn)的關(guān)系,比如,一個(gè)購(gòu)物系統(tǒng)中,一個(gè)用戶 可以有多個(gè)訂單,這是一對(duì)多的關(guān)系;一個(gè)訂單中可以購(gòu)買多種商品,一種商品也可以屬于多 個(gè)不同的訂單,訂單和商品就是多對(duì)多的關(guān)系。對(duì)于數(shù)據(jù)庫(kù)中多對(duì)多關(guān)系建議使用一個(gè)中間表 來(lái)維護(hù)關(guān)系,中間表中的訂單id作為外鍵參照訂單表的id,商品id作為外鍵參照商品表的id。 下面我們就用一個(gè)簡(jiǎn)單示例來(lái)看看MyBatis怎么處理多對(duì)多關(guān)系。
首先,給之前創(chuàng)建的mybatis數(shù)據(jù)庫(kù)創(chuàng)建三個(gè)表tb_user、tb_article和tb_order, 再創(chuàng)建一個(gè)中間表維護(hù)tb_article和tb_order的關(guān)系,并插入測(cè)試數(shù)據(jù)。SQL腳本如下。
`
/**
*
CREATE TABLE tb_user(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(18),
loginname VARCHAR(18),
PASSWORD VARCHAR(18),
phone VARCHAR(18),
address VARCHAR(18)
);
INSERT INTO tb_user(username,loginname,PASSWORD,phone,address)
VALUES('杰克','jack','123456','1392456789','廣州');
CREATE TABLE tb_article(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(18),
price DOUBLE,
remark VARCHAR(18)
);
INSERT INTO tb_article(NAME,price,remark)
VALUES('aaa',108.9,'aaa經(jīng)典著作');
INSERT INTO tb_article(NAME,price,remark)
VALUES('bbb',99.9,'bbb經(jīng)典著作');
INSERT INTO tb_article(NAME,price,remark)
VALUES('ccc',89.9,'ccc經(jīng)典著作');
INSERT INTO tb_article(NAME,price,remark)
VALUES('ddd',69.9,'ddd經(jīng)典著作');
CREATE TABLE tb_order(
id INT PRIMARY KEY AUTO_INCREMENT,
CODE VARCHAR(32),
total DOUBLE,
user_id INT,
FOREIGN KEY (user_id) REFERENCES tb_user(id)
);
INSERT INTO tb_order(CODE,total,user_id)
VALUES('6aa3fa359ff14619b77fab5990940a2d',388.6,1);
INSERT INTO tb_order(CODE,total,user_id)
VALUES('6aa3fa359ff14619b77fab5990940b3c',217.8,1);
CREATE TABLE tb_item(
order_id INT,
article_id INT,
amount INT,
PRIMARY KEY(order_id,article_id),
FOREIGN KEY (order_id) REFERENCES tb_order(id),
FOREIGN KEY (article_id) REFERENCES tb_article(id)
);
INSERT INTO tb_item(order_id,article_id,amount)
VALUES(1,1,1);
INSERT INTO tb_item(order_id,article_id,amount)
VALUES(1,2,1);
INSERT INTO tb_item(order_id,article_id,amount)
VALUES(1,3,2);
INSERT INTO tb_item(order_id,article_id,amount)
VALUES(2,4,2);
INSERT INTO tb_item(order_id,article_id,amount)
VALUES(2,1,1);
* */``
`
實(shí)體:User
`
public class User implements Serializable{
private static final long serialVersionUID = 1L;
private Integer id; // 用戶id,主鍵
private String username; // 用戶名
private String loginname; // 登錄名
private String password; // 密碼
private String phone; // 聯(lián)系電話
private String address; // 收貨地址
// 用戶和訂單是一對(duì)多的關(guān)系,即一個(gè)用戶可以有多個(gè)訂單
private List<Order> orders;
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(String username, String loginname, String password,
String phone, String address) {
super();
this.username = username;
this.loginname = loginname;
this.password = password;
this.phone = phone;
this.address = address;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getLoginname() {
return loginname;
}
public void setLoginname(String loginname) {
this.loginname = loginname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<Order> getOrders() {
return orders;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", loginname="
+ loginname + ", password=" + password + ", phone=" + phone
+ ", address=" + address + "]";
}
}
`
實(shí)體:Order
`
public class Order implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id; // 訂單id,主鍵
private String code; // 訂單編號(hào)
private Double total; // 訂單總金額
// 訂單和用戶是多對(duì)一的關(guān)系,即一個(gè)訂單只屬于一個(gè)用戶
private User user;
// 訂單和商品是多對(duì)多的關(guān)系,即一個(gè)訂單可以包含多種商品
private List<Article> articles;
public Order() {
super();
// TODO Auto-generated constructor stub
}
public Order(String code, Double total) {
super();
this.code = code;
this.total = total;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Double getTotal() {
return total;
}
public void setTotal(Double total) {
this.total = total;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<Article> getArticles() {
return articles;
}
public void setArticles(List<Article> articles) {
this.articles = articles;
}
@Override
public String toString() {
return "Order [id=" + id + ", code=" + code + ", total=" + total + "]";
}
}
`
實(shí)體:Article
`
public class Article implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id; // 商品id,主鍵
private String name; // 商品名稱
private Double price; // 商品價(jià)格
private String remark; // 商品描述
// 商品和訂單是多對(duì)多的關(guān)系,即一種商品可以包含在多個(gè)訂單中
private List<Order> orders;
public Article() {
super();
// TODO Auto-generated constructor stub
}
public Article(String name, Double price, String remark) {
super();
this.name = name;
this.price = price;
this.remark = remark;
}
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 Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public List<Order> getOrders() {
return orders;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
@Override
public String toString() {
return "Article [id=" + id + ", name=" + name + ", price=" + price
+ ", remark=" + remark + "]";
}
}
`
tb_order表的user_id作為外鍵參照tb_user表的主鍵id。tb_item表作為中間表, 用來(lái)維護(hù)tb_article和tb_order的多對(duì)多關(guān)系,tb_imte表的order_id作為外鍵參照 tb_order表的主鍵id, article id作為外鍵參照tb article表的主鍵id
- 郵箱:ithelei@sina.cn
- 技術(shù)討論群:687856230
- GoodLuck