精华内容
下载资源
问答
  • MongoDB、Java与对象关系映射 MongoDB、Java与对象关系映射
  • JPA实体关系映射

    千次阅读 2015-08-27 18:09:54
    1、 实体关系映射 实体关系是指实体实体之间的关系,从方向上分为单向关联和双向关联,从实体数量上分为一对一、一对多、多对多等。对于任何两个实体,都要从这两个方面区分它们之间的关系。 单向关联是一个实体...


    实体关系是指实体与实体之间的关系,从方向上分为单向关联和双向关联,从实体数量上分为一对一、一对多、多对多等。对于任何两个实体,都要从这两个方面区分它们之间的关系。

    单向关联是一个实体中引用了另外一个实体,也即通过一个实体可以获取另一个实体对象的引用;双向关联是两个实体之间可以相互获取对方对象的引用。

    1、一对一

    学生和身份证是一对一的关系,下面将从单向关联和双向关联来分析。

    1.1、单向关联

    假设在学生实体中可以获取身份证对象的引用;反之,不能在身份证实体中获取学生对象的引用,则学生和身份证是一对一的单向关联关系,关系映射如下:

    @Entity

    @Table(name="t_IDCard")

    public class IDCard implements Serializable

    {

       private static final long  serialVersionUID   = 1L;

        private Stringnum;

       

        public IDCard()

        {

          

        }

        @Id

       @GeneratedValue

       public String getNum()

       {

          return num;

       }

     

       public void setNum(String num)

       {

          this.num =num;

       }

    /*

         * ....

         * */

    }

    @Entity

    @Table(name="t_student")

    public class Student implements Serializable

    {

       private static final long  serialVersionUID   = 1L;

       private int id;

       private IDCardidCard;

      

       public Student(){}

     

       @Id

       @GeneratedValue

       public int getId()

       {

          return id;

       }

     

       public void setId(intid)

       {

          this.id =id;

       }

     

       @OneToOne(cascade=CascadeType.ALL)

       @JoinColumn(name="IDCrad_id")

       public IDCardgetIdCard()

       {

          return idCard;

       }

      

       public void setIdCard(IDCard idCard)

       {

          this.idCard =idCard;

       }

    /*

         * ....

         * */

    }

     

    @OneToOne只能确定实体与实体的关系是一对一的关系,不能指定数据库表中的保存的关联字段,所以要结合@JoinColumn来指定关联字段。

    在默认情况下,关联实体(IDCard)的主键一般是用来做外键的。但如果此时不想将关联实体的主键作为外键,而是将其他字段作为关联字段(外键可以关联到其他表的主键上,也可以关联到其他表的非空字段上),此时需要设置@JoinColumn的referencedColumnName属性。

     

    1.2、双向关联

    @Entity

    @Table(name="T_IDCARD")

    public class IDCard implements Serializable

    {

       private static final long  serialVersionUID   = 1L;

        private Stringnum;

        private Studentstudent;

       

        public IDCard()

        {

          

        }

        @Id

       @GeneratedValue

       public String getNum()

       {

          return num;

       }

     

       public void setNum(String num)

       {

          this.num =num;

       }

      

       @OneToOne(mappedBy="idCard")

       public StudentgetStudent()

       {

          return student;

       }

       public void setStudent(Student student)

       {

          this.student =student;

       }

       /*

        * ....

        * */

      

    }

     

    @Entity

    @Table(name="T_STUDENT")

    public class Student implements Serializable

    {

       private static final long  serialVersionUID   = 1L;

       private int id;

       private IDCardidCard;

      

       public Student(){}

     

       @Id

       @GeneratedValue

       public int getId()

       {

          return id;

       }

     

       public void setId(intid)

       {

          this.id =id;

       }

     

       @OneToOne(cascade=CascadeType.ALL)

       @JoinColumn(name="idcard_id")

       public IDCardgetIdCard()

       {

          return idCard;

       }

     

       public void setIdCard(IDCard idCard)

       {

          this.idCard =idCard;

       }

        /*

         * ...

         **/

    }

     

    1.3、主键关联

    既让两个实体对象具有相同的主键值,以表明它们之间的一一对应的关系;而数据库不会有额外的字段来维护它们之间的关系,仅仅通过表的主键来关联,主键的值需要程序来显示维护,映射如下

    @Entity

    @Table(name="T_IDCARD")

    public class IDCard implements Serializable

    {

       private static final long  serialVersionUID   = 1L;

       private int id;

        private Stringnum;

        private Studentstudent;

       

        public IDCard()

        {

          

        }

       

    @Id

    @GeneratedValue

        public int getId()

       {

          return id;

       }

       public void setId(intid)

       {

          this.id =id;

       }

     

       public String getNum()

       {

          return num;

       }

     

       public void setNum(String num)

       {

          this.num =num;

       }

      

       @OneToOne

       @PrimaryKeyJoinColumn

       public StudentgetStudent()

       {

          return student;

       }

       public void setStudent(Student student)

       {

          this.student =student;

       }

       /*

        * ....

        * */

    }

    @Entity

    @Table(name="T_STUDENT")

    public class Student implements Serializable

    {

       private static final long  serialVersionUID   = 1L;

       private int id;

       private IDCardidCard;

      

       public Student(){}

     

       @Id

       @GeneratedValue

       public int getId()

       {

          return id;

       }

     

       public void setId(intid)

       {

          this.id =id;

       }

     

       @OneToOne

       @PrimaryKeyJoinColumn

       public IDCardgetIdCard()

       {

          return idCard;

       }

     

       public void setIdCard(IDCard idCard)

       {

          this.idCard =idCard;

       }

        /*

         * ...

         **/

    }

     

    1.4、总结

    1)     确定实体与实体之间的关系

    如果是一对一的关系,则使用@OneToOne

    2)     确定表结构的设计

    l  如果是外键关联,在关系维护端考虑默认的实体关系映射或配合@JoinColumn;

    l  如果表位于不同的数据中,可以采用主键关联,使用@PrimaryKeyJoinColumn;

    3)     确定实体关系的方向

    l  单向关联

    在保存关联关系的实体中,使用@JoinColumn;

    l  双向关联

    若为双向关联,则在保存关联关系(也即存在外键)的实体中,要配合@JoinColumn;在没有保存关联关系的实体中,要使用mappedBy属性明确所关联的实体。

    mappedBy用在双向关联中,mappedBy所在的实体为关系被维护端,而另一个实体为关系维护端(也即保存关联关系的一端)。

     

    2、一对多

    2.1、单向关联

    @Entity

    @Table(name="T_SCHOOL")

    public class School implements Serializable

    {

       private static final long  serialVersionUID   = 1L;

       private int id;

       private Stringname;

       public School()

       {

         

       }

     

       @Id

       @GeneratedValue

       public int getId()

       {

          return id;

       }

     

       public void setId(intid)

       {

          this.id =id;

       }

     

       public String getName()

       {

          return name;

       }

     

       public void setName(String name)

       {

          this.name =name;

       }

        /*

         * ...

         **/

    }

     

    @Entity

    @Table(name="T_STUDENT")

    public class Student implements Serializable

    {

       private static final long  serialVersionUID   = 1L;

       private int id;

       private Schoolschool;

      

       public Student(){}

     

       @Id

       @GeneratedValue

       public int getId()

       {

          return id;

       }

     

       public void setId(intid)

       {

          this.id =id;

       }

       

       @ManyToOne

       @JoinColumn(name="school_id")

       public SchoolgetSchool()

       {

          return school;

       }

     

       public void setSchool(School school)

       {

          this.school =school;

       }

     

        /*

         * ...

        **/

    }

    2.2、双向关联

    @Entity

    @Table(name="T_SCHOOL")

    public class School implements Serializable

    {

       private static final long  serialVersionUID   = 1L;

       private int id;

       private Stringname;

       privateSet<Student>students=new HashSet<Student>();

       public School()

       {

         

       }

     

       @Id

       @GeneratedValue

       public int getId()

       {

          return id;

       }

     

       public void setId(intid)

       {

          this.id =id;

       }

     

       public String getName()

       {

          return name;

       }

     

       public void setName(String name)

       {

          this.name =name;

       }

      

       @OneToMany(mappedBy="school", cascade=CascadeType.ALL)

       publicSet<Student> getStudents()

       {

          return students;

       }

     

       public void setStudents(Set<Student> students)

       {

          this.students =students;

       }

        /*

         * ...

         **/

    }

    @Entity

    @Table(name="T_STUDENT")

    public class Student implements Serializable

    {

       private static final long  serialVersionUID   = 1L;

       private int id;

       private Schoolschool;

      

       public Student(){}

     

       @Id

       @GeneratedValue

       public int getId()

       {

          return id;

       }

     

       public void setId(intid)

       {

          this.id =id;

       }

       

       @ManyToOne(optional=false)

       @JoinColumn(name="school_id")

       public SchoolgetSchool()

       {

          return school;

       }

     

       public void setSchool(School school)

       {

          this.school =school;

       }

     

        /*

         * ...

         **/

    }

    l   cascade:定义类和类之间的级联关系。级联关系定义对当前对象的操作将波及到关联类的对象,而且这种关系是递归调用的。如School与Student有级联删除关系,那么删除School时将同时删除关联的Student对象。如果Student还和其他对象之间有级联删除关系,那么这样的操作会一直递归执行下去。级联操作只有在persist、remove、refresh、merge方法调用时才会发生。

    l   option:指定级联方是否可以为空,默认为true,允许外键字段为空。若将其设置为false,则要求双发必须存在,也即外键字段不能为空。optional属性将影响关联查询的形式。例如通过find、getReference方法查询Student实体,当optional=false时,Student与School关联为innerjoin;当optional=true时,Student与School关联形式为leftjoin。

    2.3、表关联(双向)

    在一对多或多对一的关联关系中,除了使用默认的外键关联外;还可以使用表关联,多的一方可以作为关系表的主键(唯一性约束),而一的一方可以作为关系表另一个字段,如下

    @Entity

    @Table(name="T_SCHOOL")

    public class School implements Serializable

    {

       private static final long  serialVersionUID   = 1L;

       private int id;

       private Stringname;

       privateSet<Student>students=new HashSet<Student>();

       public School()

       {

       }

     

       @Id

       @GeneratedValue

       public int getId()

       {

          return id;

       }

     

       public void setId(intid)

       {

          this.id =id;

       }

     

       public String getName()

       {

          return name;

       }

     

       public void setName(String name)

       {

          this.name =name;

       }

      

       @OneToMany(mappedBy="school")

       public Set<Student>getStudents()

       {

          return students;

       }

     

       public void setStudents(Set<Student> students)

       {

          this.students =students;

       }

        /*

         * ...

         **/

    }

    @Entity

    @Table(name="T_STUDENT")

    public class Student implements Serializable

    {

       private static final long  serialVersionUID   = 1L;

       private int id;

       private Schoolschool;

      

       public Student(){}

     

       @Id

       @GeneratedValue

       public int getId()

       {

          return id;

       }

     

       public void setId(intid)

       {

          this.id =id;

       }

       

       @ManyToOne

       @JoinTable(name="SCHOOL_STUDENT",

                 joinColumns={

                             @JoinColumn(name="student_id",referencedColumnName="id")

                            },

                inverseJoinColumns={

                             @JoinColumn(name="school_id",referencedColumnName="id")

                              })

       public SchoolgetSchool()

       {

          return school;

       }

     

       public void setSchool(School school)

       {

          this.school =school;

       }

     

        /*

         * ...

         **/

    }

    l   name:中间表的名称;

    l   joinColumns:中间表中,指向关系维护端的外键;

    l   inverseJoinColumns:与joinColumns相似,指向中间表中关系被维护段的外键;

    2.4、总结

    1)确定实体与实体之间的关系

    如果是一对多的关系,则使用@OneToMany;如果是多对一的关系,使用@manyToOne。

    2)确定表结构的设计

    l  如果是外键关联,在关系维护端考虑默认的实体关系映射或配合@JoinColumn;

    l  如果是表关联,则在关系维护端使用@JoinTable

    3)确定实体关系的方向

    l  单向关联

    一般情况下,多的一方为关系维护端;在保存关联关系的实体中,使用@JoinColumn或@JoinTable;

    l  双向关联

    若为双向关联,则在关系维护端,配合@JoinColumn@JoinTable;在关系被维护端,要使用mappedBy属性明确所关联的实体。

    3、多对多

    3.1、单向关联

    @Entity

    @Table(name="T_TEACHER")

    public class Teacher implements Serializable

    {

     

       private static final long  serialVersionUID   = 1L;

        private int id;

        private Set<Student>students=new HashSet<Student>();

       

        public Teacher()

       {

       }

       

        @Id

        @GeneratedValue

       public int getId()

       {

          return id;

       }

       public void setId(intid)

       {

          this.id =id;

       }

       

       @ManyToMany(fetch=FetchType.LAZY)

       @JoinTable(name="TEACHER_STUDENT",

                   joinColumns={@JoinColumn(name="teacher_id")},

                   inverseJoinColumns={@JoinColumn(name="student_id")})

       publicSet<Student> getStudents()

       {

          return students;

       }

     

       public void setStudents(Set<Student> students)

       {

          this.students =students;

       }

      

        /*

         * ...

         **/

    }

    @Entity

    @Table(name="T_STUDENT")

    public class Student implements Serializable

    {

       private static final long  serialVersionUID   = 1L;

       private int id;

      

       public Student(){}

     

       @Id

       @GeneratedValue

       public int getId()

       {

          return id;

       }

     

       public void setId(intid)

       {

          this.id =id;

       }

     

        /*

         * ...

         **/

    }

     

    3.2、双向关联

    @Entity

    @Table(name="T_TEACHER")

    public class Teacher implements Serializable

    {

     

       private static final long  serialVersionUID   = 1L;

        private int id;

        private Set<Student>students=new HashSet<Student>();

       

        public Teacher()

       {

       }

       

        @Id

        @GeneratedValue

       public int getId()

       {

          return id;

       }

       public void setId(intid)

       {

          this.id =id;

       }

       

       @ManyToMany(fetch=FetchType.LAZY)

       @JoinTable(name="TEACHER_STUDENT",

                   joinColumns={@JoinColumn(name="teacher_id")},

                   inverseJoinColumns={@JoinColumn(name="student_id")})

       publicSet<Student> getStudents()

       {

          return students;

       }

     

       public void setStudents(Set<Student> students)

       {

          this.students =students;

       }

      

        /*

         * ...

         **/

    }

    @Entity

    @Table(name="T_STUDENT")

    public class Student implements Serializable

    {

       private static final long  serialVersionUID   = 1L;

       private int id;

       privateHashSet<Teacher>teachers=new HashSet<Teacher>();

      

       public Student(){}

     

       @Id

       @GeneratedValue

       public int getId()

       {

          return id;

       }

     

       public void setId(intid)

       {

          this.id =id;

       }

     

       @ManyToMany(mappedBy="students",fetch=FetchType.LAZY)

       publicHashSet<Teacher> getTeachers()

       {

          return teachers;

       }

     

       public void setTeachers(HashSet<Teacher> teachers)

       {

          this.teachers =teachers;

       }

        /*

         * ...

         **/

    }

    3.3、总结

      确定实体关系的方向

    l  单向关联

    在关系维护端使用@JoinTable;

    l  双向关联

    若为双向关联,则在关系维护端,使用@JoinTable;在关系被维护端,要使用mappedBy属性明确所关联的实体。

    4、集合类

    多的一方,在选用集合类时,需要注意一下几点:

    1)     在未确定使用Set还是List时,可以采用Collection来声明;

    2)     Set集合中的对象不能有重复,并且是无序的;

    3)     List集合中的对象可以有重复,并且可以排序,可以结合@OrderBy;

    4)     Map集合是key和value的集合,如果使用Map集合需要配合@MapKey来指定map中的key值。

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

    千次阅读 2018-08-03 10:52:40
     简单来说Hibernate是ORM映射的持久层框架,全称是(Object Relational Mapping),即对象关系映射。  它将数据库中的表映射成对应的对象,以对象的形式展现,这样我们就可以通过映射的对象来对数据库中的数据...

    一、什么是Hibernate中的关联映射?

      简单来说Hibernate是ORM映射的持久层框架,全称是(Object Relational Mapping),即对象关系映射。

      它将数据库中的表映射成对应的对象,以对象的形式展现,这样我们就可以通过映射的对象来对数据库中的数据进行间接的操作。

      关联映射是将数据库中的表映射成与之相对应的对象,当你对这个对象进行操作的时候,Hibernate会对数据库中对应的表执行相应的操作,你对该实体的操作实际上就是在间接的操作数据库中与之相对应的表。

      Hibernate正是实现了这种思想,达到了方便开发人员以面向对象的思想来实现对数据库的操作。 

    二、Hibernate主要实现的映射关系:

            

     

    三、Hibernate映射的基本结构

        hibernate在实现ORM功能的时候主要用到的文件有:映射类(*.Java)、映射文件(*.hbm.xml)和数据库配置文件(*.properties/*.cfg.xml),它们各自的作用如下。

            映射类(*.java):它是描述数据库表的结构,表中的字段在类中被描述成属性,将来就可以实现把表中的记录映射成为该类的对象了。

            映射文件(*.hbm.xml):它是指定数据库表和映射类之间的关系,包括映射类和数据库表的对应关系、表字段和类属性类型的对应关系以及表字段和类属性名称的对应关系等。

            数据库配置文件(*.properties/*.cfg.xml):它是指定与数据库连接时需要的连接信息,比如连接哪种数据库、登录数据库的用户名、登录密码以及连接字符串等。当然还可以把映射类的地址映射信息放在这里。

     

    四、hibernate中的关联关系有四种:一对一、一对多、多对一、多对多。

     

    1、单向关联与双向关联

     单向关联:单向关联是指只有一方有另一方的关联信息而另一方没有关联信息                    

      

        A——>B  

        A对象中有B对象的关联信息

        B对象中没有A对象的关联信息

        我们可以通过A对象中B的关联信息查询或修改B对象的信息但无法通过B对象来查询修改A对象的信息

     双向关联:双向关联是指两方都有另一方的关联信息

      

        A<——>B

        A对象中有B对象的关联信息

        B对象中也有A对象的关联信息

        我们可以通过A对象中B的关联信息查询或修改B对象的信息也可以通过B对象来查询修改A对象的信息

     

    单向关联一般在一方配置多方不进行配置

      如:一对多 单向关联在“一”的一方配置文件里进行配置,"多"的一方不进行配置

    双向关联两方都要配置

      如:一对多 双向关联在“一”的一方配置文件里需要配置,“多”的一方也需要进行配置

     

    2、一对一关联映射

      一对一关联:一对一是指一个对象对应一个对象  如:一个人只有一个身份证。

      在两个数据表之间的一对一关系可以有两种实现方法,其中一种就是通过两个表的主键相关联,另一种是通过外键相关联

        如:一个人(Person)对应一个地址(Address)代码如下。

     (1)一对一主键单向关联: 

        Person——>Address

    public class Person {
        private int personid;
        private String name;
        private int age;
        //在Person对象中有Address对象的关联信息
        private Address address;
     
    public class Address{
        //Address对象中没有Person对象的关联信息
        private int addressid;
        private String addressdetail;

    这种单方面有另一个对象的关联信息的时候我们称为单向关联,再来看一下两个表中的映射hbm.xml文件:

    Person.hbm.xml

    <hibernate-mapping>
        <class name="com.entity.Person" table="PERSON">
            <id name="personid" column="presonid">
                <!--基于主键关联时,主键生成策略是foreign,表明根据关联类生成主键-->
                <generator class="foreign">
                    <!--关联持久化类的属性名-->
                    <param name="property">address</param>
                </generator>
            </id>
            <property name="name"/>
            <property name="age"/>
            <!--constrained设定为true,表示的主键必须与Person中对应资料的主键相同。-->
            <one-to-one name="address" constrained="true"/>
        </class>
    </hibernate-mapping>

    单向关联和双向关联的区别主要在于单向只在一方配置而双向两方都要配置

    Address.hbm.xml 

    因为是单方面关联所以只在Person.hbm.xml中配置了关联信息而Address.hbm.xml中不做任何配置

    所以我们省略Address.hbm.xml

      …………

     

    (2)一对一主键双向关联:

      Person<——>Address

    public class Person implements java.io.Serializable { 
    
      private Long id; 
      private String name; 
      //双向关联中Person对象中有Adderss对象的关联信息  
      private Address address;
     
    public class Address implements java.io.Serializable { 
      private Long id; 
      //Adderss对象中也有Person对象的关联信息  
      private Person person; 
      private String detail;

    这种两方面都有另一个对象的关联信息的时候我们称为双向关联,再来看一下两个表中的映射hbm.xml文件:

    Person.hbm.xml

    <hibernate-mapping> 
      <class name="entity.Person" table="person"> 
        <id name="id" type="java.lang.Long"> 
          <column name="id" /> 
          <generator class="identity" /> 
        </id> 
        <property name="name" type="java.lang.String"> 
          <column name="name" length="24" not-null="true"> 
            <comment>姓名</comment> 
          </column> 
        </property> 
        <one-to-one name="address"/> 
      </class> 
    </hibernate-mapping>

    单向关联和双向关联的区别主要在于单向只在一方配置而双向两方都要配置 

    Address.hbm.xml

    <hibernate-mapping> 
      <class name="entity.Address" table="address" catalog="mydb"> 
        <id name="id" type="java.lang.Long"> 
          <column name="id" /> 
          <!-- class="foreign": 一对一主键映射中,使用另外一个相关联的对象的标识符 --> 
          <generator class="foreign"> 
            <param name="property">person</param> 
          </generator> 
        </id> 
        <property name="detail" type="java.lang.String"> 
          <column name="detail" length="120" not-null="true"> 
            <comment>详细地址</comment> 
          </column> 
        </property> 
        <!-- 表示在address表存在一个外键约束,外键参考相关联的表person --> 
        <one-to-one name="person" constrained="true" /> 
      </class> 
    </hibernate-mapping>

     当我们操作Person对象时,可以对Address对象进行操作,也可以操作Address对象时对Person对象进行操作这样就形成了双向的关联

    双向关联还需要在hibernate.cfg.xml中进行配置

    <hibernate-configuration> 
    
      <session-factory> 
        <property name="connection.username">root</property> 
        <property name="connection.url"> 
          jdbc:mysql://localhost:3306/testdb 
        </property> 
        <property name="dialect"> 
          org.hibernate.dialect.MySQLDialect 
        </property> 
        <property name="connection.password">xiaohui</property> 
        <property name="connection.driver_class"> 
          com.mysql.jdbc.Driver 
        </property> 
        <property name="show_sql">true</property> 
        <property name="format_sql">true</property> 
    
       <!--在hibernate.cfg.xml中配置hbm.xml文件-->
        <mapping resource="com/entity/Person.hbm.xml" /> 
        <mapping resource="com/entity/Address.hbm.xml" /> 
    
      </session-factory> 
    
    </hibernate-configuration>

    (3)一对一外键单向关联:

      Person——>Address

    public class Person {
        private int personid;
        private String name;
        private int age;
        private Address address;
     
    public class Address{
        private int addressid;
        private String addressdetail;

    Address.hbm.xml

    
    <!--address中不做任何配置所以我们省略-->
    
      …………………………
    
    <!--单向关联和双向关联的区别在于单向关联只在一方配置双向关联两方都要配置-->
    Person.hbm.xml
    <hibernate-mapping> 
            <class name="com.entity.Person" table="PERSON"> 
                    <id name="personid"> 
                            <generator class="identity"/> 
                    </id> 
                    <property name="name"/> 
                    <property name="age"/> 
                    <!--用来映射关联PO column是Address在该表中的外键列名,增加unique变成唯一的--> 
                    <many-to-one name="address" unique="true"/> 
            </class> 
    </hibernate-mapping>

    关联和主键关联不同的地方是采用<many-to-one>标签来映射,一对一唯一外键关联映射其实是多对一的特例。<many-to-one>指定多的一端unique为true,这样就限制了多的一端的多重性为一,就是这样来映射的。

    (4)一对一外键双向关联:

      Person<——>Address

    public class Person implements java.io.Serializable { 
    
      private Long id; 
      private String name; 
      private Address address;
     
    public class Address implements java.io.Serializable { 
      private Long id; 
      private Person person; 
      private String detail;

    Person.hbm.xml 

    <hibernate-mapping> 
      <class name="com.entity.Person" table="person"> 
        <id name="personid" type="java.lang.Long"> 
          <column name="personid" /> 
          <generator class="identity" /> 
        </id> 
        <property name="name" type="java.lang.String"> 
          <column name="name" length="24" not-null="true"> 
            <comment>姓名</comment> 
          </column> 
        </property> 
      <!--双向关联配置-->
        <one-to-one name="address" /> 
      </class> 
    </hibernate-mapping>

    Address.hbm.xml

    <hibernate-mapping> 
      <class name="com.entity.Address" table="address" catalog="testdb"> 
        <id name="addressid" type="java.lang.Long"> 
          <column name="addressid" /> 
          <generator class="identity" /> 
        </id> 
        <property name="detail" type="java.lang.String"> 
          <column name="detail" length="120" not-null="true"> 
            <comment>详细地址</comment> 
          </column> 
        </property> 
        <many-to-one name="person" class="entity.Person" unique="true"> 
          <column name="personid"> 
            <comment>人的ID</comment> 
          </column> 
        </many-to-one> 
      </class> 
    </hibernate-mapping>

    单向关联和双向关联的区别主要在于单向只在一方配置而双向两方都要配置所以一对一双向关联比单向关联多了一个在Person.hbm.xml文件中配置<one-to-one name="address" /> 

     双向关联还需要在hibernate.cfg.xml中进行配置

    <hibernate-configuration> 
    
      <session-factory> 
        <property name="connection.username">root</property> 
        <property name="connection.url"> 
          jdbc:mysql://localhost:3306/testdb 
        </property> 
        <property name="dialect"> 
          org.hibernate.dialect.MySQLDialect 
        </property> 
        <property name="connection.password">xiaohui</property> 
        <property name="connection.driver_class"> 
          com.mysql.jdbc.Driver 
        </property> 
        <property name="show_sql">true</property> 
        <property name="format_sql">true</property> 
    
       <!--在hibernate.cfg.xml中配置hbm.xml文件-->
        <mapping resource="com/entity/Person.hbm.xml" /> 
        <mapping resource="com/entity/Address.hbm.xml" /> 
    
      </session-factory> 
    
    </hibernate-configuration>

     注意:因为一对一的主键关联映射扩展性不好,当我们的需要发生改变想要将其变为一对多的时候变无法操作了,所以我们遇到一对一关联的时候经常会采用唯一外键关联来解决问题,而很少使用一对一主键关联。

     

    3、一对多关联映射

      一对多关联:一对多是指一个对象对应多个对象 同样也分为单向关联和双向关联 如:一个教室可以有多个学生

    (1) 一对多单向关联:

       Classes——>Student

    public class Classes {  
        private int id;  
        private String name;     
        //Set支持延迟加载因为多个学生所以我们用Set集合关联  
        private Set students;  
    }  
    public class Student {  
        private int id;  
        private String name;      
    }  

    单向关联只需在一方配置hbm.xml文件Student不需要配置所以就省略了 

    Classes对象中使用了set属性,但是只是说明了延迟加载的属性,并没有为属性配置对应的对象,属性的对象是要在映射文件中来配置的,需要添加set标签,并在set标签中添加<one-to-many>标签,具体如下代码:

    Classes.hbm.xml

    <hibernate-mapping>  
        <class name="com.hibernate.Classes" table="t_classes">  
            <id name="id">  
                <generator class="native"/>  
            </id>  
            <property name="name"/>  
            <set name="students">  
                <key column="classesid"></key>  
                <one-to-many class="com.hibernate.Student"></one-to-many>  
            </set>  
        </class>  
    </hibernate-mapping>  

    因为Classes一方是一方对应的Student是多方 所以我们要用<set>来关联一方

    Student.hbm.xml不做任何改变

      省略………………

     

    (2)一对多双向关联:

        Classes<——>Student

    public class Classes {  
        private int id;  
        private String name;     
        //Set支持延迟加载  
        private Set<Student> students;  
    }  
    public class Student {  
        private int id;  
        private String name; 
        //添加class对象关联信息因为是一方所以我们用一个对象关联
        private Classes classes;     
    }  

    Classes.hbm.xml

      因为与单向一对多配置一样所以就省略了 可以参考上面单向一对多的代码

    Student.hbm.xml

    双向我们需要两方都要配置代码如下:

    <hibernate-mapping>  
        <class name="com.hibernate.Student" table="t_student">  
            <id name="id">  
                <generator class="native"/>  
            </id>  
            <property name="name"/>  
            <!-- 在多的一端Student中添加一行新的Classes列 ,并且列的名称要和Classes.hbm.xml的列明相同-->  
            <many-to-one name="classes" column="classesid"></many-to-one>  
        </class>  
    </hibernate-mapping>  

     因为Student一方是多方对应的Classes是一方 所以我们要用<many-to-one>来关联一方

    4、多对多关联映射

     多对多关联:多对多关联是指多个对象对应多个对象 如:老师可以有多个学生,学生也可以有多个老师

    (1)多对多单向关联:

       Teacher——>Student

    public class Teacher {
        private int id;
        private String name;
        private Set<Student> students = new HashSet<Student>();
    }
    
    public class Student {
        private int id;
        private String name;
        private String title;
    }

    Teacher.hbm.xml

    <hibernate-mapping>  
        <class name="com.hibernate.Teacher" table="t_teacher">  
            <id name="id">  
                <generator class="native"/>  
            </id>  
            <property name="name"/>  
         <!--生成一张新表存放两个关联对象的ID-->
            <set name="students" table="Teacher_Sutdent">  
           <!--将Teacher表的外键关联 注意不是对象的属性是表中的字段-->
                <key column="teacher_id"></key>  
           <!--将Student表的外键关联 注意不是对象的属性是表中的字段--> 
           <many-to-many class="com.hibernate.Student" column="student_id"></many-to-many> 
          </set> 
       </class> 
    </hibernate-mapping>

    文件中要使用<many-to-many>标签,并且在标签中添加上对应的列关系,因为你要让两个对象中都要清楚它们之间的映射是如何使用的,并且在生成的关系表中哪一列是对应的自己的外键,所以要在该标签中指明,另外在<set>标签中添加table属性会指明要生成新表,下面的示例中添加了t_user_role,所以会生成新的关联表。 

    Student.hbm.xml不做任何配置所以省略

      …………

    (2)多对多双向关联:

      Teacher<——>Student

    public class Teacher {
        private int id;
        private String name;
        private Set<Student> students = new HashSet<Student>();
    }
    
    public class Student {
        private int id;
        private String name;
        private String title;
        private Set<Teacher> teachers = new HashSet<Teacher>();
    }

    Teacher.hbm.xml同单向多对多一样故省略

      …………

    Student.hbm.xml

    <hibernate-mapping>  
        <class name="com.hibernate.Student" table="t_student">  
            <id name="id">  
                <generator class="native"/>  
            </id>  
            <property name="name"/>  
         <!--生成一张新表存放两个表的Id-->
            <set name="teachers" table="Teacher_Student">  
           <!--将Teacher表的外键关联 注意不是对象的属性是表中的字段-->
                <key column="student_id"></key>  
           <!--将Student表的外键关联 注意不是对象的属性是表中的字段--> 
           <many-to-many class="com.hibernate.Teacher" column="teacher_id"></many-to-many> 
          </set> 
       </class> 
    </hibernate-mapping>

     

    5、多对一关联

        对比一对一关联映射和多对一唯一外键关联映射,其实它们两个都是使用了<many-to-one>本质上都是外键约束,只不过一对一的是唯一映射,需要添加unique="true"的属性,其它的它们两个是相同的。

      多对一关联:多对一关联是指多个对象对应一个对象 如:多个员工对应一个部门

    (1)多对一单向关联:

    public class Department {  
        private int id;  
        private String name;  
    }  
    
    public class Employee {  
        private int id;  
        private String name;  
        private Department depart;//注意这里是以部门的对象来作为员工的属性的,这个思想很关键,是建立起部门和员工关联的关键  
          
    }  

    Department.hbm.xml不做任何配置故省略  

      …………    

    Employee.hbm.xml

    <hibernate-mapping package="com.suo.domain">  
          
        <class name="Employee">  
            <id name="id">  
                <generator class="native"/>  
            </id>  
            <property name="name"/>  
            <many-to-one name="depart"></many-to-one>  
            <!-- many-to-one指明了外键 ,会根据反射机制,找到要和Employee建立多对一关系的类,该列默认的是可以为空的-->  
        </class>  
          
    </hibernate-mapping>  

    (2)多对一双向关联:

    public class Department {  
        private int id;  
        private String name;
        private Set<Employee> emps;//用集合来存储员工     
    }  
    
    public class Employee {  
        private int id;  
        private String name;  
        private Department depart;//注意这里是以部门的对象来作为员工的属性的,这个思想很关键,是建立起部门和员工关联的关键  
          
    }  

    Departement .hbm.xml

    <hibernate-mapping package="com.suo.domain">  
          
        <class name="Department">  
            <id name="id">  
                <generator class="native"/>  
            </id>  
            <property name="name"/>  
              
            <set name="emps">  
                <key column="depart_id"/><!-- key指明了员工表中的外键-->  
                <one-to-many class="Employee"/><!-- one-to-many指明了和哪个类进行一对多的映射 -->  
            </set>  
            <!--   
                用set标签表示Department中的员工集合的属性,这个属性并没有映射到数据库中的部门表中,  
                即部门表中,并没有emps这样的一个列。  
             -->  
        </class>  
          
    </hibernate-mapping>  

    Employee.hbm.xml同单向关联配置相同故省略

      …………

     

    五、 级联操作 Cascade:

    1、简单的介绍

    cascade和inverse (Employee – Department)

    l  Casade用来说明当对主对象进行某种操作时是否对其关联的从对象也作类似的操作,常用的cascade:

             none,all,save-update,delete, lock,refresh,evict,replicate,persist,

             merge,delete-orphan(one-to-many)。

       一般对many-to-one,many-to-many不设置级联,

         在<one-to-one>和<one-to-many>中设置级联。

    l  inverse表“是否放弃维护关联关系”(在Java里两个对象产生关联时,对数据库表的影响),在one-to-many和many-to-many的集合定义中使用,inverse=”true”表示该对象不维护关联关系;

       该属性的值一般在使用有序集合时设置成false(注意hibernate的缺省值是false)。

             one-to-many维护关联关系就是更新外键。many-to-many维护关联关系就是在中间表增减记录。

             注: 配置成one-to-one的对象不维护关联关系

     

    2、属性的解析
    class元素的lazy属性设定为true,表示延迟加载,如果lazy设为false,则表示立即加载。以下对这二点进行说明。
         立即加载:表示Hibernate在从数据库中取得数据组装好一个对象(如学生1)后, 会立即再从数据库取得数据组装此对象所关联的对象(如学生证1)。
         延迟加载:表示Hibernate在从数据库中取得数据组装好一个对象(如学生1)后,不会立即再从数据库中取得数据组装此对象所关联的对象(如学生1),而是等到需要时,才会从数据库取得数据组装此关联对象。

     

    <one-to-one>元素的cascade属性表明操作是否从父对象级联到被关联的对象,

    它的取得可以是以下几种:


         none:在保存,删除或修改当前对象时,不对其附属对象(关联对象)进行级联操作。它是默认值。
         save-update:在保存,更新当前对象时,级联保存,更新附属对象(临时对象,游离对象)。
         delete:在删除当前对象时,级联删除附属对象。
         all:所有情况下均进行级联操作,即包含save-update和delete操作。
         delete-orphan:删除和当前对象解除关系的附属对象。


    <one-to-one>元素的fetch属性的可选值是join和select,默认是select。当fetch属性设定为join时,表示连接抓取(Join fetching):Hibernate通过在Select语句中使用outer join(外连接)来获得对象的关联实例或者关联集合。

      当fetch属性设定为select时,表示查询抓取(Select fetching):需要另外发送一条Select语句抓取当前对象的关联实体或集合。

    3、代码练习

    <set name="emps" cascade="save-update">
     <key column="depart_id"/>
      <one-to-many class="Employee"/>
    </set>

    <set name="students" table="taacher_student" inverse="true"><!-- table是用来指定中间表的属性 -->
    <key column="teacher_id"></key><!-- 查找教师id时,链接中间表表的teacher_id -->
    <many-to-many class="Student" column="student_id"></many-to-many>
    </set>

    六、总结:

    1、单向关联

      (1)、一对一主键关联:单向关联时我们需要在有关联信息一方的配置文件里加入<one-to-one  constrained="true">并且将constrained属性设置为true 表示的主键必须与这个对象中对应资料的主键相同

      (2)、一对一外键关联:单向关联时我们需要在有关联信息一方的配置文件里加入<many-to-one unique="true">并且将unique属性设置为true 表示这个主键是唯一的

      (3)、一对多单向关联:单向关联时我们需要在有关联信息一方的配置文件里加入<set>在<set>中加入<one-to-many/>

          <set>  

             <key column="关联的外键">

             <one-to-many/>

          </set>

      (4)、多对多单向关联:单向关联时我们需要在有关联信息一方的配置文件里加入<set>在<set 中生成一张新表用来存放两个表的外键table="">中加入<key column="当前表的外键ID"><many-to-many clasee="关联对象路径" column="关联对象表的Id">

          <set table="">

              <key column=""/>

              <many-to-many class="" column="">

          </set>

      (5)、多对一单向关联:单向关联时我们需要在有关联信息一方的配置文件里加入<many-to-one>

     

    2、双向关联

      (2)、一对一主键关联:在从表的一方加入<one-to-oneconstrained="true">还需要在主表加入<one-to-one>

      (2)、一对一外键关联:除了在从表中加入<many-to-one unique="true">也需要在主表加入<one-to-one>

      (3)、一对多双向关联:除了在一方中加入<set><one-to-many></set>还需要在多放加入<many-to-one>

      (4)、多对多双向关联:需要在两方都加入<set><many-to-many></set>  注:<set>中的table="表名"   表明两方的配置要一样

           <set name="关联对象的属性名" table="生成一张新表">

             <key column="当前对象数据库表的外键"/>

             <many-to-many class="关联对象的类路径" column="关联对象数据库表的外键">

           </set>

         (5)、多对一双向关联:要在多方中加入<many-to-one>还要在一方中加入<set>

                <set>

                   <key column="关联外键"/>

                   <one-to-many>

                </set>

    展开全文
  • JPA对象关系映射——访问实体状态

    千次阅读 2015-03-31 22:26:39
    访问实体状态
    访问实体状态
    展开全文
  • 待办事项清单(使用Enity框架进行对象关系映射实验的实践)
  • 什么是ORM对象关系映射?

    千次阅读 2018-03-29 08:55:37
    作者:郭霖 第一行代码AndroidStudio开发工具书是o/r mapping 就是对象关系映射。 详细一点,是 面向对象编程中的 对象(Object) 和关系数据库的 关系(Relation) 的一个映射(Mapping)。 产生的原因是因为软件开发...
    作者:郭霖 第一行代码AndroidStudio开发工具书

    是o/r mapping 就是对象关系映射。
    详细一点,是 面向对象编程中的 对象(Object)
    和关系数据库的 关系(Relation)  
    的一个映射(Mapping)。
    
    产生的原因是因为软件开发已经是面向对象的了。  所有的值,操作都是基于
    对象的概念。
    而数据库还是关系数据库。记录的存储还是一条一条的。
    
    为了在逻辑上使得软件开发与存取数据库保持一致(都按照对象的概念进行开发,
    存取。)。才出现了这种or-mapping
    
    实际上,如果面向对象数据库成为主流,or-mapping就没用了。
    
    好处,就是上面所属的逻辑上的一致性,开发人员不必管数据库怎么存储,他只要知道要保存的也是一个对象(和他开发的概念一致)就可以了。
    
    没有O/R M之前,都是直接用SQL操作数据库,或者使用DAO之类的机制进行对象概念到关系数据库概念的转换。

    安卓开发中我们创建数据库是通过自定义一个类继承自SQLiteOpenHelper,然后在onCreate()方法中编写

    建表语句来实现的,而使用开源的Android数据库LitePal就不用这么麻烦了,它可以用面向对象的思维

    来操作数据库,而不用再和SQL语句打交道了。



    展开全文
  • 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简言之,ORM是通过使用描述对象和数据库之间映射 的元数据,把对象模型映射到数据库中。 ...
  • 对象关系映射

    千次阅读 2013-05-30 20:57:27
    ORM的全称是Object Relational Mapping,即对象关系映射。它的实质就是将关系数据(库)中的业务数据用对象的形式表示出来,并通过面向对象(Object-Oriented)的方式将这些对象组织起来,实现系统业务逻辑的过程。...
  • Hibernate之实体关系映射

    千次阅读 2015-03-06 09:27:40
    延迟加载即时加载 例如Person类和Email类是一对多关系,如果设为即时加载,当加载Person时,会自动加载Email,如果设置为延迟加载,当第一次调用person.getEmails()时才会执行SQL语句加载Email 注解配置时,@...
  • ORM,即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的...
  • 而如今我们要根据类来映射相应的表,那只能是通过类类之间的关系加上映射文件来映射数据库的表。我们学习UML建模,类类之间存在五种关系,继承,实现,关联,依赖,聚合/组合,在hibernate中实体类之间的
  • ORM-对象关系映射

    千次阅读 2015-12-13 13:03:27
    对象关系映射(Object Relational Mapping,简称ORM)是为了解决面向对象与关系型数据库存在的互不匹配的现象的技术。本质上就是将数据从一种形式转换到另外一种形式。 这也同时暗示着额外的执行开销;然而,如果ORM...
  • poi导出导入封装(使用注解建立实体与excel映射关系+反射设置实体属性值), poi导出导入封装(使用注解建立实体与excel映射关系+反射设置实体属性值) poi导出导入封装(使用注解建立实体与excel映射关系+反射设置...
  • 对象关系映射--ORM

    2018-09-05 01:13:52
    对象关系映射基础: 把代码中的类类之间的关系数据库中的实体表之间的关系关联起来,这就是ORM的核心思想。  
  • mysql数据库对象关系映射

    千次阅读 2017-07-15 23:47:49
    mysql数据库对象关系映射   1.对“对象关系映射”的理解   a.对象:可以理解为java中的类   b.关系:可以理解为数据库的表   c.映射:这是因为java中的数据的类型数据库的数据类型是有些不同的,...
  • MongoDB Java与对象关系映射

    千次阅读 2014-08-08 11:18:03
    导读:MongDB是一个优秀的NoSQL数据存储,有着大量...关键词:MongoDB Java 对象关系映射 NoSQL   MongoDB介绍  当今NoSQL领域中有很多有力的竞争者通过多种方式来处理海量数据问题。其中重要的解决
  • Hibernate实体关系映射—Annotation

    千次阅读 2016-04-07 21:31:25
    Hibernate实体关系映射分为:  单边一对一,双边一对一;  单边一对多,单边多对一;  双边一对多,双边多对一;  单边多对多,双边多对多;  以及主键相同的单双边一对一。下面分别总结这几种关系映射的注解...
  • 关联关系映射:关联关系是面向对象分析、面向对象设计最重要的知识,JPA完全可以正确处理这种关系。如果映射得当,JPA的映射可以大大简化持久层数据的访问。 关联关系分类: 1、单向关联:单向 1-1、单向 1-N、单向 ...
  • HarmonyOS 对象关系映射(Object Relational Mapping,ORM)数据库是一款基于 SQLite 的数据库框架,屏蔽了底层 SQLite 数据库的 SQL 操作,针对实体和关系提供了增删改查等一系列的面向对象接口。应用开发者不必再...
  • 使用mybatisPlus时,会确定实体类和数据的映射关系 具体的映射方法有两种: 1、默认:采用驼峰映射规则,例如MyUserTable 对应的数据库表为 my_user_table ; TEMyUserTable 对应表名为t_e_my_user_table; 2、注解...
  • 数据库设计,讲解业务实体对象到数据库表的映射关系
  • 对象关系映射ORM?

    千次阅读 2015-11-15 17:23:12
    对象关系映射(Object Relational Mapping,简称ORM)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将java程序中的对象自动持久...
  • Json格式与对象之间的映射关系

    千次阅读 2018-03-01 17:49:38
    Json格式与对象之间的映射关系大括号中括号 大括号({}):可以看作是一个对象,或者对应于程序中的对象对象中可以包含属性 大括号{}内部是采用key:value的形式,key可以是string,int等,value可以是string,int,...
  • MySql (四) ER图与实体关系映射

    千次阅读 2017-10-07 05:49:09
    实体关系映射什么是数据库的设计?数据库设计(Database Design)是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之能够有效地存储数据,满足各种用户的应用需求(信息要求和处理要求...
  • python-sqlite-orm:SQLite的Python对象关系映射
  • 实体关联关系映射

    千次阅读 2018-06-14 19:01:36
    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接。1.多对一单向关联类product引用了类factory,但是类factory没有引用类product。映射文件的配置&lt;many-to-one name="factory" class=&...
  • Hibernate 一对多的联系(Set关联) 对象关系映射

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 125,712
精华内容 50,284
关键字:

对象关系与实体关系映射