才高行厚的hibernate(2)---hibernate的映射

来源:互联网 发布:arp协议端口号 编辑:程序博客网 时间:2024/06/04 20:14

集合映射

1.使用xml

集合类:
一下类全部省略getter和setter方法
package hibernate.senssic.mapping;import java.util.List;import java.util.Map;import java.util.Set;public class CollectionMapping {private String cid;private String desc;private Set<Student> studs;private List<Teacher> lteach;private Map<String, String> mtuds;private Set<Student> bagstuds;private List<Teacher> idbagltuds;private String[] strs;}
辅助类student:
package hibernate.senssic.mapping;import java.util.Date;public class Student {private String id;private Date name;}

辅助类teacher类:
package hibernate.senssic.mapping;public class Teacher {private String id;private String name;private int inx;}
xml映射:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">    <hibernate-mapping package="hibernate.senssic.mapping">    <!-- 上面已经配置package,下面的class只需要写类名即可 -->      <class name="CollectionMapping">         <id name="cid">           <!--有这么几种设置:increment用于为long, short或者int类型生成 唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。 在集群下不要使用。identity对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。 返回的标识符是long, short 或者int类型的。sequence在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence), 而在Interbase中使用生成器(generator)。返回的标识符是long, short或者 int类型的。hilo使用一个高/低位算法高效的生成long, short 或者 int类型的标识符。给定一个表和字段(默认分别是 hibernate_unique_key 和next_hi)作为高位值的来源。 高/低位算法生成的标识符只在一个特定的数据库中是唯一的。seqhilo使用一个高/低位算法来高效的生成long, short 或者 int类型的标识符,给定一个数据库序列(sequence)的名字。uuid用一个128-bit的UUID算法生成字符串类型的标识符, 这在一个网络中是唯一的(使用了IP地址)。UUID被编码为一个32位16进制数字的字符串。guid在MS SQL Server 和 MySQL 中使用数据库生成的GUID字符串。native根据底层数据库的能力选择identity, sequence 或者hilo中的一个。assigned让应用程序在save()之前为对象分配一个标示符。这是 <generator>元素没有指定时的默认生成策略。select通过数据库触发器选择一些唯一主键的行并返回主键值来分配一个主键。foreign使用另外一个相关联的对象的标识符。通常和<one-to-one>联合起来使用。 -->           <generator class="uuid"></generator>         </id>         <property name="desc" column="des" length="200" ></property>         <!-- 数组的映射 -->         <array name="strs" table="aray" >         <key column="aryid"></key>            <index column="strinx"></index>            <element column="str" type="string"></element>         </array>         <!-- set映射不可重复,不记录顺序 -->         <set name="studs" table="sstudent"  >           <key column="cid" not-null="true"></key>           <element column="name" type="java.util.Date"></element>         </set>         <!-- List映射可重复,但需记录顺序,需要有记录索引 -->         <list name="lteach" table="teacher">           <key column="cid"  not-null="true"></key>           <index column="inx" type="int"></index>           <element column="name" type="string"></element>         </list>         <!-- map映射需要对应的key和value映射 -->         <map name="mtuds" table="mstudent" >           <key column="cid" not-null="true"></key>          <map-key type="string" column="mkey"></map-key>          <element type="string" column="value"></element>         </map>         <!-- bag映射可重复,且不记录顺序。 -->         <bag name="bagstuds">           <key column="cid"  not-null="true"></key>            <element column="name" type="java.util.Date"></element>         </bag>         <!-- idbag映射集合映射的一种扩展。可以在定义Bag映射时,为每一个添加的对象指定“id”,让Hibernate可以直接确定要更新的数据。 -->         <idbag name="idbagltuds">          <collection-id type="int" column="inx">             <generator class="uuid"></generator>           </collection-id>            <key column="cid" ></key>            <element column="name" type="java.util.Date"></element>         </idbag>               </class>    </hibernate-mapping>

2.使用注解

