• mybatis关联映射多对多


    项目开发中,多对多关系也是非常常见的关系

    在数据库中创建表的脚本
    table.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','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.java

    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.java

    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.xml

    <?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.xml

    <?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.xml

    <?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>
    

    测试代码

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

    多对多关系测试代码

  • 相关阅读:
    要求两个条件都为假时,执行某些操作
    Celery + RabbitMq 示意图
    关于消息队列的好文章
    django related_name, on_delete
    Celery 图,[转]
    django model 中 meta子类详解
    django 自定义app
    python __dict__
    Python SQLAlchemy基本操作和常用技巧(包含大量实例,非常好)【转】
    scala private
  • 原文地址:https://www.cnblogs.com/haizhilangzi/p/11055450.html
Copyright © 2020-2023  润新知