mybatis關聯映射多對多

項目開發中,多對多關係也是很是常見的關係

在數據庫中建立表的腳本
table.sqljava

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','13920001616','廣州');

CREATE TABLE tb_article(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(50),
price DOUBLE,
remark VARCHAR(18)
);

INSERT INTO tb_article(NAME,price,remark) 
VALUES('瘋狂Java講義',108.9,'李剛老師經典著做');
INSERT INTO tb_article(NAME,price,remark) 
VALUES('瘋狂Android講義',99.9,'李剛老師經典著做');
INSERT INTO tb_article(NAME,price,remark) 
VALUES('瘋狂iOS講義',89.9,'李剛老師經典著做');
INSERT INTO tb_article(NAME,price,remark) 
VALUES('SpringMVC+MyBatis企業開發',69.9,'肖文吉老師經典著做');

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);

接下來建立一個User類,Article和一個Order類來映射數據庫中的表
用戶和訂單是一對多的關係,即一個用戶能夠有多個訂單,在User類中定義一個orders屬性,該屬性是一個List集合,用來映射一對多的關聯關係
訂單與用戶是多對一的關係,一個訂單只是屬於一個用戶,在Order類中定義一個user屬性,用來映射多對一的關聯關係
商品和訂單是多對多的關係,即一種商品能夠出如今多個訂單中,在Article類中定義一個orders屬性,該屬性是一個List集合,用來映射多對多的關聯關係,表示該商品關聯的多個訂單
Article.javasql

public class Article implements Serializable {
    
    private Integer id;     // 商品id,主鍵
    private String name;    // 商品名稱
    private Double price;   // 商品價格
    private String remark;  // 商品描述
    
    // 商品和訂單是多對多的關係,即一種商品能夠包含在多個訂單中
    private List<Order> orders;
}

Order.java數據庫

public class Order implements Serializable {

    private Integer id;  // 訂單id,主鍵
    private String code;  // 訂單編號
    private Double total; // 訂單總金額
    
    // 訂單和用戶是多對一的關係,即一個訂單隻屬於一個用戶
    private User user;
    
    // 訂單和商品是多對多的關係,即一個訂單能夠包含多種商品
    private List<Article> articles;
}

User.javaapache

public class User implements Serializable{
    
    private Integer id;  // 用戶id,主鍵
    private String username;  // 用戶名
    private String loginname; // 登陸名
    private String password;  // 密碼
    private String phone;    // 聯繫電話
    private String address;  // 收貨地址
    
    // 用戶和訂單是一對多的關係,即一個用戶能夠有多個訂單
    private List<Order> orders;

xml文件配置
ArticleMapper.xmlsession

<?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">
<!-- namespace指用戶自定義的命名空間。 -->
<mapper namespace="com.rookie.bigdata.mapper.ArticleMapper">
  
  <select id="selectArticleByOrderId" parameterType="int" 
  resultType="com.rookie.bigdata.domain.Article">
    SELECT * FROM tb_article WHERE id IN ( 
        SELECT article_id FROM tb_item WHERE order_id = #{id} 
    ) 
  </select>
  

</mapper>

OrderMapper.xmlmybatis

<?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">
<!-- namespace指用戶自定義的命名空間。 -->
<mapper namespace="com.rookie.bigdata.mapper.OrderMapper">

    <resultMap type="com.rookie.bigdata.domain.Order" id="orderResultMap">
        <id property="id" column="oid"/>
        <result property="code" column="code"/>
        <result property="total" column="total"/>
        <!-- 多對一關聯映射:association   -->
        <association property="user" javaType="com.rookie.bigdata.domain.User">
            <id property="id" column="id"/>
            <result property="username" column="username"/>
            <result property="loginname" column="loginname"/>
            <result property="password" column="password"/>
            <result property="phone" column="phone"/>
            <result property="address" column="address"/>
        </association>
        <!-- 多對多映射的關鍵:collection   -->
        <collection property="articles" javaType="ArrayList"
      column="oid" ofType="com.rookie.bigdata.domain.Article"
      select="com.rookie.bigdata.mapper.ArticleMapper.selectArticleByOrderId"
      fetchType="lazy">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="price" column="price"/>
        <result property="remark" column="remark"/>
      </collection>
    </resultMap>
    
