zoukankan      html  css  js  c++  java
  • MyBatis学习(七)MyBatis关联映射之多对多映射

    对于数据库中的多对多关系建议使用一个中间表来维护关系。

    1.创建四张表,分别为用户表,商品表,订单表,中间表。

     1 DROP TABLE IF EXISTS `t_user`;
     2 CREATE TABLE `t_user` (
     3   `id` int(11) NOT NULL AUTO_INCREMENT,
     4   `username` varchar(18) NOT NULL,
     5   `sex` char(2) NOT NULL,
     6   `age` int(11) NOT NULL,
     7   PRIMARY KEY (`id`)
     8 ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
     9 
    10 -- ----------------------------
    11 -- Records of t_user
    12 -- ----------------------------
    13 INSERT INTO `t_user` VALUES ('1', '张三', '', '12');
    14 INSERT INTO `t_user` VALUES ('2', '王五', '', '12');
    user表
     1 -- ----------------------------
     2 -- Table structure for `t_article`
     3 -- ----------------------------
     4 DROP TABLE IF EXISTS `t_article`;
     5 CREATE TABLE `t_article` (
     6   `id` int(11) NOT NULL AUTO_INCREMENT,
     7   `name` varchar(255) NOT NULL,
     8   `price` int(11) NOT NULL,
     9   `remark` varchar(255) NOT NULL,
    10   PRIMARY KEY (`id`)
    11 ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
    12 
    13 -- ----------------------------
    14 -- Records of t_article
    15 -- ----------------------------
    16 INSERT INTO `t_article` VALUES ('1', 'java', '100', 'java');
    17 INSERT INTO `t_article` VALUES ('2', 'spring', '100', 'spring');
    商品表
    -- ----------------------------
    -- Table structure for `t_order`
    -- ----------------------------
    DROP TABLE IF EXISTS `t_order`;
    CREATE TABLE `t_order` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `uid` int(11) NOT NULL,
      `total` int(11) NOT NULL,
      PRIMARY KEY (`id`),
      KEY `uid` (`uid`),
      CONSTRAINT `uid` FOREIGN KEY (`uid`) REFERENCES `t_user` (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of t_order
    -- ----------------------------
    INSERT INTO `t_order` VALUES ('1', '1', '100');
    INSERT INTO `t_order` VALUES ('2', '1', '200');
    订单表
    -- ----------------------------
    -- Table structure for `t_item`
    -- ----------------------------
    DROP TABLE IF EXISTS `t_item`;
    CREATE TABLE `t_item` (
      `order_id` int(11) NOT NULL,
      `article_id` int(11) NOT NULL,
      PRIMARY KEY (`order_id`,`article_id`),
      KEY `article_id` (`article_id`),
      CONSTRAINT `article_id` FOREIGN KEY (`article_id`) REFERENCES `t_article` (`id`),
      CONSTRAINT `order_id` FOREIGN KEY (`order_id`) REFERENCES `t_order` (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of t_item
    -- ----------------------------
    INSERT INTO `t_item` VALUES ('1', '1');
    INSERT INTO `t_item` VALUES ('2', '1');
    INSERT INTO `t_item` VALUES ('1', '2');
    中间表

    2.创建一个项目,导入所需的jar包,导入db.perproties、log4j.properties属性文件

    3.编写对应的实体类

    User.java

    public class User {
    
        private Integer id;
        private String username;
        private String sex;
        private Integer age;
        //一个用户可以有多个订单
        private List<Order> orders;
           //省略set、get、toString方法          
    }

    Order.java

    public class Order {
    
        private Integer id;
        private Double total;
        //一个订单对应一个用户
        private User user;
        //一个订单可以有多个商品
        private List<Article> articles;
        //省略set、get、toString方法
    }

    Article.java

    public class Article {
    
        private Integer id;
        private String name;
        private Double price;
        private String remark;
        //一种商品可以出现在多个订单中
        private List<Order> orders;
    //省略get、set、toString方法
    }

    4.编写SQL映射文件

    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">
    <mapper namespace="com.dj.mapper.OrderMapper">
        <resultMap type="com.dj.domain.Order" id="orderResultMapper">
            <id property="id" column="oid"/>
            <result property="total" column="total"/>
            <!-- 多对一关联映射 -->
            <association property="user" javaType="com.dj.domain.User">
                <id property="id" column="id"/>
                <result property="username" column="username"/>
                <result property="sex" column="sex"/>
                <result property="age" column="age"/>
            </association>
            <!-- 多对多映射 -->
            <!-- 使用查询到的column属性oid的值作为参数执行selectArticleByOrderId -->
            <collection property="articles" column="oid" fetchType="lazy"
                javaType="ArrayList" ofType="com.dj.domain.Article" 
                select="com.dj.mapper.ArticleMapper.selectArticleByOrderId"> 
                <id property="id" column="id"/>
                <result property="name" column="name"/>
                <result property="price" column="price"/>
                <result property="remark" column="remark"/>
            </collection>
        </resultMap>
        <!-- 查询结果有两个id列,所以把order的id取一个别名oid -->
        <select id="selectOrderById" parameterType="int" resultMap="orderResultMapper">
            select u.*,o.id as oid ,o.total     
            from t_user u,t_order o
            where u.id=o.uid and o.id=#{id}
        </select>
    </mapper>

    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">
    <mapper namespace="com.dj.mapper.ArticleMapper">
        <select id="selectArticleByOrderId" parameterType="int"
            resultType="com.dj.domain.Article">
                select * from t_article where id in(
                    select article_id from t_item where order_id=#{id}
                )
                </select>
    </mapper>

    5.mapper接口对象

    public interface OrderMapper {
    Order selectOrderById(int id);
    }

    6.测试类

    public class SelectOrderTest {
        public static void main(String[] args) throws Exception {
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession session = factory.openSession();
            //获得接口的代理对象
            OrderMapper om = session.getMapper(OrderMapper.class);
            Order order = om.selectOrderById(1);
            System.out.println(order);
            User user = order.getUser();
            System.out.println(user);
            List<Article> articles = order.getArticles();
            for (Article article : articles) {
                System.out.println(article);    
            }  
        }
    }

      流程:

      得到一个OrderMapper接口的代理对象,调用里面的selectOrderById(int id)方法,找到OrderMapper.xml里面 id为selectOrderById的select属性,返回的是一个resultMap,找到这个resultMap,这个resultMap返回的是一个Order类型。

      执行id为selecOrderById的select属性里面的SQL语句结果如下图

      

      然后将查询到的数据中的用户信息装载到Order对象的user属性中,将查询到column属性的oid的值作为参数,执行ArticleMapper.xml里面的selectArticleByOrderId查询订单中的商品,将查询到的商品数据封装到Order对象的articles对象当中。

      结果如图所示:

    测试成功!

  • 相关阅读:
    这鸡汤、真香
    linux 编译安装python并且安装虚拟环境工具
    前端数据删除
    前后端分离DRF项目初始化
    ubuntu 安装nginx docker
    ubuntu安装vue
    虚拟环境安装
    sql语句优化
    Python之网络编程 进程 线程 协程
    Python之网络编程 文件上传 基于udp的协议的socket socketsever同时接收多方消息
  • 原文地址:https://www.cnblogs.com/dj-blog/p/7568562.html
Copyright © 2011-2022 走看看