在hibernate配置文件中加入:
<mapping class="hibernate.senssic.mapping.CollectionMapping"/>        <mapping class="hibernate.senssic.mapping.Student"/>        <mapping  class="hibernate.senssic.mapping.Teacher"/>
主类Collectionmapping类:
package hibernate.senssic.mapping;import java.util.List;import java.util.Map;import java.util.Set;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.MapKey;import javax.persistence.OneToMany;import javax.persistence.Table;import org.hibernate.annotations.IndexColumn;@Entity@Table(name = "collectionmap")public class CollectionMapping {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private int id;@Column(length = 200)private String des;@OneToMany(mappedBy = "cid")private Set<Student> studs;@OneToMany(mappedBy = "cid")@IndexColumn(name = "id")private List<Teacher> teacher;@OneToMany(mappedBy = "cid")@MapKeyprivate Map<Integer, Student> mapts;@OneToMany(mappedBy = "cid")@IndexColumn(name = "id")private Student[] stuts;}
辅类student类:
package hibernate.senssic.mapping;import java.util.Date;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;@Entitypublic class Student {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private int id;@Column(name = "sdate")private Date name;@ManyToOne@JoinColumn(name = "cid", nullable = false, referencedColumnName = "id")private CollectionMapping cid;}

辅类Teacher类:
package hibernate.senssic.mapping;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;@Entitypublic class Teacher {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private int id;@Columnprivate String name;@Columnprivate int inx;@ManyToOne@JoinColumn(name = "conid", referencedColumnName = "id", nullable = false)private CollectionMapping cid;}

组件映射

特点:一个表映射多个类

1.使用xml配置

主类User类:
package hibernate.senssic.component;public class User {private int id;private String name;private String pasd;private Pro pro;}
辅类Pro类:
package hibernate.senssic.component;public class Pro {private String address;private int phon;}
xml配置:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">    <hibernate-mapping package="hibernate.senssic.component">    <class name="User">       <id name="id">         <generator class="uuid"></generator>       </id>       <property name="name" ></property>       <property name="pasd"></property>       <component name="pro" class="Pro">           <property name="address"></property>           <property name="phon"></property>       </component>    </class>    </hibernate-mapping>
若想实现双向关联,即从profile对象也可找到user对象,只需
在以上的基础上,改动两个地方:A.在profile类中增加user对象属性。B.在映射文件的<component></component>中增加一行
 <parent name="user"/>

2.使用注解

user类:
package hibernate.senssic.component;import javax.persistence.Column;import javax.persistence.Embedded;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;@Entitypublic class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private int id;@Columnprivate String name;@Columnprivate String pasd;@Embeddedprivate Pro pro;}

Pro类:
package hibernate.senssic.component;import javax.persistence.Column;import javax.persistence.Embeddable;import org.hibernate.annotations.Parent;@Embeddablepublic class Pro {@Parentprivate User user;@Columnprivate String address;@Columnprivate int phon;}
组件集合映射
其实和集合映射类似,只是在将集合作为属性时,集合里的元素不是表中的一个字段(基本类型),而是由组件(复合类型:类)映射表示。
配置时,在<set></set>中添加:

 <set name="user" table="sstudent"  >           <composite-element class="Pro">             <property name="adderss"></property>             <property name="phon"></property>           </composite-element>         </set>
如果也想实现双向关联除了在Pro中加入user还需要配置

<composite-element class="Pro">              <parent name="user"/>             <property name="adderss"></property>             <property name="phon"></property>           </composite-element>

关联映射

单向关联

一对一外键单向关联

类:
Person类
package hibernate.senssic.relevance;public class Person {private int id;private String name;private Pro pro;}
Pro类
package hibernate.senssic.relevance;public class Pro {private int aid;private String address;private String phon;}

配置文件:
person.cfg.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">    <hibernate-mapping>      <class name="hibernate.senssic.relevance.Person">        <id name="id">          <generator class="uuid"></generator>        </id>        <property name="name"></property>       <many-to-one name="pro" foreign-key="address"></many-to-one><!--一对一外键单向关联-->      </class>    </hibernate-mapping>
pro.cfg.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">    <hibernate-mapping>    <class name="hibernate.senssic.relevance.Pro">      <id name="aid">       <generator class="uuid"></generator>      </id>      <property name="address"></property>      <property name="phon"></property>    </class>    </hibernate-mapping>

一对一主键单向关联

需要改动的地方只有:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">    <hibernate-mapping>      <class name="hibernate.senssic.relevance.Person">        <id name="id">            <!--一对一主键关联-->          <generator class="foreign">            <param name="property">pro</param>          </generator>        </id>        <property name="name"></property>       <one-to-one name="pro" constrained="true"></one-to-one>      </class>    </hibernate-mapping>

一对一非主键关联

两个类:
public class Person {private int id;private String name;private Pro pro;}
public class Pro {private int aid;private String address;private String phon;}

