MyBatis 關(guān)聯(lián)映射

客觀世界中的對(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)系大致有如下分類。

  1. 一對(duì)一
  2. 一對(duì)多
  3. 多對(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


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ??本文針對(duì)MyBatis的關(guān)聯(lián)映射,重點(diǎn)在于:(1)不同的關(guān)聯(lián)關(guān)系(一對(duì)一、一對(duì)多、多對(duì)多)如何創(chuàng)建數(shù)據(jù)表和在對(duì)...
    secondtown閱讀 4,315評(píng)論 0 0
  • ??前面幾篇關(guān)于mybatis的文章中的案例都是基于單表下面的操作,如果涉及多表之間的操作情況就變復(fù)雜了,常見(jiàn)的多...
    小manong閱讀 659評(píng)論 0 0
  • 一、實(shí)驗(yàn)?zāi)康模?掌握MyBatis的關(guān)聯(lián)映射(一對(duì)一、一對(duì)多、多對(duì)多)實(shí)驗(yàn)內(nèi)容:模擬用戶批量購(gòu)買理財(cái)產(chǎn)品的業(yè)務(wù)。用...
    Topus閱讀 1,504評(píng)論 0 2
  • 多對(duì)一單向關(guān)聯(lián)映射 配置方法一: 配置方法二: 配置方法三: 多對(duì)一/一對(duì)多雙向關(guān)聯(lián)映射 配置方法一: 配置方法二:
    Mr_J316閱讀 568評(píng)論 0 0
  • 1. 簡(jiǎn)介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存儲(chǔ)過(guò)程以及高級(jí)映射的優(yōu)秀的...
    笨鳥(niǎo)慢飛閱讀 6,273評(píng)論 0 4

友情鏈接更多精彩內(nèi)容