    <!-- 注意,若是查詢出來的列同名,例如tb_user表的id和tb_order表的id都是id,同名,須要使用別名區分 -->
  <select id="selectOrderById" parameterType="int" resultMap="orderResultMap">
    SELECT u.*,o.id AS oid,CODE,total,user_id
     FROM tb_user u,tb_order o
    WHERE u.id = o.user_id
     AND o.id = #{id}
  </select>
  
  <!-- 根據userid查詢訂單 -->
  <select id="selectOrderByUserId" parameterType="int" resultType="com.rookie.bigdata.domain.Order">
    SELECT * FROM tb_order WHERE user_id = #{id}
  </select>
  

</mapper>

UserMapper.xmlapp

<?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">
<!-- namespace指用戶自定義的命名空間。 -->
<mapper namespace="com.rookie.bigdata.mapper.UserMapper">

    <resultMap type="com.rookie.bigdata.domain.User" id="userResultMap">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="loginname" column="loginname"/>
        <result property="password" column="password"/>
        <result property="phone" column="phone"/>
        <result property="address" column="address"/>
        <!-- 一對多關聯映射:collection   -->
        <collection property="orders" javaType="ArrayList"
      column="id" ofType="com.rookie.bigdata.domain.User"
      select="com.rookie.bigdata.mapper.OrderMapper.selectOrderByUserId"
      fetchType="lazy">
        <id property="id" column="id"/>
        <result property="code" column="code"/>
        <result property="total" column="total"/>
      </collection>
    </resultMap>
    
  <select id="selectUserById" parameterType="int" resultMap="userResultMap">
    SELECT * FROM tb_user  WHERE id = #{id}
  </select>
  

</mapper>

測試代碼dom

package com.rookie.bigdata.test;

import java.io.InputStream;
import java.util.List;

import com.rookie.bigdata.domain.Article;
import com.rookie.bigdata.domain.Order;
import com.rookie.bigdata.domain.User;
import com.rookie.bigdata.mapper.OrderMapper;
import com.rookie.bigdata.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;


public class ManyToManyTest {

    public static void main(String[] args) throws Exception {
        // 讀取mybatis-config.xml文件
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        // 初始化mybatis,建立SqlSessionFactory類的實例
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
                .build(inputStream);
        // 建立Session實例
        SqlSession session = sqlSessionFactory.openSession();
        
        ManyToManyTest t = new ManyToManyTest();
        
        // 根據用戶id查詢用戶,測試一對多
//      t.testSelectUserById(session);
        // 根據訂單id查詢訂單,測試多對多
        t.testSelectOrderById(session);
        
        // 提交事務
        session.commit();
        // 關閉Session
        session.close();
    }
    
    // 測試一對多,查詢班級User(一)的時候級聯查詢訂單Order(多)  
    public void testSelectUserById(SqlSession session){
        // 得到UserMapper接口的代理對象
        UserMapper um = session.getMapper(UserMapper.class);
        // 調用selectUserById方法
        User user = um.selectUserById(1);
        // 查看查詢到的user對象信息
        System.out.println(user.getId() + " " + user.getUsername());
        // 查看user對象關聯的訂單信息
        List<Order> orders = user.getOrders();
        for(Order order : orders){
            System.out.println(order);
        }
    }
    
    // 測試多對多,查詢訂單Order(多)的時候級聯查詢訂單的商品Article(多)  
    public void testSelectOrderById(SqlSession session){
        // 得到OrderMapper接口的代理對象
        OrderMapper om = session.getMapper(OrderMapper.class);
        // 調用selectOrderById方法
        Order order = om.selectOrderById(2);
        // 查看查詢到的order對象信息
        System.out.println(order.getId() + " " + order.getCode() + " " + order.getTotal());
        // 查看order對象關聯的用戶信息
        User user = order.getUser();
        System.out.println(user);
        // 查看order對象關聯的商品信息
        List<Article> articles = order.getArticles();
        for(Article article : articles){
            System.out.println(article);
        }
    }

}

多對多關係測試代碼測試

相關文章
相關標籤/搜索