其中pro要关联的是Pro中的phon!,即两个非主属性关联
配置文件:
Person.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  <hibernate-mapping>      <class name="hibernate.bean.Person">       <id name="id">         <generator class="increment"></generator>       </id>       <property name="name" ></property>       <!-- 一对一非主键关联Pro中的phon -->       <one-to-one name="pro" property-ref="phon" ></one-to-one>    </class>  </hibernate-mapping>              

Pro.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">    <hibernate-mapping>    <class name="hibernate.bean.Pro">    <id name="aid">      <generator class="increment"></generator>    </id>    <property name="address"  ></property>    <property name="phon" not-null="true"></property>    </class>    </hibernate-mapping>

一对多非主键关联

两个实体类:
public class Person {private int id;private String name;private Set<Pro> pro;}

public class Pro {private int aid;private String address;private String phon;}

一对多关联Person中的name非主字段
映射文件
Person.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  <hibernate-mapping>      <class name="hibernate.bean.Person">       <id name="id">         <generator class="increment"></generator>       </id>       <property name="name" ></property>       <!-- 一对多非主键关联Person中的name -->  <set name="pro" table="pro">     <key column="proid" property-ref="name"></key>     <one-to-many  class="hibernate.bean.Pro"/>  </set>    </class>  </hibernate-mapping>              
Pro.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">    <hibernate-mapping>    <class name="hibernate.bean.Pro">    <id name="aid">      <generator class="increment"></generator>    </id>    <property name="address"  ></property>    <property name="phon" not-null="true"></property>    </class>    </hibernate-mapping>

一对多外键单向关联

两个类:
package hibernate.senssic.relevance;import java.util.Set;public class Person {private int id;private String name;private Set<Pro> spro;}

package hibernate.senssic.relevance;public class Pro {private int aid;private String address;private String phon;}

两个配置文件:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">    <hibernate-mapping>      <class name="hibernate.senssic.relevance.Person">        <id name="id">          <generator class="uuid">                     </generator>        </id>        <property name="name"></property>        <set name="pro" table="pro">          <key column="proid"></key>          <one-to-many class="hibernate.senssic.relevance.Pro"/>        </set>      </class>    </hibernate-mapping>

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">    <hibernate-mapping>    <class name="hibernate.senssic.relevance.Pro">      <id name="aid">       <generator class="uuid"></generator>      </id>      <property name="address"></property>      <property name="phon"></property>    </class>    </hibernate-mapping>

多对一外键单向关联

两个类省略setter和getter方法:
package hibernate.senssic.relevance;import java.util.Set;public class Person {private int id;private String name;private Pro pro;}

package hibernate.senssic.relevance;public class Pro {private int aid;private String address;private String phon;}
只需要更改的配置文件:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">    <hibernate-mapping>      <class name="hibernate.senssic.relevance.Person">        <id name="id">          <generator class="uuid">                     </generator>        </id>        <property name="name"></property>        <!-- 用来映射关联address在Pro表中的外键列名-->    <many-to-one name="pro" column="address"></many-to-one>      </class>    </hibernate-mapping>

双向关联

一对一外键双向关联

两个类无getter和setter:
package hibernate.senssic.relevance;public class Pro {private int aid;private Person person;private String address;}
package hibernate.senssic.relevance;public class Person {private int id;private String name;private Pro pro;}
两个配置文件:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">    <hibernate-mapping>      <class name="hibernate.senssic.relevance.Person">        <id name="id">          <generator class="uuid">                     </generator>        </id>        <property name="name"></property>       <one-to-one name="pro" property-ref="person"></one-to-one>          </class>    </hibernate-mapping>

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">    <hibernate-mapping>    <class name="hibernate.senssic.relevance.Pro">      <id name="aid">       <generator class="uuid"></generator>      </id>      <property name="address"></property>       <many-to-one name="person" column="personid"></many-to-one>    </class>    </hibernate-mapping>

一对一主键双向关联

值需要改:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">    <hibernate-mapping>    <class name="hibernate.senssic.relevance.Pro">      <id name="aid">       <generator class="foreign">         <param name="property">person</param>       </generator>      </id>      <property name="address"></property>     <one-to-one name="person" constrained="true"></one-to-one>    </class>    </hibernate-mapping>

一对多外键双向关联

类:
package hibernate.senssic.relevance;import java.util.Set;public class Person {private int id;private String name;private Set<Pro> pro;}
package hibernate.senssic.relevance;public class Pro {private int aid;private Person person;private String address;}

