精华内容
下载资源
问答
  • 26.Django实现关系(一对多,一对一,多对多))

    千次阅读 多人点赞 2021-08-30 17:06:26
    关系实现: 实践: (1)模型的定义(models.py文件): class Department(models.Model): """ 学院表 """ d_id = models.AutoField(primary_key=True) d_name = models.CharField(max_length=30) def ...

    表关系的实现:

    在这里插入图片描述

    实践实现:

    在这里插入图片描述

    (1)模型的定义:

    (models.py文件)

    from django.db import models
    
    # Create your models here.
    
    class Department(models.Model):
        """
        学院表
        """
        d_id = models.AutoField(primary_key=True)
        d_name = models.CharField(max_length=30)
    
        def __str__(self):
            return "Department<d_id=%s,d_name=%s>"%(self.d_id,self.d_name)
    
    
    class Student(models.Model):
        """
        学生表
        """
        s_id = models.AutoField(primary_key=True)
        s_name = models.CharField(max_length=30)
        # 外键实现一对多。  on_delete级联删除。   参数CASCADE的意思是如果对应的学院被删除了,那么对应的学院下面的学生数据也跟着删除!
        department = models.ForeignKey("Department",on_delete=models.CASCADE)       #通过外键实现学生表和学院表之间的多对一关系!
        # Django的ORM模型使得我们实现多对多不需要再建一个中间表,而之间使用.ManyToMany()方法建字段名即可自动生成!
        course = models.ManyToManyField("Course")                                   #通过.ManyToMany()方法实现课程表和学生表之间的多对多关系
    
        def __str__(self):
            return "Student<s_id=%s,s_name=%s>"%(self.s_id,self.s_name)
    
    
    class Course(models.Model):
        """
        课程表
        """
        c_id = models.AutoField(primary_key=True)
        c_name = models.CharField(max_length=30)
    
        def __str__(self):
            return "Course<c_id=%s,c_name=%s>" % (self.c_id, self.c_name)
    
    
    class Stu_detail(models.Model):
        """
        学生详情表
        """
        #Student代表外键的意思; OneToOneField()代表唯一。外键加唯一实现一对一的关系。   
        Student = models.OneToOneField("Student",on_delete=models.CASCADE)       #通过外键加唯一实现学生表和学生详情表之间的一对一关系!
        age = models.IntegerField()
        phone = models.CharField(max_length=11)
    
        def __str__(self):
            return "Stu_detail<age=%s,phone=%s>" % (self.age, self.phone)
    

    (2)切记:因为我们添加了一个新模型,因此需要再次迁移数据库。

    过程:
    修改models.py,执行命令makemigrations music,再执行命令migrate music。
    (不要嫌弃我一遍又一遍的说哦)

    (3)数据库中查看咱的表:

    在数据库我们能看到5张表,其中多对多关系的ManyToManyField方法自动生成了Student和Course表的中间表music_student_course!!!

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    ❤️可以扫码关注本人公众号——任何问题都可在公众号提问(定时有专人解答);并且不定时更新干货文。欢迎关注哦!❤️

    请添加图片描述

    展开全文
  • SQL实现一对多、多对多建表与查询

    千次阅读 2021-03-01 17:11:40
    1 一对多、多对多、自关联多对多、自关联一对多场景描述 之前在做网页开发的时候一直用Sqlalchemy来操作数据库,当我用到自关联多对多和自关联一对多的时候,sqlalchemy的配置会有一些辅助的参数,配置起来很麻烦,...

    1 一对多、多对多、自关联多对多、自关联一对多场景描述

    之前在做网页开发的时候一直用Sqlalchemy来操作数据库,当我用到自关联多对多和自关联一对多的时候,sqlalchemy的配置会有一些辅助的参数,配置起来很麻烦,灵机一动我就想了一下,为什么不能直接写sql呢!!!虽然sql语句写起来不是很方便,但是sql才是各种ORM框架的基本,话不多说,开搞

    1.1 概念

    本节内容是自己对于数据库表直接关系的一些个人理解,非官方语言描述,都是大白话
    
    • 一对多关系:
    生活中有很多一对多关系的实例,比如一个教师内有n个上课的学生,教师是一方,学生是多方
    工作中每个职位的多名员工,职位是一方,同属这个职位的员工是多方
    项目开发中可能会遇到一些权限的划分,权限规则role 和 同一个role下面的user也是一个一对多的关系
    
    • 多对多关系:
    学生选课系统,所选的课程与选课的学生就是一个多对多关系,多对多关系不能通过主键与外键的关联实现,
    必须建一个三方表,三方表中存放两个关系表的主键,将一个多对多的关系转换成两个一对多的关系。
    在第三张表中通过外键关联另外两张表的主键
    
    • 自关联一对多关系:
    新闻网站、社交网站的评论系统就是一个自关联的一对多关系,一条评论可以有n条子评论,
    但是一条子评论只能有一条父评论
    
    • 自关联多对多关系:
    典型的自关联多对多是用户关注表,比如微博、等社交软件,用户表之间会存在自关联多对多关系,
    一个用户可以有n个粉丝,同样一个用户也可以被N个用户关注
    

    1.2 创建表格& 插入数据

    • 一对多关系:
    # 1:role表 M:user表
    # 新建roles表 
    create table roles(
    	id int primary key auto_increment,
    	name varchar(10) unique not null
    )charset=utf8; 
    # 插入一些测试数据
    insert into roles (`name`) values ("admin"),("other");
    # 新建users表
    CREATE TABLE `test`.`users`  (
      `id` int(0) NOT NULL AUTO_INCREMENT,
      `uname` varchar(255) NULL,
      `role_id` int(0) NULL,
      PRIMARY KEY (`id`),
      CONSTRAINT `role_id` FOREIGN KEY (`role_id`) REFERENCES `test`.`roles` (`id`)
    );
    # 插入一些测试数据
    insert into users (`uname`,`r_id`) values ("张三",1),("里斯",2),("王刚",2),
    ("金鹏展翅",2),("大鸟飞天",2),("花花公子",2),("犯上作乱",2),("天兵天将",2),("非你莫属",2)
    
    
    • 多对多关系:
    # 用户表、兴趣爱好表、user_habbit_table
    # 新建兴趣爱好表
    create table habbits (
    	id int primary key auto_increment,
    	hname varchar(30)
    )charset=utf8;
    # 插入一些测试数据
    insert into habbits (hname) 
    values ("打篮球"),("打台球"),("踢足球"),("乒乓球"),("橄榄球"),("羽毛球"),("网球")
    
    # 新建用户与爱好关联表
    CREATE TABLE `test`.`union_table`  (
      `id` int(0) NOT NULL AUTO_INCREMENT,
      `user_id` int(0) NULL,
      `h_id` int(0) NULL,
      PRIMARY KEY (`id`),
      CONSTRAINT `user_id` FOREIGN KEY (`user_id`) REFERENCES `test`.`users` (`id`),
      CONSTRAINT `habbit_id` FOREIGN KEY (`h_id`) REFERENCES `test`.`habbits` (`id`)
    );
    # 插入测试数据
    insert into union_table (user_id,h_id) values (1,1),(1,2),(1,5),(2,4),(2,3),(2,7),(3,1),(3,2),(3,3),(3,6)
    
    • 自关联一对多关系:
    # 创建评论表
    create table comments (
    	id int primary key auto_increment,
    	content varchar(200),
    	parent_id int,
    	ctime TIMESTAMP default now()
    ) charset =utf8;
    # 插入测试数据
    insert into comments (content,parent_id) values ("今天天气真好",NULL),
    ("我觉得文章写的不错",NULL),
    ("为什么今天库里投篮不准了",NULL),
    ("明天上学的路上我要买一张报纸",NULL),
    ("你是一个乖宝宝",NULL)
    
    # 添加子评论
    insert into comments (content,parent_id) values ("天龙八部好看",1),
    ("乔丹的篮球打的很棒",2),
    ("明天是周末,可以出去玩",3),
    ("想想明天的生活也会很好",4),
    ("今天吃了三个包子",5)
    
    
    insert into comments (content,parent_id) values ("潘金莲怒打西门庆",1),
    ("吕布死后,关羽见到谁都是匹夫",2),
    ("当你慢慢学会设计数据路的时候",3),
    ("天气虽然很好但是我也不想出去打球",4),
    ("明明就是一个大骗子非要说自己是好人",5)
    
    • 自关联多对多关系:
    # 自关联一对多可以在一张表中表现出关系,但是自关联多对多需要借助一张follows表才能表现结构
    # 新建一张follows表
    CREATE TABLE `test`.`Untitled`  (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `follower_id` int(11) NULL DEFAULT NULL,
      `followed_id` int(11) NULL DEFAULT NULL,
      PRIMARY KEY (`id`) USING BTREE,
      INDEX `follower_id`(`follower_id`) USING BTREE,
      INDEX `followed_id`(`followed_id`) USING BTREE,
      CONSTRAINT `followed_id` FOREIGN KEY (`followed_id`) REFERENCES `test`.`users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
      CONSTRAINT `follower_id` FOREIGN KEY (`follower_id`) REFERENCES `test`.`users` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
    ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
    # 插入一些测试数据
    insert into follows (follower_id,followed_id) 
    values (1,2),(1,3),(1,4),
    (2,5),(2,7),(2,1),
    (3,6),(3,1),(3,2),
    (4,1),(4,2),(4,6)
    

    1.3 查询数据

    • 一对多查询
    #  查询某一种角色的所有用户
    select * from users 
    where r_id = (
    select id from roles where name = "other"
    )
    
    • 多对多查询
    # 查询某个人的所有爱好
    select * from habbits
    where id in (
    select h_id from union_table where user_id = (
    select id from users where uname like "张三"))
    
    # 查询某一种爱好有哪些用户喜欢
    select * from users 
    where id in (
    select user_id from union_table where h_id = (
    select id from habbits where hname like "打篮球"
    )
    )
    
    
    • 自关联一对多查询
    # 查询一级评论
    select * from comments 
    where parent_id is null
    
    # 查询一个父级评论的所有子评论
    select * from comments
    where parent_id = 1
    
    • 自关联多对多查询
    # 查询一个用户的所有粉丝
    select u.id,u.uname from follows as f 
    inner join users as u on u.id = f.follower_id
    where f.followed_id = (
    select id from users where uname = "张三"
    )
    

    1.4 总结

    本文用的数据库是mysql
    后续会写一个详细的sqlalchemy处理关系表的文章,比对一下两种方法的优劣势

    展开全文
  • 一对多关系多对关系 多对关系 2、多表关联关系实现 可以通过添加外键来实现。 2.1 一对一 主键共享 两张表的主键,建立外键约束。 -- 建立一对一关系:一夫一妻 mysql> create table husband( -> ...

    1、多表关联关系的分类

    既然数据库是存储项目中的数据的,项目中的数据主要是类型创建的对象,项目中类型和类型之间是有关系的,数据库中怎么体现出来?
    不论是生活中,还是抽象出来的软件中,描述生活中的多个类型之间的关系,总结如下:

    • 一对一关系
    • 一对多关系、多对一关系
    • 多对多关系

    2、多表关联关系的实现

    可以通过添加外键来实现。

    2.1 一对一
    • 主键共享
      两张表的主键,建立外键约束。
    -- 建立一对一关系:一夫一妻
    mysql> create table husband(
        -> hid int primary key auto_increment comment '丈夫编号',
        -> hname varchar(20) not null comment '丈夫姓名'
        -> );
    Query OK, 0 rows affected (0.03 sec)
    
    mysql> create table wife(
        -> wid int primary key auto_increment comment '妻子编号',
        -> wname varchar(20) not null comment '妻子姓名'
        -> ,foreign key(wid) references husband(hid)
        -> );
    Query OK, 0 rows affected (0.02 sec)
    
    -- 测试数据
    mysql> insert into husband(hname) values('邓超');
    Query OK, 1 row affected (0.01 sec)
    mysql> insert into husband(hname) values('张若昀');
    Query OK, 1 row affected (0.01 sec)
    mysql> insert into wife(wname) values('孙俪');
    Query OK, 1 row affected (0.01 sec)
    mysql> insert into wife(wname) values('唐艺昕');
    Query OK, 1 row affected (0.00 sec)
    mysql> insert into wife(wname) values('孙怡');
    ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`power`.`wife`, CONSTRAINT `wife_ibfk_1` FOREIGN KEY (`wid`) REFERENCES `husband` (`hid`))
    
    • 外键唯一
      子表添加一个新的字段并给该字段添加唯一约束和外键约束,然后关联父表主键字段。
    -- 建立一对一关系:一夫一妻
    mysql> create table wife(
        -> wid int primary key auto_increment comment '妻子编号',
        -> wname varchar(20) not null comment '妻子姓名',
        -> w_hid int unique, 
        -> foreign key (w_hid) references husband(hid));
    Query OK, 0 rows affected (0.03 sec)
    -- 测试数据:可以不按顺序插入,只要丈夫编号对应即可
    mysql> insert into wife(wname,w_hid) values('唐艺昕',2);
    Query OK, 1 row affected (0.01 sec)
    
    mysql> insert into wife(wname,w_hid) values('孙俪',1);
    Query OK, 1 row affected (0.01 sec)
    
    mysql> select * from wife;
    +-----+--------+-------+
    | wid | wname  | w_hid |
    +-----+--------+-------+
    |   1 | 唐艺昕 |     2 |
    |   2 | 孙俪   |     1 |
    +-----+--------+-------+
    2 rows in set (0.00 sec)
    
    2.2 一对多
    • 外键添加在多的一方,关联一的主键。
    -- 建立一对多关系:一个学生有多门课程
    mysql> create table stu(
        -> id int primary key auto_increment,
        -> sname  varchar(20) not null);
    Query OK, 0 rows affected (0.02 sec)
    mysql> create table course(
        -> id int primary key auto_increment,
        -> cname varchar(50) not null,
        -> score int default 0,
        -> sid int,
        -> foreign key (sid) references stu(id)
        -> );
    Query OK, 0 rows affected (0.03 sec)
    -- 测试数据
    mysql> insert into stu (sname) values('zhangsan');
    Query OK, 1 row affected (0.01 sec)
    
    mysql> insert into course(cname,score,sid) values('math',98,1);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> insert into course(cname,score,sid) values('chinese',99,1);
    Query OK, 1 row affected (0.01 sec)
    
    mysql> insert into course(cname,score,sid) values('english',111,1);
    Query OK, 1 row affected (0.01 sec)
    
    mysql> select * from course;
    +----+---------+-------+------+
    | id | cname   | score | sid  |
    +----+---------+-------+------+
    |  1 | math    |    98 |    1 |
    |  2 | chinese |    99 |    1 |
    |  3 | english |   111 |    1 |
    +----+---------+-------+------+
    3 rows in set (0.00 sec)
    
    2.3 多对多
    • 外键:两张表的普通字段,直接建立关联关系(不推荐)
    • 中间表:创建一个中间表,中间表的两个普通字段分别关联另两张表的主键。
    -- 建立多对多关系:一个学生有多个老师,一个老师有多个学生
    -- 我这里之前已经创建过学生表
    mysql> desc stu;
    +-------+-------------+------+-----+---------+----------------+
    | Field | Type        | Null | Key | Default | Extra          |
    +-------+-------------+------+-----+---------+----------------+
    | id    | int         | NO   | PRI | NULL    | auto_increment |
    | sname | varchar(20) | NO   |     | NULL    |                |
    +-------+-------------+------+-----+---------+----------------+
    2 rows in set (0.01 sec)
    
    mysql> create table teacher(
        -> tid int primary key auto_increment,
        -> tname varchar(10));
    Query OK, 0 rows affected (0.03 sec)
    
    -- 中间表
    mysql>  create table stu_tea(
        -> id int primary key auto_increment,
        -> sid int,
        -> tid int,
        -> foreign key(sid) references stu(sid),
        -> foreign key(tid) references teacher(tid));
    Query OK, 0 rows affected (0.02 sec)
    

    总结

    • 中小型项目中的数据表,为了避免垃圾数据的出现,强制添加外键约束
      项目规模和项目本身对于数据的安全性约束较少,容易产生垃圾数据
    • 大型项目并且对数据查询性能较高的数据表,约定的方式关联(不额外添加外键)
      项目规模和项目本身对于数据安全性约束较多,不容易产生垃圾数据
      不需要额外添加外键提高查询数据时的性能消耗
    展开全文
  • 多对多关联关系 本篇博客是在前四篇的基础上在进行进一步开发的 (四) mybatis集成ehcache&&mybatis集成redis_m0_58525944的博客-CSDN博客 (三) mybatis整合spring&&spring整合...

    今日目标:

    1. 一对多关联关系
    2. 多对多关联关系

    本篇博客是在前四篇的基础上在进行进一步开发的

    (四)mybatis集成ehcache&&mybatis集成redis_m0_58525944的博客-CSDN博客
    (三)mybatis整合spring&&spring整合mybatis分页插件_m0_58525944的博客-CSDN博客
    (二)mybatis之动态sql&&模糊查询&&结果集处理&&mybatis分页&&特殊字符处理_m0_58525944的博客-CSDN博客
    (一)MyBatis入门(逆向生成&&增删改查案例)_m0_58525944的博客-CSDN博客

    目录结构:

     准备工作(使用逆向生成工具生成mapper及model)数据库中所需的数据库表,五张表

    使用逆向生成工具生成mapper和model

            <table schema="" tableName="t_hibernate_order" domainObjectName="Order"
                   enableCountByExample="false" enableDeleteByExample="false"
                   enableSelectByExample="false" enableUpdateByExample="false">
            </table>
            <table schema="" tableName="t_hibernate_order_item" domainObjectName="OrderItem"
                   enableCountByExample="false" enableDeleteByExample="false"
                   enableSelectByExample="false" enableUpdateByExample="false">
            </table>
            <table schema="" tableName="t_hibernate_book" domainObjectName="Hbook"
                   enableCountByExample="false" enableDeleteByExample="false"
                   enableSelectByExample="false" enableUpdateByExample="false">
            </table>
            <table schema="" tableName="t_hibernate_category" domainObjectName="Category"
                   enableCountByExample="false" enableDeleteByExample="false"
                   enableSelectByExample="false" enableUpdateByExample="false">
            </table>
            <table schema="" tableName="t_hibernate_book_category" domainObjectName="HbookCategory"
                   enableCountByExample="false" enableDeleteByExample="false"
                   enableSelectByExample="false" enableUpdateByExample="false">
            </table>

    一对多关联关系

    利用order和orderitem两个表,来展示一对多的关联关系,一个订单中有多个订单项,多个订单项对应一个订单

    1  建立两个vo类来存储一对多的关联属性(OrderVo:订单一方,OrderItemVo:订单项多方)

    orderVo

    package com.lgs.vo;
    import com.lgs.model.Order;
    import com.lgs.model.OrderItem;
    
    import java.util.ArrayList;
    import java.util.List;
    
    //vo类是为了不破坏本身的类的封装性,跟数据库中的字段一一映射的
    public class OrderVo extends Order {
    //  一个订单中有多个订单项,所以用集合
        private List<OrderItem> orderItems = new ArrayList<>();
    
        public List<OrderItem> getOrderItems() {
            return orderItems;
        }
        public void setOrderItems(List<OrderItem> orderItems) {
            this.orderItems = orderItems;
        }
    }

    OrderItemVo 

    package com.lgs.vo;
    import com.lgs.model.Order;
    import com.lgs.model.OrderItem;
    
    public class OrderItemVo extends OrderItem {
    //  一个订单项对应一个订单
        private Order order;
    
        public Order getOrder() {
            return order;
        }
        public void setOrder(Order order) {
            this.order = order;
        }
    
    }

     2  分别在OrderMapper.xml、OrderItemMapper.xml中添加映射关系配置  和  连表查,所以需要两边都要添加一个dao方法及配置sql语句

    OrderMapper.xml

      <!--映射-->
      <!--property:实体类的属性 column:表字段-->
      <resultMap id="OrderVoMap" type="com.lgs.vo.OrderVo" >
        <result property="orderId" column="order_id"></result>
        <result property="orderNo" column="order_no"></result>
        <collection property="orderItems" ofType="com.lgs.model.OrderItem">
          <result property="orderItemId" column="order_item_id"/>
          <result property="oid" column="oid"></result>
          <result property="productId" column="product_id"></result>
          <result property="quantity" column="quantity"></result>
        </collection>
      </resultMap>
    
      <!--查询语句-->
      <select id="queryOrderVoByOrderId" resultMap="OrderVoMap" parameterType="java.lang.Integer">
        select * from t_hibernate_order o,t_hibernate_order_item oi
        where o.order_id = oi.oid
          and o.order_id = #{orderId}
      </select>

    OrderItemMapper.xml

    <!--多方的配置-->  
    <resultMap id="OrderVoMap" type="com.lgs.vo.OrderItemVo" >
        <result property="orderItemId" column="order_item_id"></result>
        <result property="oid" column="oid"></result>
        <result property="productId" column="product_id"></result>
        <result property="quantity" column="quantity"></result>
        <association property="order" javaType="com.lgs.model.Order">
          <result property="orderId" column="order_id"></result>
          <result property="orderNo" column="order_no"></result>
        </association>
      </resultMap>
    
      <select id="queryOrderItemVoByOrderItemId" resultMap="OrderVoMap" parameterType="java.lang.Integer">
        select * from t_hibernate_order o,t_hibernate_order_item oi
        where o.order_id = oi.oid
          and oi.order_item_id = #{orderItemId}
      </select>

    2 OrderMapper.java: 和 OrderItemMapper.java:的配置

    OrderMapper.java:

    OrderVo queryOrderVoByOrderId(@Param("orderId") Integer orderId);

    OrderItemMapper.java:

    OrderItemVo queryOrderItemVoByOrderItemId(@Param("orderItemId") Integer orderItemId);

    3  建立One2ManyService.java类:

    package com.lgs.service;
    import com.lgs.vo.OrderItemVo;
    import com.lgs.vo.OrderVo;
    public interface One2ManyService {
        //通过查询订单关联查询出对应的订单项信息
        OrderVo queryOrderVoByOrderId(Integer orderId);
    
        //查询订单项,关联查询出所属的订单
        OrderItemVo queryOrderItemVoByOrderItemId(Integer OrderItemId);
    }

    4  建立One2ManyServiceImpl.java实现类:

    package com.lgs.service.impl;
    import com.lgs.mapper.OrderItemMapper;
    import com.lgs.mapper.OrderMapper;
    import com.lgs.service.One2ManyService;
    import com.lgs.vo.OrderItemVo;
    import com.lgs.vo.OrderVo;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service
    public class One2ManyServiceImpl implements One2ManyService {
    
        @Autowired
        private OrderMapper orderMapper;
        @Autowired
        private OrderItemMapper orderItemMapper;
     
        @Override
        public OrderVo queryOrderVoByOrderId(Integer orderId) {
            return orderMapper.queryOrderVoByOrderId(orderId);
        }
        @Override
        public OrderItemVo queryOrderItemVoByOrderItemId(Integer OrderItemId) {
            return orderItemMapper.queryOrderItemVoByOrderItemId(OrderItemId);
        }
    }

    5  测试

    package com.lgs.service.impl;
    import com.lgs.model.OrderItem;
    import com.lgs.service.One2ManyService;
    import com.lgs.vo.OrderItemVo;
    import com.lgs.vo.OrderVo;
    import junit.framework.TestCase;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations={"classpath:applicationContext.xml"})
    public class One2ManyServiceImplTest extends TestCase {
    
        @Autowired
        private One2ManyService one2ManyService;
        @Test
        public void queryOrderVoByOrderId() {
            OrderVo orderVo = this.one2ManyService.queryOrderVoByOrderId(10);
            System.out.println(orderVo);
            for (OrderItem orderItem : orderVo.getOrderItems()) {
                System.out.println(orderItem);
            }
        }
        @Test
        public void queryOrderItemVoByOrderItemId() {
            OrderItemVo orderItemVo = this.one2ManyService.queryOrderItemVoByOrderItemId(49);
            System.out.println(orderItemVo);
            System.out.println(orderItemVo.getOrder());
        }
    
    }

     通过查询订单关联查询出对应的订单项信息

    查询订单项, 关联所属的订单

    多对多关联关系

    前面介绍了一对多的关系,那么接下来多对多的映射关系就简单多了,用两个connection配置
    为展示多对多的关联关系,利用一本书对应多种类别,一种类别对应多本书的概念

    1  建立两个vo类来存储多对多的关联属性(HBookVo:书籍,CategoryVo:书籍种类 都是多方,所以都用集合)

    HBookVo.java:

    package com.lgs.vo;
    import com.lgs.model.Category;
    import com.lgs.model.Hbook;
    import java.util.ArrayList;
    import java.util.List;
    public class HbookVo extends Hbook {
        private List<Category> categories = new ArrayList<>();
    
        public List<Category> getCategories() {
            return categories;
        }
        public void setCategories(List<Category> categories) {
            this.categories = categories;
        }
    }

    CategoryVo.java:

    package com.lgs.vo;
    import com.lgs.model.Category;
    import com.lgs.model.Hbook;
    import java.util.ArrayList;
    import java.util.List;
    public class CategoryVo extends Category {
        private List<Hbook> hbooks = new ArrayList<>();
    
        public List<Hbook> getHbooks() {
            return hbooks;
        }
        public void setHbooks(List<Hbook> hbooks) {
            this.hbooks = hbooks;
        }
    }

    2  在HBookCategoryMapper.xml中添加映射关系配置  和  连表查,所以需要添加一个dao方法及配置sql语句

    HBookCategoryMapper.xml(配置两个多对多和连表查的SQL):

      <resultMap id="HbookVoMap" type="com.lgs.vo.HbookVo">
        <result property="bookId" column="book_id"></result>
        <result property="bookName" column="book_name"></result>
        <collection property="categories" ofType="com.lgs.model.Category">
          <result property="categoryId" column="category_id"></result>
          <result property="categoryName" column="category_name"></result>
        </collection>
      </resultMap>
      <resultMap id="CategoryVoMap" type="com.lgs.vo.CategoryVo">
        <result property="categoryId" column="category_id"></result>
        <result property="categoryName" column="category_name"></result>
        <collection property="hbooks" ofType="com.lgs.model.Hbook">
          <result property="bookId" column="book_id"></result>
          <result property="bookName" column="book_name"></result>
        </collection>
      </resultMap>
    
      <select id="queryByBookId" resultMap="HbookVoMap" parameterType="java.lang.Integer">
        select * from t_hibernate_book b,t_hibernate_book_category bc,t_hibernate_category c
        where b.book_id = bc.bid and bc.cid = c.category_id and b.book_id = #{bookId}
      </select>
      <select id="queryByCid" resultMap="CategoryVoMap" parameterType="java.lang.Integer">
        select * from t_hibernate_book b,t_hibernate_book_category bc,t_hibernate_category c
        where b.book_id = bc.bid and bc.cid = c.category_id and c.category_id=#{cid}
      </select>

    3  HBookCategoryMapper.java(添加两个查询方法):

        HbookVo queryByBookId(@Param("bookId") Integer bookId);
    
        CategoryVo queryByCid(@Param("cid") Integer cid);

    4  建立Many2ManyService.java类:

    package com.lgs.service;
    import com.lgs.vo.CategoryVo;
    import com.lgs.vo.HbookVo;
    import org.apache.ibatis.annotations.Param;
    public interface Many2ManyService {
        HbookVo queryByBookId(Integer bookId);
    
        CategoryVo queryByCid(Integer cid);
    }

    5  建立Many2ManyServiceImpl.java实现类:

    package com.lgs.service.impl;
    
    import com.lgs.mapper.HbookCategoryMapper;
    import com.lgs.service.Many2ManyService;
    import com.lgs.vo.CategoryVo;
    import com.lgs.vo.HbookVo;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service
    public class Many2ManyServiceImpl implements Many2ManyService {
    
        @Autowired
        private HbookCategoryMapper hbookCategoryMapper;
    
        @Override
        public HbookVo queryByBookId(Integer bookId) {
            return hbookCategoryMapper.queryByBookId(bookId);
        }
        @Override
        public CategoryVo queryByCid(Integer cid) {
            return hbookCategoryMapper.queryByCid(cid);
        }
    
    }

    6  测试

    package com.lgs.service.impl;
    import com.lgs.model.Category;
    import com.lgs.model.Hbook;
    import com.lgs.service.Many2ManyService;
    import com.lgs.vo.CategoryVo;
    import com.lgs.vo.HbookVo;
    import junit.framework.TestCase;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations={"classpath:applicationContext.xml"})
    public class Many2ManyServiceImplTest extends TestCase {
        @Autowired
        private Many2ManyService many2ManyService;
    
        @Test
        public void queryByBookId() {
            HbookVo hbookVo = many2ManyService.queryByBookId(8);
            System.out.println(hbookVo);
            for (Category category : hbookVo.getCategories()) {
                System.out.println(category);
            }
        }
        @Test
        public void queryByCid() {
            CategoryVo categoryVo = many2ManyService.queryByCid(8);
            System.out.println(categoryVo);
            for (Hbook hbook : categoryVo.getHbooks()) {
                System.out.println(hbook);
            }
        }
    }

    根据书的id查看书有哪些类别

    根据类别查询此书类别的书还有哪些

     OK!到这就结束了,希望能帮到你!!!

    展开全文
  • 1.一对多查询:关键点在于collection标签 一对多查询是指在查询一方对象的时候,同时将其所关联的多方对象也都查询出来。 一个班级有个学生,一个学生只属于一个班级。 数据库student表里有个字段classno是外键,...
  • 字段like个条件(or关系)简写

    千次阅读 2021-01-27 07:33:17
    sql关于一个字段同时满足条件判断来筛选查询 表所有数据 查询userName为abc或xyz的 以下为本菜鸟项目中遇到的问题: 背景: /** * wangjie 180629 * * 学生需要查询四种可能的消息 * 1.班级管理员发 ... oracle...
  • 前端实现人员关系图谱

    千次阅读 多人点赞 2021-09-21 17:26:18
    当时阻碍我前进的就是如何实现族谱的连线以及根据数据渲染它们的对应关系,后来在逛博客的过程中,发现了antdesign的charts图表组件。利用这个组件,如果可以进行一些改造,可能就可以实现族谱的关系图。
  • Mybatis的表关联查询(一一、一对多

    千次阅读 多人点赞 2021-02-12 21:55:24
    Mybatis的多表关联查询mybatis中的多表查询数据库准备项目目录一对一查询(多对一)方式一(通过Accunt的子类方式查询--不常用)定义账户信息的实体类编写 Sql 语句定义 AccountUser 类定义账户的持久层 Dao 接口定义 ...
  • Mybatis入门-基于注解实现单表、表的增删改查

    千次阅读 多人点赞 2021-04-05 12:07:54
    Mybatis入门—基于注解实现单表、表的增删改查。需要我们记住一些注解@select @insert @update @delete @result @results @results @resuleMap.记注解练习。加油
  • Mybatis的多表关联查询(多对多)

    千次阅读 多人点赞 2021-02-12 23:46:03
    Mybatis的多表关联查询(多对多)项目目录结构实现 Role 到 User 多对多业务要求用户与角色的关系模型编写角色实体类编写 Role 持久层接口实现的 SQL 语句编写映射文件测试代码实现 User 到 Role 的多对多业务要求...
  • 一关联保存: ps:这里都是拿工作中的项目做例子,所有不会有完整的业务代码,提供思路 说明: 留言状态表: 记录用户的留言信息,如留言人openid,留言时间等…(主表) 用户留言内容表: 记录用户的留言内容,id与状态表一...
  • 采用DataX实现多表增量数据同步

    千次阅读 2020-12-21 14:39:17
    DataX用来做批量数据迁移很适合,能够保证数据的一致性,性能也很好,结合时间戳字段,用来实现数据定时增量同步也是可以的,如每分钟或每5分钟增量同步一次数据。用DataX这个方案做增量同步要求每个表带一个时间戳...
  • python 如何把很空格变成一个空格?现在小编的日志...是纯粹的空格还是制表位?你告诉小编,小编给你写一个。python中,如何将字符串中个空格分隔的修改为一例如,有一个字符串"1 2 3 4 5 6 7",小编想修改成"1,2...
  • 线程的实现方式 实现线程是并发编程中基础中的基础,因为我们必须要先实现线程,才可以继续后续的一系列操作。 基本实现方式 Runable public class ImplementRunable implements Runnable { @Override public ...
  • IDEA一对多查询

    千次阅读 2021-04-12 14:50:28
    上面是映射结果集,因为是查询学生对应的课程一对多关系,在学生表的mapper文件下实现,首先测试好sql语句到idea粘贴,因为查询结果不是只有学生信息还要有课程信息,在这里引入课程类如上图 在学生实体类中写好...
  • 在Python中,实现多分支选择结构的最佳方法是答:if-elif-else绘制建筑平面图时,被剖切的墙用 线绘制,定位轴线用 线绘制答:粗实 细点画智慧职教: 下列关于书写住院病历的叙述不正确的是( )。答:住院病畜一般应于...
  • 源码对比 Thread源码 Thread其实是一个类,并且这个类实现了Runnable接口。...实现多线程的方式对比 Thread 创建自己的线程类MyThread,继承Thread,重写run方法 public class Mythread extends
  • python进程线程,个程序同时运行

    千次阅读 多人点赞 2021-04-08 13:47:15
    任务的实现可以用进程和线程来实现 进程—> 线程----> 任务应用 进程操作 比如下载个文件, 利用cpu 资源 提高效率 任务: 同一时间执行个任务, 比如windows操作系统 执行方式有两种( 表现形式 ) ...
  • navicat怎么看表关系

    千次阅读 2021-01-25 20:03:45
    今天需要分析一个数据库,然后想看看各个表之间的关系,所以需要查看表与表之间的关系图,专业术语叫做ER关系图。默认情况下,Navicat显示的界面是这样的:软件将表当做一个对象,然后显示了所有的表。仅仅通过这些...
  • 用于多关系数据的图神经网络R-GCNs

    千次阅读 2020-12-30 09:23:34
    讨论如何以关系图卷积网络(R-GCN)的形式扩展GCN层,对多关系数据进行编码。 知识图作为多关系数据 基本图结构包括用于连接节点的无向,无类型和唯一边。 例如,在哲学领域,我们可以定义两个由“苏格拉底”和...
  • 编写程序实现对输入文件的排序 现在有个输入文件,每个文件中的每行内容均为一个整数。要求读取所有文件中的整数,进行升序排序后,输出到一个新的文件中,输出的数据格式为每行两个整数,第一个数字为第二个整数...
  • 多对一:查询所有学生以及他们的老师。 1. resultMap resultMap元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBCResultSets数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的...
  • 图形化界面扫雷(C语言+easyx实现图教学)

    千次阅读 多人点赞 2021-11-07 22:41:37
    //跳出循环 } } 这是头文件中的说明: 看到这,我们明白了,它可能是这样实现的: 这些鼠标信息对应的都有整数值,msg.uMsg得到的也是这些信息对应的值,因此我们可以用switch语句情况分类。 作个假设: WM_...
  • 由于我们没设置外键约束,因此用powerdesigner无法把表之间的关联关系展示出来。由于表数量、时间紧急,大家讨论说晚上可能时间来不及,建议和用户沟通延后一下。 2、冷静分析 然后我沉默了一会,突然灵感闪现,说...
  • 十种方法实现图像数据集降维

    万次阅读 多人点赞 2021-04-15 22:52:28
    本项目将依托于MNIST数据集,手把手实现图像数据集降维。
  • 线程带来的问题 为什么需要线程 其实说白了,时代变了,...Java 中的线程与 CPU 单核执行是一一的,即单个处理器同一时间只能处理一个线程的执行;而 CPU 是通过时间片算法来执行任务的,不同的线程活跃状态不同
  • Mybatis表模型

    千次阅读 2021-11-26 09:13:35
    多表模型分类 一对一:在任意一方建立外键,关联对方的主键。 一对多:在多的一方建立外键,关联一的一方的主键。 多对多:借助中间表,中间表至少两个字段,分别关联两张表的主键。
  • sql实现数据归一化 工作中真实数据因涉及法律责任不便展示,以下为模拟数据。 注:务必看完此文章因为第一种实现存在bug,后边附带解释以及完整代码。 模拟数据: 我们拿三个列实现归一作为举例,n列同理。 ...
  • 如何获取线程执行结果-java

    千次阅读 2021-08-12 16:08:05
    在日常的项目开发中,我们会经常遇到通过线程执行程序并需要返回执行结果的场景,下面我们就获取线程返回结果的几种方式进行一下归纳,并进行简要的分析与总结。 一、Thread.join 在一些简单的应用场景中...
  • Android 8.1 系统网口实现方法 分享一篇本人专利技术,已提交申请,转发请备注,谢谢! 软件开发交流群 基于 Android 8.1 系统下 Ethernet 网口动态获取 IP ,设置 IP 功能的实现方法,通过修改 Android 8.1 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,911,246
精华内容 1,164,498
关键字:

多对多关系怎么实现