精华内容
下载资源
问答
  • 数据库设计--实体关系图(ERD)

    万次阅读 多人点赞 2015-08-01 15:15:17
    1、E-R图的定义 ...E-R图为实体-联系图,提供了表示实体型、属性和联系的方法,用来描述现实世界的概念模型。实体关系图表示信息系统概念模型的数据存储。 –百度百科 2.1E-R图表示法(Chen’s模型)

     

    1、E-R图的定义 

    实体关系图:简记E-R图是指以实体、关系、属性三个基本概念概括数据的基本结构,从而描述静态数据结构的概念模式。 –百度百科

     

     

    2、E-R的使用方法 

    E-R图为实体-联系图,提供了表示实体型、属性和联系的方法,用来描述现实世界的概念模型。实体关系图表示在信息系统中概念模型的数据存储。 –百度百科

     

     

    2.1E-R图表示法(Chen’s模型)

     

    2.2E-R表示法中各图形的定义

    实体:具有公共性质的可相互区别的现实世界对象的集合,可以是具体的,也可以是抽象的概念或联系。
    属性:实体所具有的模拟特性,一个实体可由若干个属性来刻画。
    关系:数据对象彼此之间相互联系的方式称为关系。
    关系连接线:用来连接实体与关系的线段。
     

    2.3E-R图的局部表示结构

     
         
      实体--属性 实体--关系 实体之间的关系
     

    2.4E-R图中实体与关系详解

    1.联系的类型
    (1)一对一联系(1:1)
    例如:一个球队只能有一个经理,一个经理只在一个球队任职,则球队和经理是一对一的。
    (2)一对多联系(1:n)
    例如:一门课程由一个教师任教,一个教师可以任教多门课程,则教师和课程是一对多的。
    (3)多对多联系(n:n)
    例如:一个学生可以选多门选修课,一门选修课可以被多个学生选修,则学生和选修课是多对多的。
     
    2.多实体之间的关系

    定义:在两个以上多个实体集之间,当一个实体集与其它实体集之间均(注意是均)存在相同关系,而其它实体集之间均(注意是均)没有关系时,这种关系才称之为多个实体集之间的关系。

    例如:有三个实体:供应商、零件、项目,一个供应商可以供应多个项目多个零件,每个项目可以使用多个供应商提供的零件,每种零件可以由不同供应商提供。
    分析这个例子,我们可以看出:供应商和零件是多对多的,供应商和项目是多对多的,但是项目和零件之间却是没有关系的
    这符合多实体之间关系的定义,所以可以画成如下形式:
     
    3.多实体之间的关系和多实体每两个实体之间的关系的区别
        例如:有三个实体:供应商、零件、项目,画出三个实体之间的关系和三个实体两两对应的关系
     
    三个实体之间的关系
     
     
    三个实体两两对应的关系
     
    由此,可以看出三个实体之间的关系和三个实体两两对应的关系是不等价的。
     

    2.5E-R图实例

     
     

     

     

     

    展开全文
  • ER实体关系

    千次阅读 2020-07-29 09:25:37
    实体关系图(Entity Relationship Diagram)指表示实体、属性和关系的图形化表示方式,用来描述现实世界的概念模型,简称E-R图。 人员和请假单这两个实体使用矩阵表示 实体的属性使用椭圆形表示 实体与实体之间...

    实体关系图(Entity Relationship Diagram)指表示实体、属性和关系的图形化表示方式,用来描述现实世界的概念模型,简称E-R图。

    人员和请假单这两个实体使用矩阵表示

    实体的属性使用椭圆形表示

    实体与实体之间的关系使用菱形表示

    人员实体与请假单实体具有1对多的关系,在菱形附近使用1和N表示

    展开全文
  • E-R实体关系介绍

    千次阅读 2018-11-06 17:28:39
    E-R图也称实体-联系图(Entity Relationship Diagram),提供了表示实体类型、属性和联系的方法,用来描述现实世界的概念模型。 它是描述现实世界关系概念模型的有效方法。是表示概念关系模型的一种方式。用“矩形框...

     1.介绍   

    E-R图也称实体-联系图(Entity Relationship Diagram),提供了表示实体类型、属性和联系的方法,用来描述现实世界的概念模型

    它是描述现实世界关系概念模型的有效方法。是表示概念关系模型的一种方式。用“矩形框”表示实体型,矩形框内写明实体名称;用“椭圆图框”表示实体的属性,并用“实心线段”将其与相应关系的“实体型”连接起来;

    用”菱形框“表示实体型之间的联系成因,在菱形框内写明联系名,并用”实心线段“分别与有关实体型连接起来,同时在”实心线段“旁标上联系的类型(1:1,1:n或m:n)。

    2.成分

    在ER图中有如下四个成分:

    矩形框:表示实体,在框中记入实体名。

    菱形框:表示联系,在框中记入联系名。

    椭圆形框:表示实体或联系的属性,将属性名记入框中。对于主属性名,则在其名称下划一下划线。

    连线:实体与属性之间;实体与联系之间;联系与属性之间用直线相连,并在直线上标注联系的类型。(对于一对一联系,要在两个实体连线方向各写1; 对于一对多联系,要在一的一方写1,多的一方写N;对于多对多关系,则要在两个实体连线方向各写N,M。)

    图:

    3.构图要素

     

    构成E-R图的3个基本要素是实体型、属性和联系,其表示方法为:

    实体

    一般认为,客观上可以相互区分的事物就是实体,实体可以是具体的人和物,也可以是抽象的概念与联系。关键在于一个实体能与另一个实体相区别,具有相同属性的实体具有相同的特征和性质。用实体名及其属性名集合来抽象和刻画同类实体在E-R图中用矩形表示,矩形框内写明实体名;比如学生张三、学生李四都是实体。如果是弱实体的话,在矩形外面再套实线矩形。

    属性

    实体所具有的某一特性,一个实体可由若干个属性来刻画。属性不能脱离实体,属性是相对实体而言的。在E-R图中用椭圆形表示,并用无向边将其与相应的实体连接起来;比如学生的姓名、学号、性别、都是属性。如果是多值属性的话,在椭圆形外面再套实线椭圆。如果是派生属性则用虚线椭圆表示。

    联系

    联系也称关系,信息世界中反映实体内部或实体之间的关联。实体内部的联系通常是指组成实体的各属性之间的联系;实体之间的联系通常是指不同实体集之间的联系。在E-R图中用菱形表示,菱形框内写明联系名,并用无向边分别与有关实体连接起来,同时在无向边旁标上联系的类型(1 : 1,1 : n或m : n)。比如老师给学生授课存在授课关系,学生选课存在选课关系。如果是弱实体的联系则在菱形外面再套菱形。

    4.E-R图绘制工具

    1.Visio

    1.1适用对象: IT 和商务专业人员

    1.2适用事务:就复杂信息、系统和流程进行可视化处理、分析和交流。使用具有专业外观的 Office Visio 图表,促进对系统和流程的了解,深入了解复杂信息并利用这些知识做出更好的业务决策。

    2.PowerDesigner

    2.1适用类型:是Sybase公司的CASE工具集

    2.2适用事务:使用它可以方便地对管理信息系统进行分析设计,它几乎包括了数据库模型设计的全过程。可以制作数据流程图、概念数据模型、物理数据模型,可以生成多种客户端开发工具的应用程序,还可为数据仓库制作结构模型,也能对团队设备模型进行控制。

    3.Erwin

    3.1适用类型:数据建模工具,是关系数据库应用开发的优秀CASE工具。

    3.2适用事务:支持各主流数据库系统,其设计图支持MS office的直接拷贝。ERwin也能与CA的Model Mart集成,满足企业建模的需求。

    4.SmatDraw

    4.1适用类型:商业绘图软件

    4.2适用事务:是世界上最流行的。轻松的绘制具有专业水准的商业图。

     

    展开全文
  • Hibernate之实体关系映射

    千次阅读 2015-03-06 09:27:40
    例如Person类和Email类是一对多关系,如果设为即时加载,当加载Person时,会自动加载Email,如果设置为延迟加载,当第一次调用person.getEmails()时才会执行SQL语句加载Email 注解配置时,@OnetToMany(Fetch = ...

    延迟加载与即时加载

    例如Person类和Email类是一对多关系,如果设为即时加载,当加载Person时,会自动加载Email,如果设置为延迟加载,当第一次调用person.getEmails()时才会执行SQL语句加载Email
    注解配置时,@OnetToMany(Fetch = FetchType.EAGER)为即时加载,Fetch = FetchType.LAZY为延迟加载
    延迟加载和即时加载的策略适用于所有一对多、多对一、多对多等所有的实体关系

    一般来说,延迟加载要比即时加载节省资源,但是如果处理不当,延迟加载容易抛出LazyInitializationException异常,解决当方法有两种,一种是在Session关闭之前调用一下,person.getEmails()方法,强迫Hibernate加载数据,这是最常用的方式,还有一种是延迟Session的范围,使Session关闭前完成所有的业务逻辑,在web程序中有些工具也能延长Session的范围,例如Spring的OpenSessionInViewFilter,能把Session扩大到所有的web资源,包括Servlet层、JSP层、DAO层、Service层


    单边一对多

    一方有集合属性,包含多个多方,而多方没有一方的引用
    import  javax.persistence.*;
    
    
    //“一"方
    @Entity
    @Table(name="tb_person")
    public  class Person{
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	private Integer id;
    
    
    	private String name;
    
    
    	@OneToMany(fetch = FetchType.EAGER,targetEntity = Email.class,cascade={
    		CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE, CascadeType.REFRESH
    	})
    	@JoinColumns(value={@JoinColumn(name="person_id",referencedColumnName="id")})
    	@OrderBy(value = email desc")
    	private List<Email> emails = new ArrayList<Email>();
    	//在email对应的表中产生一个person_id字段,引用person标的id
    	// referencedColumnName指的是实体类的关联列,默认为主键,可省略
    
    
    	//setter、getter略
    }
    
    
    //“多"方
    @Entity
    @Table(name="tb_email")
    public  class Email{
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	private Integer id;
    
    
    	private String email;
    
    
    	//setter、getter略
    }
    


    <hibernate-mapping  package="com.clf.hibernate.bean">
    	<class  name="Person" table="tb_person">
    		<id name="id" column="id">
    			<generator class="native">
    		</id>
    		<property name="name"/>
    		<bag name="emails" cascade="all" lazy="false" where="email like %@%" order-by="email">
    			<key column="email_id"></key>
    			<one-to-many class="com.clf.hibernate.bean.Email" />
    		</bag>
    	</class>
    </ hibernate-mapping >
    
    
    <hibernate-mapping  package="com.clf.hibernate.bean">
    	<class  name="Email" table="tb_eamil">
    		<id name="id" column="id">
    			<generator class="native">
    		</id>
    		<property name="email"/>
    	</class>
    </ hibernate-mapping >



    如果集合属性使用的是Set而非List,则XML配置时需要使用<set>标签而不是<bag>标签,而且不能使用order-by属性
    JPA(Java Persistence API)要求实体类必须为POJO,而不能为String等基本类型,换句话说,电子邮件必须封装为Email对象,即使它只有一个String属性
    而XML配置允许直接使用String作为实体类,而不需要封装成一个Email对象
    配置改动如下
    <bag name="emails" cascade="all" lazy="false" where="email like %@%" order-by="email">
    		<key column="email_id"></key>
    		<element type="String" column="email" />
    </bag>


    单边多对一

    //“一"方
    @Entity
    @Table(name = "tb_table")
    public class Type{
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	private Integer id;
    	
    	@Column(unique = true)
    	private String name;
    	//setter、getter方法略
    }
    //“多"方
    @Entity
    @Table(name = tb_article")
    public class Article{
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	private Integer id;
    
    
    	@ManyToOne(cascade = {CascadeType.PERSIST},fetch = FetchType.EAGER)
    	@JoinColumn(name = "type_id")
    	Private Type type;
    	//在article表总产生一个type_id字段,引用type表中的id字段
    
    
    	@Column(columnDefinition = "text")
    	private String content;
    
    
    	private String name;
    
    
    	//setter、getter方法略
    }


    <class  name="Type" table="tb_type">
    		<id name="id" column="id">
    			<generator class="native">
    		</id>
    		<property name="name"/>
    </class>
    
    
    <class  name="Article" table="tb_article">
    		<id name="id" column="id">
    			<generator class="native">
    		</id>
    		<property name="name"/>
    		<property name="content"/>
    		<many-to-one name = "type" column = "type_id" cascade = "persist" lazy="false" not-found="ignore">
    		</ many-to-one >
    </class>


    双边多对一、一对多

    //“一"方
    @Entity
    @Table(name = "tb_class")
    public class Clazz{
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	private Integer id;
    
    
    	private String name;
    	
    	//使用反向配置(@ManyToOne不存在该属性),双边关系中,控制权一般交给多方,定义在被拥有方,指向拥有方,拥有方能够级联地维护被拥有方的关系。因此这里没有配置数据库的外键,而只配置了一个mappedBy属性,告诉Hibernate,配置信息要到Student类的“clazz"属性中找
    	@OneToMany(mappedBy = "clazz")
    	private List<Student> students;
    
    
    	//setter、getter方法略
    }
    
    
    //“多"方
    @Entity
    @Table(name = "tb_student")
    public class Student{
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	private Integer id;
    
    
    	@ManyToOne(cascade = {CascadeType.PERSIST},fetch = FetchType.EAGER)
    	@JoinColumn(name = "class_id")
    	Private Clazz clazz;
    	//在student表总产生一个class_id字段,引用class表中的id字段
    
    
    	private String sex;
    
    
    	private String name;
    
    
    	//setter、getter方法略
    }


    <class  name="Clazz" table="tb_class">
    		<id name="id" column="id">
    			<generator class="native">
    		</id>
    		<property name="name"/>
    		<bag name="students" inverse="true" cascade="all">
    			<key column="class_id"/>
    			<one-to-many class="com.clf.hibernate.bean.Student"/>
    		</bag>
    </class>
    
    
    <class  name="Student" table="tb_student">
    		<id name="id" column="id">
    			<generator class="native">
    		</id>
    		<property name="name"/>
    		<property name="sex"/>
    		<many-to-one name = "clazz" column = "class_id" cascade = "all" >
    		</ many-to-one >
    </class>


    单边一对一

    有两种策略可以实现一对一的关联映射
    主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系;数据库表不会有额外的字段来维护它们之间的关系,仅通过表的主键来关联。
    唯一外键关联:外键关联,本来是用于多对一的配置,但是如果加上唯一的限制之后,也可以用来表示一对一关联关系。
    唯一外键关联策略
    @Entity
    public class IdCard {
      private int id;
      private String cardNo;
    
      @Id
      @GeneratedValue
      public int getId() {return id;}
    
    	//setter、getter略
    }
    
    @Entity
    public class Person {
     
      private IdCard idCard;//引用IdCard对象  
      private String name; 
      
      @Id
      @GeneratedValue
      private int id;
    
      @OneToOne
      @JoinColumn(name="idCard")	
      private IdCard idCard;	//引用IdCard对象
    
      private String name; 
      
    	//setter、getter略
    }
    


    <class name="com.clf.hibernate.IdCard" table="t_idcard">
          <id name="id" column="id">
              <generator class="native"/>
          </id>
          <property name="cardNo"/>
    </class>
    
    <class name="com.clf.hibernate.Person" table="t_person">
          <id name="id" column="id">
              <generator class="native"/>
          </id>
          <property name="name"/> 
    <!--在多的一端(当前Person一端),加入一个外键(当前为idCard)指向一的一端(当前IdCard),但多对一关联映射字段是可以重复的,所以需要加入一个唯一条件unique="true",这样就可以此字段唯一了。-->
          <many-to-one name="idCard" unique="true"/>
    </class>


    主键关联策略
    IdCart正常注解

    @Entity
    public class Person {
     
      private IdCard idCard;//引用IdCard对象  
      private String name; 
      
      @Id
      @GeneratedValue
      private int id;
    
      @OneToOne 
      @PrimaryKeyJoinColumn	//注解主键关联映射  
      private IdCard idCard;	//引用IdCard对象  
    
      private String name; 
      
    	//setter、getter略
    }



    <class name="com.clf.hibernate.IdCard" table="t_idcard">
          <id name="id" column="id">
              <generator class="native"/>
          </id>
          <property name="cardNo"/>
    </class>
    
    <class name="com.clf.hibernate.Person" table="t_person">
          <id name="id" column="id">
              <!--主键不是自己生成的,而是作为一个外键,所以使用foreign生成策略。foreign:使用另外一个相关联的对象的标识符,通常和<one-to-one>联合起来使用。再使用元素<param>的属性值指定相关联对象(这里Person相关联的对象为idCard,则标识符为idCard的id)为了能够在加载person数据同时加载IdCard数据,所以需要使用一个标签<one-to-one>来设置这个功能。  -->
                <generator class="foreign">
                    <!-- 元素<param>属性name的值是固定为property -->
                    <param name="property">idCard</param>
                </generator>
          </id>
          <property name="name"/> 
      <!--表示如何加载它的引用对象(这里引用对象就指idCard这里的name值是idCard),同时也说是一对一的关系。 默认方式是根据主键加载(把person中的主键取出再到IdCard中来取相关IdCard数据。) 我们也说过此主键也作为一个外键引用 了IdCard,所以需要加一个数据库限制(外键约束)constrained="true"     -->
           <one-to-one name="idCard" constrained="true"/>  
    </class>


    联合主键关联(Annotation方式)
    实现上联合主键的原理同唯一外键关联-单向一样,只是使用的是@JoinColumns,而不是@JoinColumn,实体类注解如下:
        @OneToOne
        @JoinColumns(
            {
                @JoinColumn(name="personId", referencedColumnName="id"),
                @JoinColumn(name="personName", referencedColumnName="name")
            }
        )
       private Person person;


       注意:@JoinColumns注解联合主键一对一联系,然后再使用@JoinColumn来注解当前表中的外键字段名,并指定关联哪个字段,使用referencedColumnName指定哪个字段的名称


    双边一对一

    凡是双向关联,必设mappedBy
    唯一外键关联策略
    @Entity
    public class IdCard {
     
      private String cardNo;
    
      @Id
      @GeneratedValue
      private int id;
    
      @OneToOne(mappedBy="idCard")
      private Person person;
    
    	//setter、getter略
    }
    
    @Entity
    public class Person {
     
      private IdCard idCard;//引用IdCard对象  
      private String name; 
      
      @Id
      @GeneratedValue
      private int id;
    
      @OneToOne
      @JoinColumn(name="idCard")	//为idCard对象指定外键
      private IdCard idCard;	//引用IdCard对象  
    
      private String name; 
      
    	//setter、getter略
    }



    <class name="com.clf.hibernate.IdCard" table="t_idcard">
          <id name="id" column="id">
              <generator class="native"/>
          </id>
          <property name="cardNo"/>
    	   <one-to-one name="person" property-ref="idCard"/>
    </class>
    <!-- 一对一 唯一外键 关联映射 双向 需要在另一端(当前IdCard),添加<one-to-one>标签,指示hibernate如何加载其关联对象(或引用对象),默认根据主键加载(加载person),外键关联映射中,因为两个实体采用的是person的外键来维护的关系,所以不能指定主键加载person,而要根据person的外键加载,所以采用如下映射方式:
    	<one-to-one>标签:告诉hibernate如何加载其关联对象
    property-ref属性:是根据哪个字段进行比较加载数据  -->
    
    <class name="com.clf.hibernate.Person" table="t_person">
          <id name="id" column="id">
              <generator class="native"/>
          </id>
          <property name="name"/> 
    <!--在多的一端(当前Person一端),加入一个外键(当前为idCard)指向一的一端(当前IdCard),但多对一关联映射字段是可以重复的,所以需要加入一个唯一条件unique="true",这样就可以此字段唯一了。-->
          <many-to-one name="idCard" unique="true"/>
    </class>


    主键关联策略
    @Entity
    public class IdCard {
     
      private String cardNo;
    
      @Id
      @GeneratedValue
      private int id;
    
      @OneToOne(mappedBy="idCard")
      private Person person;
    
    	//setter、getter略
    }
    
    @Entity
    public class Person {
     
      private IdCard idCard;//引用IdCard对象  
      private String name; 
      
      @Id
      @GeneratedValue
      private int id;
    
      @OneToOne 
      @PrimaryKeyJoinColumn	//注解主键关联映射  
      private IdCard idCard;	//引用IdCard对象  
    
      private String name; 
      
    	//setter、getter略
    }

    <class name="com.clf.hibernate.IdCard" table="t_idcard">
          <id name="id" column="id">
              <generator class="native"/>
          </id>
          <property name="cardNo"/>
    	   <one-to-one name="person"/>
    </class>
    
    
    
    <class name="com.clf.hibernate.Person" table="t_person">
          <id name="id" column="id">
                <generator class="foreign">
                    <param name="property">idCard</param>
                </generator>
          </id>
          <property name="name"/> 
          <one-to-one name="idCard" constrained="true"/>  
    </class>


    单边多对多

    @Entity
    public class User {
      private int id;
      private String name;
      private Set<User> roles = new HashSet<User>();// Role对象的集合  @Id
      
    @GeneratedValue
      public int getId() {return id;}
     
      @ManyToMany
      @JoinTable(name="u_r",//使用@JoinTable标签的name属性注解第三方表名称
              joinColumns={@JoinColumn(name="userId")},
    //使用joinColumns属性来注解当前实体类在第三方表中的字段名称并指向该对象
              inverseJoinColumns={@JoinColumn(name="roleId")}
    //使用inverseJoinColumns属性来注解当前实体类持有引用对象在第三方表中的字段名称并指向被引用对象表
      )
      public Set<User> getRoles() {return roles;
    }



    Role实体正常注解

    Role映射文件:
    <class name="com.clf.hibernate.Role" table="t_role">
            <id name="id">
                <generator class="native"/>
            </id>
            <property name="name" column="name"/>
    </class>
    
    User映射文件:
        <class name="com.clf.hibernate.User" table="t_user">
            <id name="id"column="id">
                <generator class="native"/>
            </id>
            <property name="name"/>
    <!--使用<set>标签映射集合(set),标签中的name值为对象属性名(集合roles),而使用table属性是用于生成第三方表名称,例:table="t_user_role",但是第三方面中的字段是自动加入的,作为外键分别指向其它表。
    所以表<key>标签设置,例:<key column="userid"/>,意思是:在第三方表(t_user_role)中加入一个外键并且指向当前的映射实体类所对应的表(t_user).使用<many-to-many>来指定此映射集合所对象的类(实例类),并且使用column属性加入一个外键指向Role实体类所对应的表(t_role) -->
            <set name="roles" table="t_user_role">
                <key column="userid"/>
                <many-to-many class="com.clf.hibernate.Role" column="roleid"/>
            </set>
    </class>


    双边多对多

    User实体类的注解与单边多对多一样

    Role实体类注解也非常的简单:使用@ManyToMany注解,并使用mappedBy属性指定引用对象持有自己的的属性名
    @Entity
    public class Role {
      private int id;
      private String name;
      private Set<User> users = new HashSet<User>();
    
      @Id
      @GeneratedValue
      public int getId() {return id;  }
    
      @ManyToMany(mappedBy="roles")
      public Set<User> getUsers() {return users;}
    
      public voidsetUsers(Set<User> users) {this.users = users;  
    }
    


    <class name="com.clf.hibernate.User" table="t_user">
            <id name="id"column="id">
                <generator class="native"/>
            </id>
            <property name="name"/>
            <set name="roles" table="t_user_role">
                <key column="userid"/>
                <many-to-many class="com.clf.hibernate.Role" column="roleid"/>
            </set>
        </class>
    
    <class name="com.clf.hibernate.Role" table="t_role">
            <id name="id">
                <generator class="native"/>
            </id>
            <property name="name" column="name"/>
            <set name="users" table="t_user_role"order-by="userid">
                <key column="roleid"/>
                <many-to-many class="com.clf.hibernate.User" column="userid"/>
            </set>  
    </class>


    component(组件)关联映射

    例如有以下两个实体类:用户与员工,两者存在很多相同的字段,但是两者有不可以是同一个类,这样在实体类中每次都要输入很多信息,现在把其中共有部分抽取出来成为一个类,然后在用户、员工对象中引用就可以
    值对象没有标识,而实体对象具有标识,值对象属于某一个实体,使用它重复使用率提升,而且更清析。
    以上关系的映射称为component(组件)关联映射
    在hibernate中,component是某个实体的逻辑组成部分,它与实体的根本区别是没有oid,component可以成为是值对象(DDD)。
    采用component映射的好处:它实现了对象模型的细粒度划分,层次会更加分明,复用率会更高。
    <class name="com.clf.hibernate.User" table="t_user">
          <id name="id" column="id">
              <generator class="native"/>
          </id>
          <property name="name" column="name"/>
          <component name="contact">
              <property name="email"/>
              <property name="address"/>
              <property name="zipCode"/>
              <property name="contactTel"/>          
          </component>
      </class>


    @Entity
    public class User {
        private int id;
        private String name;   
        private Contact contact;//值对象的引用   
    
        @Id
        @GeneratedValue
        public int getId() {    return id;}
    
        @Embedded//用于注解组件映射,表示嵌入对象的映射
        public Contact getContact() {return contact;}
        public void setContact(Contactcontact) {this.contact = contact;} 
    


    Contact类是值对象,不是实体对象,是属于实体类的某一部分,因此没有映射文件

    Contact值对象:
    public class Contact {
      private String email;  
      private String address;
      private String zipCode;
      private String contactTel;
      //setter、getter略
    }


    继承关联映射

    继承映射:就是把类的继承关系映射到数据库里(首先正确的存储,再正确的加载数据)
    继承关联映射的分类:
    单表继承:每棵类继承树使用一个表(table per class hierarchy)
    具体表继承:每个子类一个表(table per subclass)
    类表继承:每个具体类一个表(table per concrete class)(有一些限制)

    下面用一个实例来说明三种继承关系的用法和区别:

    动物Animal有三个基本属性,然后有一个Pig继承了它并扩展了一个属性,还有一个Brid也继承了并且扩展了一个属性


     
    Animal实体类:
    public class Animal {
      private int id;
      private String name;   
      private boolean sex;
      public int getId() {return id;  }
      public void setId(int id) { this.id = id;}
      public String getName() {return name;}
      public void setName(Stringname) {this.name = name;}
      public boolean isSex() {return sex;}
      public void setSex(boolean sex) {this.sex = sex;} 
    }


    Pig实体类:
    public class Pig extends Animal {
      private int weight;
      public int getWeight() {return weight;}
      public void setWeight(int weight) {this.weight = weight;}
    }


    Bird实体类:
    public class Bird extends Animal {
      private int height;
      public int getHeight() {return height;}
      public void setHeight(int height) {this.height = height;} 
    }
    


    单表继承
    把所有的属性都要存储表中,目前至少需要5个字段,另外需要加入一个标识字段(表示哪个具体的子类)
     
    其中:
               ①、id:表主键
               ②、name:动物的姓名,所有的动物都有
               ③、sex:动物的性别,所有的动物都有
               ④、weight:只有猪才有
               ⑤、height:只有鸟才有
               ⑥、type:表示动物的类型;P表示猪;B表示鸟
      <class name="Animal" table="t_animal" lazy="false">
          <id name="id">
              <generator class="native"/>
          </id>
          <discriminator column="type" type="string"/>
          <property name="name"/>
          <property name="sex"/>
          <subclass name="Pig" discriminator-value="P">
              <property name="weight"/>
          </subclass>
          <subclass name="Bird" discriminator-value="B">
              <property name="height"/>
          </subclass>
      </class>


    父类用普通的<class>标签定义
    在父类中定义一个discriminator,即指定这个区分的字段的名称和类型,如:<discriminator column="XXX" type="string"/>
    子类使用<subclass>标签定义,在定义subclass的时候,需要注意如下几点:
    Subclass标签的name属性是子类的全路径名
    在Subclass标签中,用discriminator-value属性来标明本子类的discriminator字段(用来区分不同类的字段)  的值Subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标  签平行。 当subclass标签的定义与class标签平行的时候,需要在subclass标签中,添加extends属性,里面的值  是父类的全路径名称。子类的其它属性,像普通类一样,定义在subclass标签的内部。

    annotation注解
    父类中注解如下:
    使用@Inheritance注解为继承映射,再使用strategy属性来指定继承映射的方式
    strategy有三个值:InheritanceType.SINGLE_TABLE           单表继承
                      InheritanceType.TABLE_PER_CLASS       类表继承
                      InheritanceType.JOINED                具体表继承
    再使用@DiscriminatorColumn注意标识字段的字段名,及字段类型
    在类中使用@DiscriminatorValue来注解标识字段的值
    @Entity
    @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
    @DiscriminatorColumn(
    name="discriminator",
    discriminatorType=DiscriminatorType.STRING)
    @DiscriminatorValue("type")
    public class Animal {……}


    继承类中注解如下:

        只需要使用@DiscriminatorValue来注解标识字段的值


    具体表继承
    每个类映射成一个表(table per subclass),所以Animal也映射成一张表(t_animal),表中字段为实体类属性
    而pig子类也需要映射成一张表(t_pid),但为了与父类联系需要加入一个外键(pidid)指向父类映射成的表(t_animal),字段为子类的扩展属性。Bird子类同样也映射成一张表(t_bird),也加入一个外键(birdid)指向父类映射成的表(t_animal),字段为子类的扩展属性。
    <class name="com.clf.hibernate.Animal" table="t_animal">
            <id name="id"column="id"><!-- 映射主键 -->
                <generator class="native"/>
            </id>
            <property name="name"/><!-- 映射普通属性 -->
            <property name="sex"/>
            <!--joined-subclass标签:每个类映射成一个表 -->
            <joined-subclass name="com.clf.hibernate.Pig" table="t_pig">
    <!-- <key>标签:会在相应的表(当前映射的表)里,加入一个外键 , 参照指向当前类的父类(当前Class标签对象的表(t_animal))-->
                <key column="pigid"/>
                <property name="weight"/>
            </joined-subclass>
            <joined-subclass name="com.clf.hibernate.Bird" table="t_bird">
                <key column="birdid"/>
                <property name="height"/>
            </joined-subclass>
        </class>


    这种策略是使用joined-subclass标签来定义子类的。父类、子类,每个类都对应一张数据库表。
    在父类对应的数据库表中,实际上会存储所有的记录,包括父类和子类的记录;在子类对应的数据库表中,这个表只定义了子类中所特有的属性映射的字段。子类与父类,通过相同的主键值来关联。实现这种策略的时候,有如下步骤:
    父类用普通的<class>标签定义即可
    父类不再需要定义discriminator字段
    子类用<joined-subclass>标签定义,在定义joined-subclass的时候,需要注意如下几点:
    Joined-subclass标签的name属性是子类的全路径名
    Joined-subclass标签需要包含一个key标签,这个标签指定了子类和父类之间是通过哪个字段来关联的。如:<key column="PARENT_KEY_ID"/>,这里的column,实际上就是父类的主键对应的映射字段名称。Joined-subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标签平行。 当Joined-subclass标签的定义与class标签平行的时候,需要在Joined-subclass标签中,添加extends属性,里面的值是父类的全路径名称。子类的其它属性,像普通类一样,定义在joined-subclass标签的内部。

    annotation注解
    因为子类生成的表需要引用父类生成的表,所以只需要在父类设置具体表继承映射就可以了,其它子类只需要使用@Entity注解就可以了
    @Entity
    @Inheritance(strategy=InheritanceType.JOINED)
    public class Animal {……}

    具体表继承效率没有单表继承高,但是单表继承会出现多余的庸于字段,具体表层次分明


    类表继承
    每个具体类(Pig、Brid)映射成一个表(table per concrete class)(有一些限制)
    <class name="com.clf.hibernate.Animal" table="t_animal">
            <id name="id"column="id"><!-- 映射主键 -->
                <generator class="assigned"/><!-- 每个具体类映射一个表主键生成策略不可使用native -->       
    		 </id>  
            <property name="name"/><!-- 映射普通属性 -->
            <property name="sex"/>
            <!--使用<union-subclass>标签来映射"每个具体类映射成一张表"的映射关系,实现上上面的表t_animal虽然映射到数据库中,但它没有任何作用。      -->
            <union-subclass name="com.clf.hibernate.Pig" table="t_pig">
                <property name="weight"/>
            </union-subclass>
            <union-subclass name="com.clf.hibernate.Bird" table="t_bird">
                <property name="height"/>
            </union-subclass>
    </class>


    如果不想t_animal存在(因为它没有实际的作用),可以设置<class>标签中的abstract="true"(抽象表),这样在导出至数据库时,就不会生成t_animal表了
    这种策略是使用union-subclass标签来定义子类的。每个子类对应一张表,而且这个表的信息是完备的,即包含了所有从父类继承下来的属性映射的字段(这就是它跟joined-subclass的不同之处,joined-subclass定义的子类的表,只包含子类特有属性映射的字段)。实现这种策略的时候,有如下步骤:
    父类用普通<class>标签定义即可
    子类用<union-subclass>标签定义,在定义union-subclass的时候,需要注意如下几点:
    Union-subclass标签不再需要包含key标签(与joined-subclass不同)
    Union-subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标签平行。 当Union-subclass标签的定义与class标签平行的时候,需要在Union-subclass标签中,添加extends属性,里面的值是父类的全路径名称。子类的其它属性,像普通类一样,定义在Union-subclass标签的内部。这个时候,虽然在union-subclass里面定义的只有子类的属性,但是因为它继承了父类,所以,不需要定义其它的属性,在映射到数据库表的时候,依然包含了父类的所有属性的映射字段。
    注意:在保存对象的时候id是不能重复的(不能使用自增生成主键)

    annotation注解
    只需要对父类进行注解就可以了,因为子类表的ID是不可以重复,所以一般的主键生成策略已经不适应了,只有表主键生成策略。
    首先使用@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)来注解继承映射,并且使用具体表继承方式,使用@TableGenerator来申明一个表主键生成策略再在主键上@GeneratedValue(generator="t_gen", strategy=GenerationType.TABLE)来注解生成策略为表生成策略,并且指定表生成策略的名称继承类只需要使用@Entity进行注解就可以了
    @Entity
    @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
    @TableGenerator(
          name="t_gen",
          table="t_gen_table",
          pkColumnName="t_pk",
          valueColumnName="t_value",
          pkColumnValue="person_pk",
          initialValue=1,
          allocationSize=1
          )



    三种继承关联映射的区别:
    第一种:它把所有的数据都存入一个表中,优点:效率好(操作的就是一个表);缺点:存在庸于字段,如果将庸于字段设置为非空,则就无法存入数据;
    第二种:层次分明,缺点:效率不好(表间存在关联表)
    第三种:主键字段不可以设置为自增主键生成策略。
    展开全文
  • 数据库实体关系笔记

    千次阅读 2017-03-30 09:12:49
    判断实体关系只需要问自己两个问题: 1. 实体A包含实体B吗? 2. 实体B包含实体A吗? - 都回答‘是’-->M:N - 都回答‘否’-->1:1 - 答案不同 --> 1:N ---- 当实在是不能分辨两个实体间的关系是 一对多 还是 多...
  • 什么是实体关系图(ERD)?

    千次阅读 2020-07-13 14:53:19
    数据库是软件系统不可或缺的一个组成部分,若能数据库工程好好利用 ER 图,便能让您生成高质量的数据库设计,用于数据库创建,管理和维护,也为人员间的交流提供了具意义的基础。 实体关系图(ERD) 今天,...
  • nlp实体关系抽取方法总结

    千次阅读 2020-07-04 21:23:00
    联合抽取实体关系抽取的解码方式与Q2实体抽取的解码方式基本一致,主要包括:序列标注CRF/SoftMax、指针网络、分类SoftMax、Seq2Seq等。基于共享参数的联合抽取,实体抽取loss会与关系抽取loss相加。 ...
  • PD的CDM模型的三种实体关系

    千次阅读 2015-05-22 18:07:50
    PD的CDM模型的三种实体关系 CDM是大多数开发者使用PD时最先创建的模型,也是整个数据库设计最高层的抽象。CDM是建立传统的ER图模型理论之上的,ER图有三大主要元素:实体型,属性和联系。其中实体型对应到...
  • 关于PowerDesigner实体关系模型(CDM)关于实体关系的使用一直有些疑惑,最近正好设计一套系统,所以用PD做了一些测试,记录如下 我们使用PDCDM的时候可定会遇到处理Entities见关系的情况,但是CDM...
  • uml之实体关系

    万次阅读 2019-05-19 00:44:54
    什么是实体关系图(ERD)? 数据库是软件系统不可或缺的一个组成部分,若能数据库工程好好利用 ER 图,便能让您生成高质量的数据库设计,用于数据库创建,管理和维护,也为人员间的交流提供了具意义的基础。 ...
  • E-R图也称实体-联系图(Entity Relationship Diagram),提供了表示实体类型、属性和联系的方法,用来描述现实世界的概念模型。 它是描述现实世界关系概念模型的有效方法。是表示概念关系模型的一种方式。用“矩形框...
  • 实体关系抽取任务方法及SOTA模型总结

    千次阅读 多人点赞 2020-05-31 21:02:08
    对于实体关系抽取任务,最容易想到的方法就是先抽取句子实体,然后实体对进行关系分类,从而找出spo三元组,这种思想被称作管道模型(Pipeline)。管道模型把实体关系抽取分成了两个子任务,实体识别和关系...
  • ER图(实体关系图)怎么画?

    千次阅读 多人点赞 2020-11-27 19:56:32
    E-R图又称实体关系图,是一种提供了实体,属性和联系的方法,用来描述现实世界的概念模型。通俗点讲就是,当我们理解了实际问题的需求之后,需要用一种方法来表示这种需求,概念模型就是用来描述这种需求。 比如...
  • 数据库:E-R图也称实体-联系图(Entity Relationship Diagram),提供了表示实体类型、属性和联系的方法,用来描述现实世界的概念模型。 实体之间的关系有 一对一(如一个学生对应一个档案,一个档案对应一个学生)...
  • 实体关系图(数据库资料)

    千次阅读 2011-01-26 12:06:00
    E-R图为实体-联系图,提供了表示实体型、属性和联系的方法,用来描述现实世界的概念模型。E-R模型最常见的运用是数据库设计的分析阶段,也就是数据库设计者和数据库用户之间的沟通工具和桥梁。E-R模型的作用是建构...
  • 文章标题:Entity-Relation Extraction as Multi-turn Question Answering(实体关系提取作为多轮问题的回答)ACL2019 Abstract 本文提出了一种新的实体关系抽取方法。我们将任务转换为一个多回合的问题回答问题,即...
  • 知识抽取-实体关系抽取

    千次阅读 2020-06-30 22:15:52
    知识抽取涉及的“知识”通常是清楚的、事实性的信息,这些信息来自不同的来源和结构,而对不同数据源进行的知识抽取的方法各有不同,从结构化数据获取知识用 D2R,其难点在于复杂表数据的处理,包括嵌套表、多列、...
  • PowerDesigner概念模型实体关系说明

    万次阅读 2009-03-13 08:56:00
    PowerDesigner的概念模型实体之间的关系是非常重要的,也决定了从概念模型转化到物理模型时的表现形式,所以有必须深究其中的相关设置。做数据库重要的就是表与表之间的关系,而这个关系是连接所有数据库系统...
  • MySql (四) ER图与实体关系映射

    千次阅读 2017-10-07 05:49:09
    实体关系映射什么是数据库的设计?数据库设计(Database Design)是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之能够有效地存储数据,满足各种用户的应用需求(信息要求和处理要求...
  • 概念设计(Conceptual Design) —— 设计实体关系模型 (ER Model) 逻辑设计(Logical Design)—— 实现从 ER 模型到关系模式(Relation Schemas)的转换。 物理设计(Physical Design) 本文主...
  • 我们先说说CDM和PDM的区别: ...信息系统的概念设计工具,即实体-联系图(E-R图),CDM就是以其自身方式来描述E-R图。此时不考虑物理实现的细节,只表示数据库的整体逻辑结构,独立于任何软件和数据存储结构。
  • ER图(实体-联系图)

    万次阅读 多人点赞 2019-02-14 11:00:45
    概念 E-R图也称实体-联系图(Entity Relationship Diagram),提供了表示实体类型、属性和联系的方法,用来描述现实世界的概念模型。 构成 ER图有实体(entity)、属性...用”菱形框“表示实体型之间的关系菱形...
  • 数据库实体间多对多关系处理

    千次阅读 2013-04-14 10:30:38
    数据库实体间多对多关系处理   数据库实体间有三种对应关系:一对一,一对多,多对多。 一对一关系示例:一个学生对应一个...这三种关系在数据库逻辑结构处理分析:   1.一对多关系处理: 我们以学生和班级之
  • 文章标题:Joint Extraction of Entities and Relations Based on a Novel Tagging Scheme(基于新标注方案的实体关系联合抽取)ACL2017 Outstanding Paper 文章出处:中国科学院 作者对本文的报告PPT:ht...
  • 数据库实体间有三种对应关系:一对一,一对多,多对多。...这三种关系在数据库逻辑结构处理分析:1.一对多关系处理: 我们以学生和班级之间的关系来说明一对多的关系处理方法。 假设现有基本表学生表
  • 例如“马云”和“阿里巴巴”分别属于实体中的人名和机构名,而它们是具有一定关系的。 ~~~~~~~~ 命名实体识别和关系抽取之后,需要对所产生的数据进行整合,三元组是能够描述整合后的最好方式。三元组是指(实体1...
  • 本体( ontology)最先是被哲学领域研究者提出,其作用主要是为了更好地描述客观事物,对客观事物描述的过程,根据描述对象的共性将客观事物抽象为系统化的概念或专业术语。 概括而言,本体是基于自身对客观...
  • CMP实体BEAN使用BLOB数据类型

    千次阅读 2005-06-23 10:35:00
    主题:CMP实体BEAN使用BLOB数据类型作者:Debu Panda翻译:蔡毅(caiyi0903@hotmail.com)时间:2005-6-23Oracle这样的关系数据库,CLOB和BLOB类型被用来存放大对象。BOLB表示二进制大对象,这种数据类型...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 126,917
精华内容 50,766
关键字:

在关系中用来表示实体的是