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

}

多对多关系测试代码测试

相关文章
相关标签/搜索