配置文件:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">    <hibernate-mapping>      <class name="hibernate.senssic.relevance.Person">        <id name="id">          <generator class="uuid">                     </generator>        </id>        <property name="name"></property>       <set name="pro" inverse="true">         <key column="addid"></key>          <one-to-many class="hibernate.senssic.relevance.Pro"/>       </set>          </class>    </hibernate-mapping>

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">    <hibernate-mapping>    <class name="hibernate.senssic.relevance.Pro">      <id name="aid">       <generator class="foreign">         <param name="property">person</param>       </generator>      </id>      <property name="address"></property>     <many-to-one  name="person"></many-to-one>    </class>    </hibernate-mapping>

多对多双向关联

两个类:
package hibernate.senssic.relevance;import java.util.Set;public class Pro {private int aid;private Set<Person> person;private String address;}

package hibernate.senssic.relevance;import java.util.Set;public class Person {private int id;private String name;private Set<Pro> pro;}

配置文件:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">    <hibernate-mapping>    <class name="hibernate.senssic.relevance.Pro">      <id name="aid">       <generator class="foreign">         <param name="property">person</param>       </generator>      </id>      <property name="address"></property>       <set name="pro">         <key column="proid"></key>         <many-to-many column="person" class="hibernate.senssic.relevance.Person"></many-to-many>       </set>    </class>    </hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">    <hibernate-mapping>      <class name="hibernate.senssic.relevance.Person">        <id name="id">          <generator class="uuid">                     </generator>        </id>        <property name="name"></property>       <set name="pro" inverse="true">         <key column="personid"></key>        <many-to-many column="addreid" class="hibernate.senssic.relevance.Pro"></many-to-many>       </set>          </class>    </hibernate-mapping>

使用注解实现关系映射:

实例的实体是user和role,主键分别是userid和roleid
 1)一对一外键关联映射(单向)
 @OneToOne(cascade=CascadeType.ALL)  //一对一外键关联,使用@OneToOne,并设置了级联操作
 @JoinColumn(name="userid",unique=true)   //@JoinColum设置了外键的名称为userid(数据库字段名),如果不设置,则默认为另一类的属性名+ _id。外键的值是唯一的(unique),不可重复,与另一类的主键一直
 
 2)一对一外键关联映射(双向)
 @OneToOne(mappedBy=" role",cascade=CascadeType.ALL)  //一对一双向关联关系,使用@OneToOne。注意:需要加上mappedBy="role",如果不加上的话, role 也会生成一个外键(user_id),mappedby="role"需要指向与他关联对象的一个属性,说明双向关联关系中,有且仅有一端是作为主体(owner)端存在的,主体端负责维护联接列,对于不需要维护这种关系的从表则通过mappedBy属性进行声明,mappedBy的值指向主体的关联属性
 //规律:只有是双向关联关系,都加上mappedby,cascade=CascadeType.ALL级联


  3)一对一主键关联映射(不重要)
 在实际中很少用,使用注解@PrimaryKeyJoinColumn,意思是说,我的主键去参考另外一张表中的主键,作为我的主键,但是在我测试使用注解一对一主键关联映射,在生成表的时候,数据库中并没有生成关联,使用XML映射可以生成。Annotation注解一对一主键关联映,有些bug。不过没空去研究它。因为在实际开发中一对一很少用,主键关联就更少了


 4)多对一关联映射
 多端配置
 @ManyToOne(targetEntity=role.class)  //多对一注解@ManyToOne;targetEntity指定了关联对象
 @JoinColumn(name="userid")  //@JoinColumn(name="userid")指定生产的外键的字段名,默认是org_id


 5)一对多关联映射(单向)
 @OneToMany   //一对多注解@OneToMany(单向),如果只写@OneToMany的话,hibernate会建一张中间表来维护他们之间的关系
 @JoinColumn(name="roleid")    //加上@JoinColumn(name="roleid"),则不会建中间表,他会在多的一端加上外键roleid,来维护他们之间的关系


 6)一对多关联映射(双向)
 一端配置
 @OneToMany(mappedBy="role")  //一对多双向,在一的一端中设置mappedBy,说明多的一端为主导
 @JoinColumn(name="roleid")  //如果指定了外键字段名称,则多的一端也需要指定相同的字段名称
 多端配置
 @ManyToOne  //一对多双向
 @JoinColumn(name=" roleid ") //需要指定外键与一的一端给的外键名称一致,@JoinColumn(name=" roleid "),也可以不指定,如果在多的一端不指定,则一的一端也不能指定,否则为生成两个外键


 7)多对多关联映射(单向)
 @ManyToMany  //多对多映射:注解@ManyToMany(单向),默认情况下,hibernate会自动的创建一张中间表来维护多对多关系
  默认中间表的名称 :user_role中间表,字段的名称user_id role_id,如果想更换表名和字段名称,注解如下:
 @JoinTable(name="t_u_r",joinColumns={@JoinColumn(name="u_id")},inverseJoinColumns={@JoinColumn(name="r_id")})
 
 8)多对多关联映射(双向)
 user端
 @ManyToMany  //多对多映射:注解@ManyToMany(单向);默认情况下,hibernate会自动的创建一张中间表,来维护多对多关系;默认中间表的名称 :user_role中间表,字段的名称user_id role_id
 如果想更换表名和字段名称,注解如下:
 @JoinTable(name="t_u_r",joinColumns={@JoinColumn(name="u_id")},inverseJoinColumns={@JoinColumn(name="r_id")})  //@JoinTable(name="t_u_r"),指定中间表的表名;joinColumns={@JoinColumn(name="u_id")},指定当前对象的外键;inverseJoinColumns={@JoinColumn(name="r_id")},指定关联对象的外键
 role端
 @ManyToMany(mappedBy="role")   //多对多,双向关联映射

