一对多的自身关联
数据库中表的关联设计
数据库中表的关联设计数据库中表的关联设计是数据库设计的核心环节之一,它关系到数据的完整性、查询效率以及系统的可扩展性。
在进行数据库表关联设计时,需要遵循一定的原则和方法,以确保数据库结构的合理性和高效性。
本文将深入探讨数据库中表的关联设计,包括关联类型、设计原则、实施步骤以及优化策略等方面。
一、关联类型数据库中的表关联主要分为三种类型:一对一关联(1:1)、一对多关联(1:N)和多对多关联(M:N)。
1. 一对一关联(1:1):指两个表中的记录之间存在一一对应的关系。
例如,一个用户表和一个用户详情表,每个用户都有唯一的详情信息。
在这种关联中,通常将两个表合并为一个表,或者在主表中添加一个唯一的外键列来引用另一个表。
2. 一对多关联(1:N):指一个表中的记录可以与另一个表中的多个记录相关联。
例如,一个部门表可以有多个员工表记录与之关联。
在这种关联中,通常在多的一方添加一个外键列,用于引用一的一方的主键。
3. 多对多关联(M:N):指两个表中的记录都可以与对方表中的多个记录相关联。
例如,学生和课程之间的关系,一个学生可以选修多门课程,一门课程也可以被多个学生选修。
在这种关联中,通常需要引入一个中间表来表示两个表之间的关联关系,中间表包含两个外键列,分别引用两个表的主键。
二、设计原则在进行数据库表关联设计时,需要遵循以下原则:1. 规范化原则:通过数据规范化来消除数据冗余和依赖,确保数据的完整性和一致性。
规范化过程中,将数据分解到多个表中,并定义表之间的关系,以减少数据的重复存储。
2. 完整性原则:确保数据的完整性和准确性。
通过设置主键、外键、唯一约束等数据库对象,来维护数据的完整性。
同时,还需要考虑业务规则和数据校验等方面的需求。
3. 可扩展性原则:数据库设计应具有良好的可扩展性,能够适应未来业务的发展和变化。
在设计过程中,需要预留一定的扩展空间,避免过多的硬编码和固定配置。
4. 性能原则:数据库设计应充分考虑查询性能和数据处理能力。
数据仓库设计与建模的维度表与事实表的一对多关系的设计方法(四)
数据仓库设计与建模的维度表与事实表的一对多关系的设计方法数据仓库是企业用于支持决策和分析的重要工具,而数据仓库的设计与建模是构建一个高效可靠的数据仓库的关键。
在数据仓库的设计中,维度表和事实表是两个重要的概念,维度表用于描述业务对象的特征信息,而事实表用于存储业务指标的数值数据。
本文将探讨维度表与事实表之间的一对多关系的设计方法。
一、维度表与事实表的基本概念在数据仓库的设计过程中,维度表和事实表是两个基本的表结构。
维度表常常包括与业务对象有关的特征属性,例如时间、地理、产品等。
而事实表则存储了度量指标的数值数据,例如销售额、订单数量等。
维度表的每一行代表一个业务对象的一个特定特征,而事实表的每一行则代表某个业务对象的一个特定指标的数值。
维度表与事实表之间通过共享的维度键(surrogate key)建立关联。
二、一对多关系的设计方法在数据仓库的设计中,维度表与事实表之间的关系可以分为一对一、一对多和多对多三种类型。
其中,一对多关系是最常见的情况,即一个维度表与多个事实表建立关联。
下面将介绍一些常用的一对多关系的设计方法。
1. 一对多关系的直接关联一对多关系的最简单的设计方法就是直接在事实表中添加维度表的外键。
例如,在销售事实表中添加产品维度表的主键作为外键,即可建立销售事实表与产品维度表的一对多关系。
这种方法简单直接,但可能导致冗余数据的增加,因为事实表中可能会包含大量重复的维度数据。
2. 一对多关系的分离设计为了避免冗余数据的增加,可以采用分离设计的方法。
在该方法中,维度表和事实表通过中间表进行关联。
中间表包含了维度表和事实表之间的键值对映射关系。
例如,在销售事实表和产品维度表之间添加一个映射表,该表包含了销售事实表中的产品外键和产品维度表中的主键的对应关系。
这样就实现了销售事实表与产品维度表的一对多关系的分离设计,避免了冗余数据。
3. 聚集与层次的设计方法另外一种常用的一对多关系的设计方法是聚集与层次的设计。
类与类之间的关系
类与类之间的关系展开全文一、关联关系1. 单向关联:从一个类中可以访问另一个类的成员,有这个类的引用。
2. 双向关联:两个类可以互相访问,互相有引用。
3. 自身关联:本类中调用自身self or this.4. 多维关联:多个类互相之间有单向关联也有双向关联,还可以有自身关联,多个维度的关联。
5. 一对多关联:一个类有多个类的引用。
6. 多对多关联:多个类互相之间有单向关联也有双向关联。
7. 当一个类的属性保存了对另一个类的一个实例的引用时,就产生了关联。
二、泛化关系:继承与实现1. 在 UML 中, 泛化关系用来表示类与类, 接口与接口之间的继承关系。
更准确的说是不仅有继承关系,还有类和接口的实现关系。
2. 泛化关系包括继承关系和实现关系。
三、聚合关系1. 聚合关联是一种特殊的关联. 它表示类间的关系是整体与部分的关系. 简言之: 关联关系中的一个类描述了一个较大的事物, 它由较小的事物组成.2. 聚合关系中一个大类由多个小类组成,但是没有这个大类,这些小类可以再次聚合成另外一个大类而继续使用,这是与组合关系的区别。
3. 聚合关系是关联关系的一种,是强的关联关系。
4. 聚合是整体和部分之间的关系,例如汽车由引擎、轮胎以及其它零件组成。
5. 聚合关系也是通过成员变量来实现的。
但是,关联关系所涉及的两个类处在同一个层次上,而聚合关系中,两个类处于不同的层次上,一个代表整体,一个代表部分。
6. 通俗的讲:“汽车”有一个引擎和四个轮胎,如果这个“汽车”毁了,它的引擎和轮胎还可以安在别的汽车上。
四、组合关系1. 整件拥有部件的生命周期, 所以整件删除时, 部件一定会跟着删除. 而且, 多个整件不可以同时共享同一个部件。
2. 组合关系中一个大类由多个小类组成,没有这个大类,小类不能存在。
3. 聚合关系是当描述一个大的事物时,大的事务可以包含小的事务,也可以不包含小的事物,比如图书馆和图书,而组合是一个大的事物的存在必须是由多个小的事务组成的,缺省了小的事务是不可以的。
一对多,多对一关系映射
⼀对多,多对⼀关系映射 ⼀对多,多对⼀关系映射 现实⽣活中有很多1对多(多对1)的关系模型。
⽐如,⼀个⼈可以有0到多套房⼦,0到多辆汽车;⼀个⽗亲有0到多个孩⼦等等。
这种关系被称作1对多关系。
反过来,房⼦与⼈,汽车与⼈的关系,以及孩⼦与⽗亲的关系就是多对⼀的关系。
这⾥需要注意⼀点的是,多对⼀关系的⼀个前提是:⼀套确定的房⼦只能属于某个确定的⼈(不能属于多⼈);⼀个确定的孩⼦也只能属于某个确定的⽗亲。
下⾯我们就拿最简单的⽗亲和孩⼦的关系来说明1对多(多对1)模型的映射。
关系模型:⽗亲 vs 孩⼦(Father vs Son)。
关系映射:one-to-many反过来,关系模型:孩⼦ vs ⽗亲(Son vs Father)。
关系映射:many-to-one 很多初学者往往有这样的疑问,我什么时候需要定义映射关系呢? 答案很简单:按需求来确定。
就是说你需要哪种关系的时候就定义哪种映射,不需要的时候就可以不定义它们的关系映射了。
还是以上⾯的例⼦来说明。
如果你需要在取得孩⼦(Son)的时候,同时需要知道该孩⼦的⽗亲(Father)是谁,你就可以在孩⼦的实体类⾥定义孩⼦跟⽗亲的关系映射: @ManyToOne 。
同样,如果需要知道某⽗亲的所有孩⼦,就可以在⽗亲的实体类⾥定义⽗亲跟孩⼦的关系映射: @OneToMany 。
1.ManyToOne(多对⼀) 单向:不产⽣中间表,但可以⽤@Joincolumn(name=" ")来指定⽣成外键的名字,外键在多的⼀⽅表中产⽣!2.OneToMany(⼀对多) 单向:会产⽣中间表,此时可以⽤@onetoMany @Joincolumn(name=" ")避免产⽣中间表,并且指定了外键的名字(别看 @joincolumn在⼀中写着,但它存在在多的那个表中)3.OneToMany ,ManyToOne 双向( 两个注解⼀起⽤的):如果不在 @OneToMany 中加mappedy属性就会产⽣中间表,此时通常在 @ManyToOne 的注解下再添上注解 @Joincolumn(name=" ") 来指定外键的名字(说明:多的⼀⽅为关系维护端,关系维护端负责外键记录的更新,关系被维护端没有权利更新外键记录)!( @OneToMany(mappedBy="⼀对多中,多中⼀的属性") 出现mapby为被维护端|||默认为延迟加载)⽤例:1 @ManyToOne(fetch=ZY)2 @JoinColumn(name="child_id")3private OrderChild orderChild;45 @OneToMany(mappedBy="orderChild",fetch=ZY,cascade={CascadeType.MERGE})6 @NotFound(action=NotFoundAction.IGNORE)//代表可以为空,允许为null7private List<OrderChildGoods> goodsList; hibernate中@ManyToOne默认是⽴即加载,@OneToMany默认是懒加载但是如果加上了@NotFound之后设置的fetch=ZY是不起作⽤的,也就是设置@NotFound后变为了⽴即加载eager 下⾯举例详细说明⼀下@ManyToOne @ManyToOne注解的这端,是多端 1.在注释@ManyToOne(cascade=CascadeType.REFRESH,optional=true)中将属性optional设置为true,这可以使得即使外键为空时仍可以向表中添加数据。
主表和子表的关联方式
主表和子表的关联方式
在数据库设计中,主表和子表之间的关联通常是通过主键和外键来实现的。
这种设计允许我们在不同表之间建立关系,并确保数据的引用完整性。
以下是主表和子表关联的几种常见方式:
1. 一对多关联(One-to-Many):
在这种关联中,一个主表(父表)可以与多个子表(子表)相关联。
主表中的每条记录都可以对应子表中的多条记录。
例如,一个订单表(Order)可以与多个订单详情表(Order Details)相关联,因为一个订单可以有多个订单项。
2. 多对多关联(Many-to-Many):
当两个表中的记录可以相互关联时,就会使用到多对多关联。
这通常通过一个关联表(或交叉参考表)来实现,该表包含两个表的主键。
例如,学生表(Students)和课程表(Courses)之间的多对多关联可以通过一个学生课程关联表(StudentCourses)来实现,该表包含学生ID和课程ID。
3. 一对一关联(One-to-One):
在一对一关联中,主表中的每条记录最多只能与子表中的一条记录相关联,反之亦然。
例如,一个用户表(Users)可以与一个用户详细信息表(User Details)一对一关联,因为每个用户只有一个用户详细信息。
在实际应用中,这些关联方式可以根据实际业务需求进行组合和
扩展。
使用主键和外键的关联可以帮助数据库管理系统维护数据的完整性和一致性,同时也使得查询和数据分析变得更加高效和灵活。
mybatiscollection一对多关联查询,单边分页的问题总结!
mybatiscollection⼀对多关联查询,单边分页的问题总结!若想直接通过sql实现多级关联查询表结构得有2 个必不可少的字段:id ,parentId,levelIdid:主键id,parentId:⽗idlevelId:表⽰第⼏级(表本⾝关联查询的时候需要⽤到,不然会有重复数据)利⽤mybatis collection 实现⼀对多关联查询Dto:(⼀级)public class ProvinceInfoDTO implements Serializable {private String id;private String name;private String pinyin;private String firstLetter;private List<CitysInfoDTO> cities;}Dto:(⼆级)public class CitysInfoDTO implements Serializable {private String id;private String name;private String pinyin;private String firstLetter;private String acronym;private List<RegionInfoDTO> regions;}Dto(三级)public class RegionInfoDTO implements Serializable {private String id;private String name;private String pinyin;private String firstLetter;}resultMap<resultMap id="unloadAreaQueryResultMap" type="com.haoyunhu.res.ProvinceInfoDTO"> // ⼀级<result column="aid" property="id"/><result column="aname" property="name"/><result column="apinyin" property="pinyin"/><result column="aletter" property="firstLetter"/><collection property="cities" ofType="com.haoyunhu.res.CitysInfoDTO"> //⼆级<result column="bid" property="id"/><result column="bname" property="name"/><result column="bpinyin" property="pinyin"/><result column="bletter" property="firstLetter"/><result column="bacronym" property="acronym"/><collection property="regions" ofType="com.haoyunhu.res.RegionInfoDTO"> // 三级<result column="cid" property="id"/><result column="cname" property="name"/><result column="cpinyin" property="pinyin"/><result column="cletter" property="firstLetter"/></collection></collection></resultMap>省市区级联查询sql:SELECT a.PROV_NAME,b.PROV_NAME,c.PROV_NAMEFROM T_DATA_AREAS aLEFT JOIN T_DATA_AREAS bON a.id=b.PROV_PARENTIDLEFT JOIN T_DATA_AREAS CON b.id =C.PROV_PARENTIDWHERE a.PROV_LEVELTYPE=1AND b.PROV_LEVELTYPE =2AND c.PROV_LEVELTYPE =3ORDER BY a.PROV_NAME;以上mybatis的操作最终得到的json是:{"id":"310000","name":"上海","pinyin":"Shanghai","firstLetter":"","cities":[{"id":"310100","name":"上海市","pinyin":"Shanghai","firstLetter":"","acronym":"","regions":[{"id":"230506","name":"宝⼭区","pinyin":"Baoshan","firstLetter":""}]}]}⼀对多关联查询单边分页:上述的这种关联查询时没法直接使⽤pagehelper分页插件的,因为pagehelper分页插件是针对真个sql 截取,所以只能⼿动分页(简单,分页⽆⾮就是截取sql +查询总条数),所以若⼀对多关联查询想分页得针对主表(案例中的A表)截取sql(pageindex pagesize) ,再另外写条sql查询主表(案例中的A表)的记录数 ------注意mysql 的偏移量的概念还需要注意的坑:1:这种需要做级联查询,表结构⼜不满⾜的坑:若表结构不满⾜,但是⼜想省事,就得写sql 把原表整成这种固定格式的临时表结构(⼦查询)2:电商领域的商品类⽬的级联查询和这个省市区的查询⼀样(都需要levelid,⽤在查询条件处:where a.levelid=0 and b.levelid=1 and c.levelid=2;当然这种级联查询可以在java代码中可以实现,三条sql,分别查询 level =0 1 2的,然后java代码⾥⾯循环!。
Access数据库的表关系与关联操作
Access数据库的表关系与关联操作Access是一款常用的关系型数据库管理系统(RDBMS),它以其易用性和功能强大而受到广泛应用。
在Access中,表关系和关联操作是数据库设计和数据管理中至关重要的概念。
本文将详细介绍Access数据库的表关系和关联操作。
一、表关系的概念表关系是指不同表之间的属性和数据的共享和联系。
在Access中,常见的表关系包括一对一关系、一对多关系和多对多关系。
1. 一对一关系一对一关系意味着两个表之间的每个记录在另一个表中只有一个与之对应的记录。
例如,一个学生表和一个考勤表之间可以建立一对一关系,确保每个学生只有一条考勤记录。
2. 一对多关系一对多关系是指一个表的记录可以与另一个表的多个记录相关联,而另一个表的记录只能与一个表的记录相关联。
例如,一个客户表和一个订单表之间可以建立一对多关系,每个客户可以拥有多个订单。
3. 多对多关系多对多关系是指两个表之间的每个记录都可以与另一个表的多个记录相关联。
为了实现多对多关系,通常需要通过中间表来关联两个表。
例如,一个学生表和一个课程表之间可以建立多对多关系,通过一个成绩表来关联学生和课程。
二、创建表关系在Access中,可以通过创建外键来建立表关系。
外键是一个字段或一组字段,它引用了另一张表的主键(或唯一键),从而将两个表联系起来。
1. 创建一对一关系要创建一对一关系,可以在其中一个表中创建一个引用另一个表主键的字段。
在Access的设计视图中,选择该字段,右键点击并选择“设置主键和外键”,然后选择目标表中的相关字段作为外键。
2. 创建一对多关系要创建一对多关系,可以在“多”一方的表中创建一个引用“一”一方表主键的字段。
然后,在Access的设计视图中,选择该字段,右键点击并选择“设置主键和外键”,然后选择目标表中的相关字段作为外键。
3. 创建多对多关系要创建多对多关系,需要创建一个中间表,该表包含了两个表的主键作为外键。
javaee一对一,一对多,多对多的心得
JavaEE是一种用于开发企业级应用程序的技术评台,它构建在Java评台之上,提供了一系列的API和功能,从而使开发人员能够更加便利地构建出可靠、可扩展和安全的应用程序。
在JavaEE中,常见的关系模型有一对一、一对多和多对多,这三种关系模型在实际开发中具有重要的作用。
本文将深入探讨这三种关系模型在JavaEE中的应用,并结合实际开发经验,共享一些心得体会。
一、一对一关系1.1. 一对一关系概述在JavaEE中,一对一关系指的是两个实体之间的一对一映射关系,即一个实体实例只对应另一个实体实例。
这种关系模型在数据库设计和应用程序开发中经常会遇到,例如学生和唯一识别信息号码之间的关系就是一对一关系。
在JavaEE中,一对一关系通常通过OneToOne注解来进行表示。
1.2. 一对一关系的实际应用在实际开发中,一对一关系常常用于处理一些固定的关联关系,例如用户和用户详细信息、公司和公司详情等。
通过一对一关系的映射,可以方便地进行数据查询和管理,提高了系统的可维护性和可扩展性。
1.3. 一对一关系的心得体会在处理一对一关系时,需要注意合理设计数据库表结构和Entity对象之间的映射关系,避免出现冗余或不必要的数据。
还需要考虑数据查询的性能和效率,避免因为关联关系过多导致数据查询变慢。
一对一关系在JavaEE开发中具有重要的作用,需要合理使用和灵活运用。
二、一对多关系2.1. 一对多关系概述一对多关系指的是一个实体实例对应多个实体实例的关系模型,例如一个班级对应多个学生,一个订单对应多个商品等。
在JavaEE中,一对多关系通常通过OneToMany注解来进行表示。
2.2. 一对多关系的实际应用一对多关系在实际开发中非常常见,例如新闻和评论之间的关系、部门和员工之间的关系等。
通过一对多关系的映射,可以方便地进行数据操作和管理,提高了系统的灵活性和扩展性。
2.3. 一对多关系的心得体会在处理一对多关系时,需要注意数据的一致性和完整性,避免因为关联关系过于复杂而导致数据操作的困难和混乱。
SpringBootjpa注解@ElementCollection实现一对多关联
SpringBootjpa注解@ElementCollection实现⼀对多关联环境:jdk: openjdk11springboot: 2.2操作系统: win10教育版 19031. pom.xml (jpa依赖主要在 jpa-redis注释下的两个)1<?xml version="1.0" encoding="UTF-8"?>2<project xmlns="/POM/4.0.0" xmlns:xsi="/2001/XMLSchema-instance"3 xsi:schemaLocation="/POM/4.0.0 https:///xsd/maven-4.0.0.xsd">4<modelVersion>4.0.0</modelVersion>5<parent>6<groupId>org.springframework.boot</groupId>7<artifactId>spring-boot-starter-parent</artifactId>8<version>2.2.4.RELEASE</version>9<relativePath/><!-- lookup parent from repository -->10</parent>11<groupId>com.rurjs</groupId>12<artifactId>starter</artifactId>13<version>0.0.1</version>14<name>RurjsStarter</name>15<description>Demo project for Spring Boot</description>1617<properties>18<java.version>11</java.version>19<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>20<security-jwt.version>1.0.9.RELEASE</security-jwt.version>21<jjwt.version>0.9.0</jjwt.version>22<spring-cloud-dependency-version>2.1.2.RELEASE</spring-cloud-dependency-version>23</properties>2425<dependencies>26<dependency>27<groupId>org.springframework.boot</groupId>28<artifactId>spring-boot-starter-web</artifactId>29</dependency>30<!--开发⼯具-->31<dependency>32<groupId>org.springframework.boot</groupId>33<artifactId>spring-boot-devtools</artifactId>34<scope>runtime</scope>35<optional>true</optional>36</dependency>37<dependency>38<groupId>mons</groupId>39<artifactId>commons-lang3</artifactId>40<version>3.9</version>41</dependency>42<!--lombok⼯具-->43<dependency>44<groupId>org.projectlombok</groupId>45<artifactId>lombok</artifactId>46<optional>true</optional>47</dependency>48<!--单元测试-->49<dependency>50<groupId>org.springframework.boot</groupId>51<artifactId>spring-boot-starter-test</artifactId>52<scope>test</scope>53<exclusions>54<exclusion>55<groupId>org.junit.vintage</groupId>56<artifactId>junit-vintage-engine</artifactId>57</exclusion>58</exclusions>59</dependency>60<dependency>61<groupId>io.projectreactor</groupId>62<artifactId>reactor-test</artifactId>63<scope>test</scope>64</dependency>65<!--jpa-redis-->66<dependency>67<groupId>org.springframework.boot</groupId>68<artifactId>spring-boot-starter-data-jpa</artifactId>69</dependency>70<dependency>71<groupId>mysql</groupId>72<artifactId>mysql-connector-java</artifactId>73<!--<version>5.1.46</version>-->74</dependency>75<dependency>76<groupId>org.springframework.boot</groupId>77<artifactId>spring-boot-starter-data-redis</artifactId>78</dependency>79<!--oauth2认证-->80<dependency>81<groupId>org..springframework.cloud</groupId>82<artifactId>spring-cloud-starter-oauth2</artifactId>83<version>${spring-cloud-dependency-version}</version>84</dependency>85<dependency>86<groupId>org.springframework.cloud</groupId>87<artifactId>spring-cloud-starter-security</artifactId>88<version>${spring-cloud-dependency-version}</version>89</dependency>90<dependency>91<groupId>org.springframework.security</groupId>92<artifactId>spring-security-jwt</artifactId>93<version>${security-jwt.version}</version>94</dependency>95<dependency>96<groupId>io.jsonwebtoken</groupId>97<artifactId>jjwt</artifactId>98<version>0.7.0</version>99</dependency>100<!--json-->101<dependency>102<groupId>com.alibaba</groupId>103<artifactId>fastjson</artifactId>104<version>1.2.57</version>105</dependency>106<!--API⽂档-springfox-swagger2-->107<dependency>108<groupId>io.springfox</groupId>109<artifactId>springfox-swagger2</artifactId>110<version>2.9.2</version>111<!--排除这个包,这⾥有个bug: Illegal DefaultValue for parameter type integer-->112<exclusions>113<exclusion>114<groupId>io.swagger</groupId>115<artifactId>swagger-models</artifactId>116</exclusion>117</exclusions>118</dependency>119<dependency>120<groupId>io.swagger</groupId>121<artifactId>swagger-models</artifactId>122<version>1.5.21</version>123</dependency>124<dependency>125<groupId>io.springfox</groupId>126<artifactId>springfox-swagger-ui</artifactId>127<version>2.9.2</version>128</dependency>129</dependencies>130131<build>132<plugins>133<plugin>134<groupId>org.springframework.boot</groupId>135<artifactId>spring-boot-maven-plugin</artifactId>136</plugin>137</plugins>138</build>139140</project>2. application.yml( 主要是 spring.datasource 和 spring.jpa部分)1 server:2 port: 90183 spring:4 redis:5 host: 127.0.0.16 database: 07 datasource:8 url: jdbc:mysql://127.0.0.1:3306/rurjs_starter?characterEncoding=UTF-8&serverTimezone=UTC9 username: root10 password: DRsXT5sJ6Oi55LPj11 jpa:12 hibernate:13 ddl-auto: update14 database: mysql15 show-sql: true16 database-platform: org.hibernate.dialect.MySQL5InnoDBDialect1718 rjsSecurity:19 exclude:20 antMatchers: /oauth/**,/login,/home21 #logging:22 # level: debug3. 主类1package com.rurjs.starter;23import org.springframework.boot.SpringApplication;4import org.springframework.boot.autoconfigure.SpringBootApplication;5import org.springframework.web.bind.annotation.RequestMapping;6import org.springframework.web.bind.annotation.RestController;78 @SpringBootApplication9public class RurjsStarterApplication {1011public static void main(String[] args) {12 SpringApplication.run(RurjsStarterApplication.class, args);13 }1415 @RestController16public class HealthController{1718 @RequestMapping("ping")19public String ping()20 {21return "Pong";22 }23 }24 }4. 实体类package com.rurjs.starter.config.sso.domain;import lombok.Getter;import lombok.Setter;import lombok.ToString;import org.hibernate.annotations.Fetch;import org.hibernate.annotations.FetchMode;import org.springframework.data.jpa.domain.support.AuditingEntityListener;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.oauth2.provider.ClientDetails;import java.io.Serializable;import javax.persistence.*;import java.util.*;@Getter@Setter@ToString@Entity@EntityListeners(AuditingEntityListener.class)@Tablepublic class OauthClientDetails implements Serializable{private static final long serialVersionUID = 2930534157595467437L;@Idprivate String clientId;//client_id@Fetch(FetchMode.JOIN)@ElementCollectionprivate Set<String> resourceIds;//资源idprivate String clientSecret;//client 密钥}⾃动⽣成表如下:mysql> show create table oauth_client_details_resource_ids;+-----------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| Table | Create Table +-----------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| oauth_client_details_resource_ids | CREATE TABLE `oauth_client_details_resource_ids` (`oauth_client_details_client_id` varchar(255) NOT NULL,`resource_ids` varchar(255) DEFAULT NULL,KEY `FKo1c1xapbgjtw5kgq9c1fy8vp3` (`oauth_client_details_client_id`),CONSTRAINT `FKo1c1xapbgjtw5kgq9c1fy8vp3` FOREIGN KEY (`oauth_client_details_client_id`) REFERENCES `oauth_client_details` (`client_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 |+-----------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------1 row in set (0.03 sec)mysql>5. Daopackage com.rurjs.starter.config.sso.dao;import com.rurjs.starter.config.sso.domain.OauthClientDetails;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.stereotype.Repository;import java.util.Collection;@Repository("OauthClientDetailsDao")public interface OauthClientDetailsDao extends JpaRepository<OauthClientDetails,String> {//批量删除.public int deleteAllByClientIdIn(Collection<String> clientId);}6. 单元测试package com.rurjs.starter;import com.rurjs.starter.config.sso.dao.OauthClientDetailsDao;import com.rurjs.starter.config.sso.domain.OauthClientDetails;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.oauth2.provider.ClientDetailsService;import org.springframework.transaction.annotation.Transactional;import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.Set;@SpringBootTestclass RurjsStarterApplicationTests {@Autowiredprivate OauthClientDetailsDao oauthClientDetailsDao;@Testpublic void ClientInsert(){Set<String> resources = new HashSet<>();resources.add("resource1");resources.add("all");OauthClientDetails oauthClientDetails = new OauthClientDetails();oauthClientDetails.setClientId("client1");oauthClientDetails.setClientSecret("123456");oauthClientDetails.setResourceIds(resources);OauthClientDetails oauthClientDetails1 = oauthClientDetailsDao.save(oauthClientDetails);System.out.println(oauthClientDetails1);}@Testpublic void ClientQuery(){String clientId = "client1";OauthClientDetails oauthClientDetails = oauthClientDetailsDao.findById(clientId).orElse(null);System.out.println(oauthClientDetails);}}7. 可能的⼀些问题及解决⽅式.1. 添加数据(带⼀对多关系)时正常,但是查询的时候抛出异常如下zyInitializationException: failed to lazily initialize a collection of role: com.rurjs.starter.config.sso.domain.OauthClientDetails.resourceIds, could not initialize proxy - no Sessionat org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:606)at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:218)at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:162)at org.hibernate.collection.internal.PersistentSet.size(PersistentSet.java:168)at java.base/java.util.HashSet.<init>(HashSet.java:119)at com.rurjs.starter.config.sso.domain.OauthClientDetails.getResourceIds(OauthClientDetails.java:66)at com.rurjs.starter.config.sso.domain.OauthClientDetails.toString(OauthClientDetails.java:18)at java.base/ng.String.valueOf(String.java:2951)at java.base/java.io.PrintStream.println(PrintStream.java:897)at com.rurjs.starter.RurjsStarterApplicationTests.ClientQuery(RurjsStarterApplicationTests.java:87)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.base/ng.reflect.Method.invoke(Method.java:566)at mons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125)at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132)at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124)at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:74)at org.junit.jupiter.engine.execution.ExecutableInvoker$mbda$ofVoidMethod$0(ExecutableInvoker.java:115)at mbda$invoke$0(ExecutableInvoker.java:105)at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104)at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62)at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43)at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35)at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)at mbda$invokeTestMethod$6(TestMethodTestDescriptor.java:202)at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198)at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)at mbda$executeRecursively$5(NodeTestTask.java:135)at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)at mbda$executeRecursively$7(NodeTestTask.java:125)at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)at mbda$executeRecursively$8(NodeTestTask.java:123)at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)at mbda$executeRecursively$5(NodeTestTask.java:139)at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)at mbda$executeRecursively$7(NodeTestTask.java:125)at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)at mbda$executeRecursively$8(NodeTestTask.java:123)at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)at mbda$executeRecursively$5(NodeTestTask.java:139)at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)at mbda$executeRecursively$7(NodeTestTask.java:125)at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)at mbda$executeRecursively$8(NodeTestTask.java:123)at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)at uncher.core.DefaultLauncher.execute(DefaultLauncher.java:229)at mbda$execute$6(DefaultLauncher.java:197)at uncher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)at uncher.core.DefaultLauncher.execute(DefaultLauncher.java:191)at uncher.core.DefaultLauncher.execute(DefaultLauncher.java:128)at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:74)at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)解决⽅式:在实体类中给有⼀对多关系的属性(如 resourceIds )上添加注解 @Fetch(FetchMode.JOIN);⽆该注解和注解为 @Fetch(FetchMode.SUBSELECT)或@Fetch(FetchMode.SELECT)时,都会抛出该异常,按异常信息来说,解决懒加载问题也⾏,题主未并未使⽤解决懒加载的⽅式解决该异常。
数据库中表的一对多、多对多、一对一关系等
数据库中表的⼀对多、多对多、⼀对⼀关系等外键前戏之⼀对多关系"""把所有数据都存放于⼀张表的弊端1.组织结构不清晰2.浪费硬盘空间3.扩展性极差"""# 上述的弊端产⽣原因类似于把代码全部写在⼀个py⽂件中,你应该怎么做?>>>解耦合!将上述⼀张表拆成员⼯和部门两张表!# 类似的表关系学⽣与班级,也是如此,⼀张学⽣表和⼀张班级表# 分析表数据之间的关系:多个⽤户对应⼀个部门,⼀个部门对应多个⽤户。
禁⽌⼀个⽤户对应多个部门这种情况是另外⼀张表关系# 如何查找表与表之间的关系"""⽼师与课程表1.站在⽼师表的⾓度:⼀名⽼师能否教授多门课程(限制死,不能,⼀名⽼师只能教python,不能同时教python和linux)2.站在课程表的⾓度:⼀门课程能否可以被多个⽼师教,完全可以!那就是课程表多对⼀⽼师表,如何表⽰这种关系?在课程表中创建⼀个字段(tea_id)指向⽼师表的id字段学⽣与班级表1.站在学⽣表的⾓度:2.站在班级表的⾓度:那就是学⽣表多对⼀班级表,如何表⽰这种关系?在学⽣表中创建⼀个字段(class_id)指向班级表的id字段"""# 再回过头来看员⼯与部门表,我员⼯表⾥⾯的dep_id我可以随意更改,但是应该有⼀个强制限制,限制dep_id字段必须只是部门表已有的id字段才合理⼀对多(Foreign Key)# foreign key会带来什么样的效果?# 1、在创建表时,先建被关联的表dep,才能建关联表empcreate table dep(id int primary key auto_increment,dep_name char(10),dep_comment char(60));create table emp(id int primary key auto_increment,name char(16),gender enum('male','female') not null default 'male',dep_id int,foreign key(dep_id) references dep(id));# 2、在插⼊记录时,必须先插被关联的表dep,才能插关联表empinsert into dep(dep_name,dep_comment) values('sb教学部','sb辅导学⽣学习,教授python课程'),('外交部','⽼男孩上海校区驻张江形象⼤使'),('nb技术部','nb技术能⼒有限部门');insert into emp(name,gender,dep_id) values('alex','male',1),('egon','male',2),('lxx','male',1),('wxx','male',1),('wenzhou','female',3);# 当我想修改emp⾥的dep_id或dep⾥⾯的id时返现都⽆法成功# 当我想删除dep表的教学部的时候,也⽆法删除# ⽅式1:先删除教学部对应的所有的员⼯,再删除教学部# ⽅式2:受限于外键约束,导致操作数据变得⾮常复杂,能否有⼀张简单的⽅式,让我不需要考虑在操作⽬标表的时候还需要考虑关联表的情况,⽐如我删除部门,那么这个部门对应的员⼯就应该跟着⽴即清空# 先把之前创建的表删除,先删员⼯表,再删部门表,最后按章下⾯的⽅式重新创建表关系# 3.更新于删除都需要考虑到关联与被关联的关系>>>同步更新与同步删除create table dep(id int primary key auto_increment,dep_name char(10),dep_comment char(60));create table emp(id int primary key auto_increment,name char(16),gender enum('male','female') not null default 'male',dep_id int,foreign key(dep_id) references dep(id)on update cascadeon delete cascade);insert into dep(dep_name,dep_comment) values('sb教学部','sb辅导学⽣学习,教授python课程'),('外交部','⽼男孩上海校区驻张江形象⼤使'),('nb技术部','nb技术能⼒有限部门');insert into emp(name,gender,dep_id) values('alex','male',1),('egon','male',2),('lxx','male',1),('wxx','male',1),('wenzhou','female',3);# 删除部门后,对应的部门⾥⾯的员⼯表数据对应删除# 更新部门后,对应员⼯表中的标⽰部门的字段同步更新多对多# 图书表与作者表之间的关系"""仍然站在两张表的⾓度:1.站在图书表:⼀本书可不可以有多个作者,可以!那就是书多对⼀作者2.站在作者表:⼀个作者可不可以写多本书,可以!那就是作者多对⼀书双⽅都能⼀条数据对应对⽅多条记录,这种关系就是多对多!"""# 先来想如何创建表?图书表需要有⼀个外键关联作者,作者也需要有⼀个外键字段关联图书。
多对一,一对一,一对多
第一种关联关系:一对多(多对一)"一对多"是最普遍的映射关系,简单来讲就如消费者与订单的关系。
一对多:从消费者角的度来说一个消费者可以有多个订单,即为一对多。
多对一:从订单的角度来说多个订单可以对应一个消费者,即为多对一。
一对多关系在hbm文件中的配置信息:消费者(一方):<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.suxiaolei.hibernate.pojos.Customer" table= "customer"><!-- 主键设置 --><id name="id" type="string"><column name="id"></column><generator class="uuid"></generator></id><!-- 属性设置 --><property name="username" column="username" type="string "></property><property name="balance" column="balance" type="integer"> </property><set name="orders" inverse="true" cascade="all"><key column="customer_id"></key><one-to-many class="com.suxiaolei.hibernate.pojos.Or der"/></set></class></hibernate-mapping>订单(多方):<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.suxiaolei.hibernate.pojos.Order" table="or ders"><id name="id" type="string"><column name="id"></column><generator class="uuid"></generator></id><property name="orderNumber" column="orderNumber" type=" string"></property><property name="cost" column="cost" type="integer"></pro perty><many-to-one name="customer" class="com.suxiaolei.hibern ate.pojos.Customer"column="customer_id" cascade="save-update"> </many-to-one></class></hibernate-mapping>"一对多"关联关系,Customer方对应多个Order方,所以Customer包含一个集合用于存储多个Order,Order包含一个Customer用于储存关联自己的Customer。
二级ACCESS笔试知识点
1.1数据库基础知识1、数据库有关的概念:a、数据:是指描述事物的符号记录。
b、数据库:,DB(Database)。
c、数据库管理系统:是指位于用户与操作系统之间的、方便用户管理与组织数据库的一种数据库管理软件。
简称为DBMS(Database Management System)。
d、数据库应用系统:是指在数据库系统资源的基础上、针对某一类应用而开发出来的应用软件。
如大家都e、数据库系统为DBS(Database System)。
注意:数据库系统的核心是数据库管理系统。
2、数据库系统的特点:a、实现数据共享,减少数据冗余。
这是数据库的基本特征。
b、采用特定的数据模型。
c、具有较高的数据独立性。
d、有统一的数据控制功能。
3、数据模型:数据库应用系统就是将现实世界映射到计算机中的结果。
为了简化这个映射过程,引入了数据模型。
数据模型是从现实世界到计算机世界的一个中间层次,其不仅能方便地描述数据本身,而且能正确地反映出数据之间存关系模型与层次模型、网状模型的本质区别在于数据描述的一致性、模型概念的单一性。
4、实体间联系及种类:在数据模型中,将现实世界中客观存在的事物称之间实体。
通常需要描述出现实世界中存在的实体、实体的属性及实体之间的关系。
实体之间的对应关系称之为联系,反映了现实世界事物之间的相互关联。
通常分为:a、b、一对多联系或多对一联系:注意两个实体前后的顺序关系。
一对多联系:如班级信息与学生信息。
多对一联系:如学生信息与班级信息。
c、多对多联系:如学生信息与课程信息。
历届试题:1、数据库DB、数据库系统DBS、数据库管理系统DBMS 之间的关系是(2006 年4 月选择题第10 题)A)DB 包含DBS 和DBMS B)DBMS 包含DB 和DBS C)DBS 包含DB 和DBMS D)没有任何关系2、常见的数据模型有3 种,它们是(2006 年4 月选择题第11 题)A)网状、关系和语义B)层次、关系和网状C)环状、层次和关系D)字段名、字段类型和记录3、假设数据库中表A 与表B 建立了“一对多”关系,表B 为“多”的一方,则下述说法中正确的是(2005 年4月选择题第12 题)A) 表A 中的一个记录能与表B 中的多个记录匹配B) 表B 中的一个记录能与表A 中的多个记录匹配C) 表A 中的一个字段能与表B 中的多个字段匹配D) 表B 中的一个字段能与表A 中的多个字段匹配4、如果表 A 中的一条记录与表 B 中的多条记录相匹配,且表 B 中的一条记录与表 A 中的多条记录相匹配,则表A 与表B 存在的关系是(2005 年9 月选择题第12 题)A) 一对一B) 一对多C) 多对一D) 多对多5、“商品”与“顾客”两个实体集之间的联系一般是(2006 年4 月选择题第8 题)A)一对一B)一对多C)多对一D)多对多6、列实体的联系中,属于多对多联系的是(2006 年9 月选择题第11 题)A)学生与课程B)学校与校长C)住院的病人与病床D)职工与工资正确答案:1、C 2、B 3、A 4、D 5、D 6、A1.2关系数据库1、关系数据模型的基本基本概念a、关系:一个关系就是一个二维表,每个关系有一个关系名。
hibernate学习笔记
Hibernate 学习笔记2010年7月9日星期五1目录1.学习纲要2.学习目的3.达标标准4.名词解释5.学习时间:两天又3小时(16~19pm)2具体内容2.1学习纲要2.1.1什么是hibernate?它是连接JAVA应用程序和关系数据库的中间件它对JDBC API进行了封装,负责JAVA对象的持久化在分层的软件架构中它位于持久化层,封装了所有数据访问细节,使业务逻辑层可以专注于实现业务逻辑。
它是一种ORM映射工具,能够建立面向对象的域模型和关系数据模型之间的映射2.1.2HIBERNATE原理依赖的技术有:JAVA反射机制(在org.hibernate.property中得到较多应用,通过INVORK()方法调用POJO对象的setter,getter方法设置和获取属性的值)i.Class类ii.getMethods方法得到Method类iii.Method类iv.invoke方法用来调用被反射类的方法CGLIB(用于对持久化类进行延迟加载时生成代理类)i.以asm项目为基础,对asm的功能进行封装和扩展,实现并扩展了JAVA的反射功能,可以在运行时状态下实现JAVA接口,扩展JAVA类ii.Asm项目是一个简洁的字节码工具,能够在运行的状态下动态的修改编译完成的JAVA类JAVASSIST(同CGLIB,是另一套解决方案,可以通过修改org.hibernate.cfg.Environment.java原码进行设置)i.是一个执行字节码操作的强有力的驱动代码库。
它允许开发者在代码被JAVA虚拟机载入之前定义一个新类或者修改类的的原代码。
XML技术(DOM4J)i.用来解析XML配置文件Antlr(another tool for language recognition)i.它是一个开源的工具,利用后缀为“.g”的文件来定义语法规则ii.Hibernate提供的语法规则有iii.Hql.giv.Hql-sql.gv.Sql-gen.gvi.Hibernate通过调用这些生成的解析类完成把HQL语句转为SQL语句的工作2.1.3HIBERNATE方法的内部实现略2.1.4Hibernate能做什么?2.1.5hibernate应用在哪些方面2.1.6Hibernate关联关系1.一对多关联<many-to-one name=”customer”column=”CUSTOMER_ID”class=”mypack.Customer”lazy=”false” not-null=”true”/>此种情况下不会加载关联的临时对象。
UML类图详解_关联关系_一对多
UML类图详解_关联关系_⼀对多对于⼀对多的⽰例,可以想象⼀个账户可以多次申购。
在申购的时候没有固定上限,下限为0,那么就可以使⽤容器类(container class)来搞,最常见的就是vector了。
下⾯我们来看⼀个“⼀对多”的例⼦Account.h1 #include <cstdlib>2 #include <vector>3 #include "Bid.h"4using namespace std;56class Account7 {8public:9void setBid(Bid*);10int calcAmount();11private:12 vector<Bid*> bidObj;13 };声明⼀个存放申购交易对于指针的vector对象。
然后类Account中的函数setBid设计了⼀个公有操作,让外界⽤来传⼊申购交易对象的指针,以便让账户对象将申购交易对象指针存⼊vector对象中。
Account.cpp1 #include "Account.h"23void Account::setBid(Bid *theBid)4 {5 bidObj.push_back(theBid);6 }78int Account::calcAmount()9 {10int size,theAmount=0;11 size=bidObj.size();12for(int i=0;i<size;i++)13 theAmount=theAmount+bidObj[i]->getAmount();14return theAmount;15 }Bid.h1class Bid2 {3public:4void setAmount(int);5int getAmount();6private:7int amount;8 };Bid.cpp1 #include "Bid.h"23void Bid::setAmount(int theAmount)4 {5 amount=theAmount;6 }78int Bid::getAmount()9 {10return amount;11 }main.cpp1 #include <cstdlib>2 #include <iostream>3 #include "Bid.h"4 #include "Account.h"5using namespace std;67int main(int argc, char *argv[])8 {9 Bid *myBid;10 Account myAccount;11int theAmount;12int choice;1314do15 {16 cout << "请输⼊申购⾦额: ";17 cin >> theAmount;18 myBid=new Bid;19 myBid->setAmount(theAmount);20 myAccount.setBid(myBid);21 cout << "1(继续), 2(结算) ...";22 cin >> choice;23 cout << endl;24 } while(choice==1);2526 cout << "总投资⾦额为: "27 << myAccount.calcAmount() << endl << endl;2829 system("PAUSE");30return EXIT_SUCCESS;31 }下⾯我们来画⼀下UML图,并且⽤UML⾃动⽣成C++代码来做⼀个⽐较画法⼀:⽣成代码对⽐Account.h没有达到预期,多⽣成了成员变量,如果在类图⾥⾯写明了某个指针变量的话,那么在关联关系的端点处就不能再标⽰这个成员变量了,否则就会重复⽣成见中的画法⼆,也是因为这个导致了没有达到预期Bid.h达到预期画法⼆:⽣成代码对⽐Account.h达到预期Bid.h达到预期画法三:⽣成代码对⽐Account.h没有达到预期Bid.h达到预期综上所述,在实际画图的时候采⽤画法⼆才能保证正确,⼀旦类图⾥⾯包含了⼀次成员那么在关联端点再声明⼀次的话就会重复,另外如果不在类图⾥⾯包含⼀次成员⽽在关联端点处声明⼀次的话⽣成的代码⽐较傻,很多情况下⽆法满⾜我们的要求。
数据表的关联关系
数据表的关联关系数据表的关联关系是数据库设计中非常重要的概念之一。
通过合理的关联关系,可以实现数据的一致性、完整性和可靠性,提高数据库的查询效率和数据操作的灵活性。
下面将介绍几种常见的数据表关联关系,并分析它们的应用场景和优缺点。
1. 一对一关联一对一关联是最简单的关联关系之一,指的是两个数据表之间存在唯一的对应关系。
在一对一关联中,每个记录在另一个数据表中都只对应一个记录。
这种关联关系通常用于将一个数据表中的某些字段分离出来,形成一个独立的数据表。
例如,一个人员信息表中的身份证号字段可以作为一个独立的数据表,与人员信息表进行一对一关联。
2. 一对多关联一对多关联是最常见的关联关系之一,指的是一个数据表的每条记录在另一个数据表中都可以对应多条记录。
在一对多关联中,一个数据表的主键作为另一个数据表的外键,用于建立两个数据表之间的联系。
这种关联关系通常用于表示层次关系或者父子关系。
例如,一个部门表与一个员工表之间可以建立一对多关联,一个部门可以有多个员工,而一个员工只能属于一个部门。
3. 多对多关联多对多关联是最复杂的关联关系之一,指的是两个数据表之间存在多对多的对应关系。
在多对多关联中,一个数据表的每条记录可以对应另一个数据表的多条记录,反之亦然。
为了建立多对多关联,通常需要使用一个中间表来存储两个数据表之间的对应关系。
例如,一个学生表与一个课程表之间可以建立多对多关联,一个学生可以选择多门课程,而一门课程也可以被多个学生选择。
4. 自关联自关联是指一个数据表与自身建立关联关系。
自关联通常用于表示层次结构,例如一个组织机构表中的上级部门与下级部门之间的关系。
在自关联中,一个数据表的主键同时也是外键,用于建立记录与记录之间的关联关系。
通过自关联,可以方便地查询一个记录的上级记录或者下级记录。
在实际的数据库设计中,通常会同时使用多种关联关系来满足不同的需求。
例如,一个订单表可以与一个客户表建立一对多关联,表示一个客户可以有多个订单;同时,订单表也可以与一个商品表建立多对多关联,表示一个订单可以包含多种商品。
EF里一对一、一对多、多对多关系的配置和级联删除
EF⾥⼀对⼀、⼀对多、多对多关系的配置和级联删除本章节开始了解EF的各种关系。
如果你对EF⾥实体间的各种关系还不是很熟悉,可以看看我的思路,能帮你更快的理解。
I.实体间⼀对⼀的关系添加⼀个PersonPhoto类,表⽰⽤户照⽚类///<summary>///⽤户照⽚类///</summary>public class PersonPhoto{[Key]public int PersonId { get; set; }public byte[] Photo { get; set; }public string Caption { get; set; } //标题public Person PhotoOf { get; set; }}当然,也需要给Person类添加PersonPhoto的导航属性,表⽰和PersonPhoto⼀对⼀的关系:public PersonPhoto Photo { get; set; }直接运⾏程序会报⼀个错:Unable to determine the principal end of an association between the types ‘Model.Per-sonPhoto’ and ‘Model.Person’. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.思考:为何第⼀节的Destination和Lodging类直接在类⾥加上导航属性就可以⽣成主外键关系,现在的这个不⾏呢?解答:之前⽂章⾥的Destination和Lodging是⼀对多关系,既然是⼀对多,EF⾃然就知道设置Destination类的DestinationId为主键,同时设置Lodging类⾥的DestinationId为外键;但是现在的这个Person类和PersonPhoto类是⼀对⼀的关系,如果不⼿动指定,那么EF肯定不知道设置哪个为主键哪个为外键了,这个其实不难理解。
数据库系统原理课后习题参考答案
~第一章数据库系统概述选择题B、B、A简答题1.请简述数据,数据库,数据库管理系统,数据库系统的概念。
P27数据是描述事物的记录符号,是指用物理符号记录下来的,可以鉴别的信息。
数据库即存储数据的仓库,严格意义上是指长期存储在计算机中的有组织的、可共享的数据集合。
数据库管理系统是专门用于建立和管理数据库的一套软件,介于应用程序和操作系统之间。
《数据库系统是指在计算机中引入数据库技术之后的系统,包括数据库、数据库管理系统及相关实用工具、应用程序、数据库管理员和用户。
2.请简述早数据库管理技术中,与人工管理、文件系统相比,数据库系统的优点。
数据共享性高数据冗余小易于保证数据一致性数据独立性高可以实施统一管理与控制减少了应用程序开发与维护的工作量…3.请简述数据库系统的三级模式和两层映像的含义。
P31答:数据库的三级模式是指数据库系统是由模式、外模式和内模式三级工程的,对应了数据的三级抽象。
两层映像是指三级模式之间的映像关系,即外模式/模式映像和模式/内模式映像。
4.请简述关系模型与网状模型、层次模型的区别。
P35使用二维表结构表示实体及实体间的联系建立在严格的数学概念的基础上概念单一,统一用关系表示实体和实体之间的联系,数据结构简单清晰,用户易懂易用【存取路径对用户透明,具有更高的数据独立性、更好的安全保密性。
第二章关系数据库选择题C、C、D简答题1.请简述关系数据库的基本特征。
P48答:关系数据库的基本特征是使用关系数据模型组织数据。
2.请简述什么是参照完整性约束。
P55¥答:参照完整性约束是指:若属性或属性组F是基本关系R的外码,与基本关系S的主码K 相对应,则对于R中每个元组在F上的取值只允许有两种可能,要么是空值,要么与S中某个元组的主码值对应。
3.请简述关系规范化过程。
答:对于存在数据冗余、插入异常、删除异常问题的关系模式,应采取将一个关系模式分解为多个关系模式的方法进行处理。
一个低一级范式的关系模式,通过模式分解可以转换为若干个高一级范式的关系模式,这就是所谓的规范化过程。
数据库一对一、一对多、多对多关系
数据库⼀对⼀、⼀对多、多对多关系数据库⼀对⼀、⼀对多、多对多关系⼀、⾸先给出三种关系的实例⼀对⼀关系实例⼀个⼈对应⼀张⾝份证,⼀张⾝份证对应⼀个⼈⼀对多关系实例⼀个公司的部门拥有多个职员,⼀个职员只能够属于某个部门多对多实例⼀本图⽰可以拥有多个作者,⼀个作者可以写很多本书。
⼀对⼀关系⼀对多,是最常见的⼀种设计。
就是 A 表的⼀条记录,对应 B 表的多条记录,且 A 的主键作为 B 表的外键。
这主要看以哪张表为中⼼。
优点便于管理、可提⾼⼀定的查询速度减轻 CPU 的 IO 读写,提⾼存取效率。
符合数据库设计的三⼤范式。
符合关系性数据库的特性。
缺点增加⼀定的复杂程度,程序中的读写难度加⼤。
# 左表的⼀条记录唯⼀对应右表的⼀条记录,反之也⼀样# ⾝份证表create table iden(id int primary key auto_increment,name char(20) not null,iden_num char(18) not null unique);# 公民表create table civi(id int primary key auto_increment,name char(20) not null,civi_id int unique,foreign key(iden_id) references ident(iden_num) #外键的字段⼀定要保证uniqueon delete cascadeon update cascade);⼀对多关系⼀对多,是最常见的⼀种设计。
就是 A 表的⼀条记录,对应 B 表的多条记录,且 A 的主键作为 B 表的外键。
这主要看以哪张表为中⼼,我们把多对⼀和⼀对多统称为⼀对多关系,数据库中不存在多对⼀关系。
create table dep(id int primary key auto_increment,dep_name char(10),dep_comment char(60));create table emp(id int primary key auto_increment,name char(16),gender enum('male','female') not null default 'male',dep_id int,foreign key(dep_id) references dep(id)on update cascadeon delete cascade);多对多关系多对多,在数据库中也⽐较常见,可以理解为是⼀对多和多对⼀的组合。
数据库关联映射建表图示(一对多、多对多)
数据库关联映射建表图示(一对多、多对多)数据库关联映射建表图示(一对多、多对多)2012-03-18 11:57一对一一对多多对多一对一:班级和班号,学生姓名和学号--一个表,一个主键一条信息一对多:班级和学生,学校和学校中的院系--两个表,A主表每条信息在B次表中有多条子分类对应多对多:学生和课程,教师和学生---A表一个主键B表一个主键 C关系表中一条信息记录两个表的id以示关系。
--------------明确主表和次表的关系就行了------------------------------------------------------------------------------------------------------------------------------------- 总结一下数据库的一对多、多对一、一对一、多对多关系以及对应的建表方式关联映射:一对多/多对一存在最普遍的映射关系,简单来讲就如球员与球队的关系;一对多:从球队角度来说一个球队拥有多个球员即为一对多多对一:从球员角度来说多个球员属于一个球队即为多对一数据表间一对多关系如下图:关联映射:一对一一对一关系就如球队与球队所在地址之间的关系,一支球队仅有一个地址,而一个地址区也仅有一支球队。
数据表间一对一关系的表现有两种,一种是外键关联,一种是主键关联。
图示如下:一对一外键关联:一对一主键关联:要求两个表的主键必须完全一致,通过两个表的主键建立关联关系关联映射:多对多多对多关系也很常见,例如学生与选修课之间的关系,一个学生可以选择多门选修课,而每个选修课又可以被多名学生选择。
数据库中的多对多关联关系一般需采用中间表的方式处理,将多对多转化为两个一对多。
数据表间多对多关系如下图:。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一对多的自身关联
一的一方和多的一方都属于同一个类
这种结构就类似于树状结构
每一个对象内部本身包括
一个父节点对象(此时这个原本的对象对于这个父节点对象是多对一的关系)
一个子节点的集合(此时这个对象对于子节点集合来说又是一对多的关系)
创建表
create table creature(
id bigint primary key,
name varchar(15),
parent_creature_id bigint
);
一对一关联第一种关联方式通过一个表的主键由另一个表来产生
第一张表
create table husband(
id varchar(100) primary key,
name varchar(100) default ''
)character set utf8 collate
utf8_general_ci;---能插入中文字符
create table wife(
id varchar(100) primary key,
name varchar(100) default ''
)character set utf8 collate utf8_general_ci;
Husband.hbm中uuid方式产生主键
<id name="id" unsaved-value="null">
<generator class="uuid.hex">
</generator>
</id>
<one-to-one name="wife" class="com.hibernate.model.Wife" fetch="join" cascade="all"></one-to-one>
在wife hbm中
<id name="id">
<generator class="foreign">
<param name="property">husband</param>
</generator>
</id>
<!-- constrained代表我将对方的主键作为我主键的约束--> <one-to-one name="husband" class="com.hibernate.model.Husband" constrained="true" fetch="select" cascade="none"></one-to-one>
</class>
Hibernate: insert into husband (name, id) values (?, ?)
Hibernate: insert into wife (name, id) values (?, ?)
public class Test_Normal {
public static void saveTeacherWithCascade() throws Exception{ Session session = HibernateUtil.currentSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Creature creator = new Creature("creator");
Creature fly = new Creature("fly");
Creature bird = new Creature("bird");
Creature dragon = new Creature("dragon");
bird.setParentCreature(fly);
fly.getChildCreatureSet().add(bird);
dragon.setParentCreature(fly);
fly.getChildCreatureSet().add(dragon);
fly.setParentCreature(creator);
creator.getChildCreatureSet().add(fly);
session.save(creator);
mit();
}catch(Exception e){
e.printStackTrace();
if(tx != null){
tx.rollback();
}
}finally{
session.close();
}
}
public static void main(String[] args)throws Exception { saveTeacherWithCascade();
}
}。