继承映射

关系数据库的世界中,表与表之间没有任何关键字可以明确指明这两张表的父子关系,表与表是没有继承关系这样的说法的。为了将程序领域中的继承关系反映到数据中,

Hibernate为我们提供了3中方案:

假设有这么三个类:

public class People{    /*父类所拥有的属性*/    private String id;    private String name;    private String sex;    private String age;    private Timestamp birthday;        /*get和set方法*/}



public class Student extends People{    /*学生独有的属性*/    private String cardId;//学号    public String getCardId()    {        return cardId;    }    public void setCardId(String cardId)    {        this.cardId = cardId;    }}

public class Teacher extends People{    /*Teacher所独有的属性*/    private int salary;//工资    public int getSalary()    {        return salary;    }    public void setSalary(int salary)    {        this.salary = salary;    }}

第一种方案:一个子类对应一张表。

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping>    <class name="hibernate.senssic.People" abstract="true">        <id name="id" type="string">            <column name="id"></column>            <generator class="uuid"></generator>        </id>        <property name="name" column="name" type="string"></property>        <property name="sex" column="sex" type="string"></property>        <property name="age" column="age" type="string"></property>        <property name="birthday" column="birthday" type="timestamp"></property>        <!--         <union-subclass name="hibernate.senssic.Student" table="student">             <property name="cardId" column="cardId" type="string"></property>         </union-subclass>         <union-subclass name="hibernate.senssic.Teacher" table="teacher">             <property name="salary" column="salary" type="integer"></property>         </union-subclass>         -->    </class>    <union-subclass name="hibernate.senssic.Student"        table="student" extends="hibernate.senssic.People">        <property name="cardId" column="cardId" type="string"></property>    </union-subclass>    <union-subclass name="hibernate.senssic.Teacher"        table="teacher" extends="hibernate.senssic.People">        <property name="salary" column="salary" type="integer"></property>    </union-subclass></hibernate-mapping>


第二种方案:使用一张表表示所有继承体系下的类的属性的并集。

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping>    <class name="hibernate.senssic.People" table="people">        <id name="id" type="string">            <column name="id"></column>            <generator class="uuid"></generator>        </id>        <discriminator column="peopleType" type="string"></discriminator>        <property name="name" column="name" type="string"></property>        <property name="sex" column="sex" type="string"></property>        <property name="age" column="age" type="string"></property>        <property name="birthday" column="birthday" type="timestamp"></property>        <subclass name="hibernate.senssic.Student" discriminator-value="student">            <property name="cardId" column="cardId" type="string"></property>        </subclass>                <subclass name="hibernate.senssic.Teacher" discriminator-value="teacher">            <property name="salary" column="salary" type="string"></property>        </subclass>    </class></hibernate-mapping>


第三种方案:每个子类使用一张表只存储它特有的属性,然后与父类所对应的表以一对一主键关联的方式关联起来。

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping>    <class name="hibernate.senssic.People" table="people">        <id name="id" type="string">            <column name="id"></column>            <generator class="uuid"></generator>        </id>        <property name="name" column="name" type="string"></property>        <property name="sex" column="sex" type="string"></property>        <property name="age" column="age" type="string"></property>        <property name="birthday" column="birthday" type="timestamp"></property>                <joined-subclass name="hibernate.senssic.Student" table="student">            <key column="id"></key>            <property name="cardId" column="cardId" type="string"></property>        </joined-subclass>                <joined-subclass name="hibernate.senssic.Teacher" table="teacher">            <key column="id"></key>            <property name="salary" column="salary" type="integer"></property>        </joined-subclass>    </class></hibernate-mapping>

使用注解来实现继承映射:

http://blog.csdn.net/senssic/article/details/13421201

hibernate的联合主键

如果使用联合主键,而不是实体对应的id自动生成,则需要抽象出联合主键为一个类,并需要实现序列化接口,和覆盖equals方法,最好覆盖hashCode方法(用于比较对象)。
1.使用xml
抽象主键类:
package hibernate.senssic.compositeid;import java.io.Serializable;public class ComposiTidPK implements Serializable {// 联合主键,使用name和email作为主键,需要实现序列化接口,和覆写hashCode和equals方法private String name;private String email;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((email == null) ? 0 : email.hashCode());result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;ComposiTidPK other = (ComposiTidPK) obj;if (email == null) {if (other.email != null)return false;} else if (!email.equals(other.email))return false;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}}

实体类:
package hibernate.senssic.compositeid;import java.util.Date;public class ComposiTid {private String adder;private Date date;private ComposiTidPK cPk;public String getAdder() {return adder;}public void setAdder(String adder) {this.adder = adder;}public Date getDate() {return date;}public void setDate(Date date) {this.date = date;}public ComposiTidPK getcPk() {return cPk;}public void setcPk(ComposiTidPK cPk) {this.cPk = cPk;}}

xml映射文件配置:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">   <hibernate-mapping package="hibernate.senssic.compositeid">     <class name="ComposiTid">         <composite-id name="cPk">              <key-property name="name"></key-property>              <key-property name="email"></key-property>          </composite-id>          <property name="adder"></property>          <property name="date"></property>      </class>   </hibernate-mapping>
2.使用注解
抽象联合主键类注解:
package hibernate.senssic.compositeid;import java.io.Serializable;import javax.persistence.Column;import javax.persistence.Embeddable;@Embeddablepublic class ComposiTidPK implements Serializable {// 联合主键,使用name和email作为主键,需要实现序列化接口,和覆写hashCode和equals方法@Columnprivate String name;@Columnprivate String email;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((email == null) ? 0 : email.hashCode());result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;ComposiTidPK other = (ComposiTidPK) obj;if (email == null) {if (other.email != null)return false;} else if (!email.equals(other.email))return false;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}}

实体类:
package hibernate.senssic.compositeid;import java.util.Date;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.Id;@Entitypublic class ComposiTid {@Columnprivate String adder;@Columnprivate Date date;@Idprivate ComposiTidPK cPk;public String getAdder() {return adder;}public void setAdder(String adder) {this.adder = adder;}public Date getDate() {return date;}public void setDate(Date date) {this.date = date;}public ComposiTidPK getcPk() {return cPk;}public void setcPk(ComposiTidPK cPk) {this.cPk = cPk;}}


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小米4账号密码忘了怎么办 小米2a触屏失灵怎么办 红米note5拍照不清晰怎么办 红米手机太卡怎么办 红米3x忘记密码怎么办 红米手机太卡了怎么办 红米手机太卡怎么办? 红米3老是死机怎么办 红米3s经常死机怎么办 红米4a进水了怎么办 魅族耳机声音小怎么办 魅蓝note6声音小怎么办 魅蓝3s锁定怎么办 红米1密码忘了怎么办 小米手环升级失败怎么办 红米4忘记密码怎么办 红米1代忘记密码怎么办 红米3s忘记密码怎么办 小米3卡槽卡住了怎么办 红米4手机信号不好怎么办 红米note3信号差怎么办 红米note3没信号怎么办 红米3运行慢怎么办 红米手机运行慢怎么办 红米手机忘记解锁图案怎么办 小米手机解锁图案忘了怎么办 红米2内屏坏了怎么办 红米密码忘记了怎么办 红米pro玩王者卡怎么办 红米note4不支持计步怎么办 红米pro玩游戏卡怎么办 红米手机费电快怎么办 荣耀5c忘记密码怎么办 小米之家不退货怎么办 手机号绑定过多小米账户怎么办 耐克黑色鞋褪色怎么办 买广汽传祺7s新车有问题怎么办 华为荣耀10边框掉色了怎么办 网购商家打来无货怎么办 客户拍了不发货怎么办 天猫商家欺骗买家怎么办