HelloWorld 善战者,求之于势,不责于人;故能择人而任势。

知止而后有定,定而后能静,静而后能安,安而后能虑,虑而后能得。物有本末,事有终始。知所先后,则近道矣。

  BlogJava :: 首页 ::  :: 联系 ::  :: 管理 ::
  167 随笔 :: 1 文章 :: 40 评论 :: 0 Trackbacks

Hibernate3种继承形式

1.     表和子类之间的对立一对一关系 Table per concrete class

源码下载 http://download.csdn.net/source/226662
2.     每个子类对应一张子表,并与主类共享主表 Table per subclass

源码下载 http://download.csdn.net/source/226728
3.     表与类的一对多关系 Table per class hierarchy
源码下载 http://download.csdn.net/source/226783

按照《深入潜出Hibernate》中介绍的,我们开始学习。

 

场景: 就一般的商品而言,在具备某些共性(如: 名称,厂商),也有不同的属性,如书有页数,dvd有dvd的编码格式.

 

<> table per concerte class

(a) 使用xml

Titem 有两个子类: Tbook , TDvd, 那么,所谓“表与子类之间的一对一的关系”,也就是每个子类对应一张数据库表。对应Tbook , TDvd

数据库的表我们设计如下

表 T_bool

id

Int

PK

Name

Varchar(50)

 

Manufacturer

Varchar(50)

 

Pagecount

int

 

 

表 T_dvd

id

Int

PK

Name

Varchar(50)

 

Manufacturer

Varchar(50)

 

Codetype

Varchar(30)

 

/**

* 虚拟的表

* TItem 已经知道的继承类为 AbstractTBook AbstractTDvd

*/

public abstract class TItem implements Serializable {

    private Integer id;

    private String name;

    private String manufacturer;

    public Integer getId() {

       return id;

       }

    public void setId(Integer id) {

       this.id = id;

       }

    public String getManufacturer() {

       return manufacturer;

       }

    public void setManufacturer(String manufacturer) {

       this.manufacturer = manufacturer;

       }

    public String getName() {

       return name;

       }

    public void setName(String name) {

       this.name = name;

       }

}

public abstract class AbstractTDvd extends TItem {

    private String codetype;

    public AbstractTDvd() {     }

    public String getCodetype() {

       return this.codetype;

       }

    public void setCodetype(String codetype) {

       this.codetype = codetype;

       }

}

public abstract class AbstractTBook extends TItem {

    private Integer pagecount;

    public AbstractTBook() {}

    public Integer getPagecount() {

       return this.pagecount;

       }

    public void setPagecount(Integer pagecount) {

       this.pagecount = pagecount;

       }

}

public class TDvd extends AbstractTDvd     {

    public TDvd() {}

}

public class TBook extends AbstractTDvd     {

    public TBook() {}

}

 

Tbook.hbm.xml

<?xml version="1.0" encoding="utf-8"?>

<hibernate-mapping>

       <class name="com.persist.tablePerConcreteClass.TBook" table="t_book" >

           <id name="id" type="java.lang.Integer">

               <column name="id" />

               <generator class="sequence">

               <param name="sequence">t_table_id_seq</param>

               </generator>

           </id>

           <property name="name" type="java.lang.String">

               <column name="name" length="50" />

           </property>

           <property name="manufacturer" type="java.lang.String">

               <column name="manufacturer" length="50" />

           </property>

           <property name="pagecount" type="java.lang.Integer">

               <column name="pagecount" />

           </property>

       </class>

</hibernate-mapping>

 

Tdvd.hbm.xml

<?xml version="1.0" encoding="utf-8"?>

<hibernate-mapping>

       <class name="com.persist.tablePerConcreteClass.TDvd" table="t_dvd" >

           <id name="id" type="java.lang.Integer">

               <column name="id" />

               <generator class="sequence">

               <param name="sequence">t_table_id_seq</param>

               </generator>

           </id>

           <property name="name" type="java.lang.String">

               <column name="name" length="50" />

           </property>

           <property name="manufacturer" type="java.lang.String">

               <column name="manufacturer" length="50" />

           </property>

           <property name="codetype" type="java.lang.String">

               <column name="codetype" length="50" />

           </property>

       </class>

</hibernate-mapping>

 

Hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>

<hibernate-configuration>

       <session-factory>

          <property name="dialect">

              org.hibernate.dialect.PostgreSQLDialect

          </property>

          <property name="connection.url">

              jdbc:postgresql://localhost:5432/postgres

          </property>

          <property name="connection.username">pgsql</property>

          <property name="connection.password">pgsql</property>

          <property name="connection.driver_class">

              org.postgresql.Driver

          </property>

          <property name="myeclipse.connection.profile">pgsql</property>

          <property name="show_sql">true</property>

          <mapping resource="com/persist/tablePerConcreteClass/TBook.hbm.xml" />

          <mapping resource="com/persist/tablePerConcreteClass/TDvd.hbm.xml" />

       </session-factory>

</hibernate-configuration>

测试用例

public class TBookDAO extends BaseHibernateDAO {

    public static void main(String args[]) {

       new TBookDAO().test();

       }

   

    public void test() {

          Session session = this.getSession();

          List list = session.createQuery(" from com.persist.tablePerConcreteClass.TItem").list();

          Iterator it = list.iterator();

       while (it.hasNext()) {

              TItem item = (TItem) it.next();

              System.out.println(item.getName());

          }

       }

}

 

(b) 使用hibernate注解
步骤1 修改HibernateSessionFactory 中的Configuration

AnnotationConfiguration configuration = new AnnotationConfiguration();

步骤2,修改hibernate.cfg.xml中的

<mapping resource="com/persist/tablePerConcreteClass/TBook.hbm.xml" />

<mapping resource="com/persist/tablePerConcreteClass/TDvd.hbm.xml" />

<mapping class="com.persist.tablePerConcreteClass.TBook"/>

<mapping class="com.persist.tablePerConcreteClass.TDvd"/>

步骤3,在Titem, AbstractTBook, AbstractTBook类上加注解

@MappedSuperclass

Titem

@MappedSuperclass

public abstract class TItem implements Serializable {

    @Id

    @Column(name = "id")

    @SequenceGenerator(name = "t_table_id_seq", sequenceName = "t_table_id_seq")

    private Integer id;

    @Column(name = "name")

    private String name;

    @Column(name = "manufacturer")

    private String manufacturer;

    public Integer getId() {

       return id;

    }

    public void setId(Integer id) {

       this.id = id;

    }

    public String getManufacturer() {

       return manufacturer;

    }

    public void setManufacturer(String manufacturer) {

       this.manufacturer = manufacturer;

    }

    public String getName() {

       return name;

    }

    public void setName(String name) {

       this.name = name;

    }

}

AbstractTDvd

@MappedSuperclass

public class AbstractTDvd extends TItem {

    @Column(name = "codetype")

    private String codetype;

    public AbstractTDvd() { }

    public String getCodetype() {

       return this.codetype;

    }

    public void setCodetype(String codetype) {

       this.codetype = codetype;

    }

}

AbstractTBook

@MappedSuperclass

public class AbstractTBook extends TItem {

    @Column(name = "pagecount")

    private Integer pagecount;

    public AbstractTBook() {}

    public Integer getPagecount() {

       return this.pagecount;

    }   public void setPagecount(Integer pagecount) {

       this.pagecount = pagecount;

    }

}

步骤4,在Tbook,TDvd上加注解

@Entity

@Table(name = "t_book")

@Entity

@Table(name = "t_dvd")

调用的时候一样
 

<> Table per subclass

将父类Titem单独映射到一张主表,而为Tbook, TDvd分别建立一张子表,子表和父表用外键来关联

数据库的表我们设计如下

T_item

id

Int

PK

Name

Varchar(50)

 

Manufacturer

Varchar(50)

 

CREATE TABLE t_item

(

 id int4 NOT NULL DEFAULT nextval('t_table_id_seq'::regclass),

 name varchar(50),

 manufacturer varchar(50),

 CONSTRAINT t_item_pkey PRIMARY KEY (id)

)

 

 

T_bool

id

Int

PK

Pagecount

int

 

CREATE TABLE t_book

(

 id int4 NOT NULL,

 pagecount int4,

 CONSTRAINT t_book_pkey PRIMARY KEY (id),

 CONSTRAINT t_book_id_fkey FOREIGN KEY (id)

      REFERENCES t_item (id) MATCH SIMPLE

      ON UPDATE NO ACTION ON DELETE NO ACTION

)

 

T_dvd

id

Int

PK

Codetype

Varchar(30)

 

CREATE TABLE t_dvd

(

 id int4 NOT NULL,

 codetype varchar(30),

 CONSTRAINT t_dvd_pkey PRIMARY KEY (id),

 CONSTRAINT t_dvd_id_fkey FOREIGN KEY (id)

      REFERENCES t_item (id) MATCH SIMPLE

      ON UPDATE NO ACTION ON DELETE NO ACTION

)

 

只有1个xml,TItem.hbm.xml
<hibernate-mapping>
     <class name="com.persist.tablePerConcreteClass.TItem" table="t_item">
         <id name="id" type="java.lang.Integer">
             <column name="id" />
             <generator class="sequence">
              <param name="sequence">t_table_id_seq</param>
             </generator>
         </id>
         <property name="name" type="java.lang.String">
             <column name="name" length="50" />
         </property>
         <property name="manufacturer" type="java.lang.String">
             <column name="manufacturer" length="50" />
         </property>
        
         <joined-subclass name="com.persist.tablePerConcreteClass.TBook" table="t_book">
          <key column="id"></key>
          <property name="pagecount" column="pagecount">
          </property>
         </joined-subclass>
         <joined-subclass name="com.persist.tablePerConcreteClass.TDvd" table="t_dvd">
          <key column="id"></key>
          <property name="codetype" column="codetype">
          </property>
         </joined-subclass>
     </class>
</hibernate-mapping>
使用注解
1.TItem不为抽象类,TItem的类注解为
@Entity
@Table(name = "t_item")
@Inheritance(strategy=InheritanceType.JOINED)
2.AbstractTBook和AbstractTDvd的类注解为
@PrimaryKeyJoinColumn(name="id")
3.TBook和TDvd的注解为
@Entity
@Table(name = "t_book")

@Entity
@Table(name = "t_dvd")

<> Table per class hierarchy

CREATE TABLE t_item

(

 id int4 NOT NULL DEFAULT nextval('t_table_id_seq'::regclass),

 name varchar(50),

 manufacturer varchar(50),

 category varchar(30),

 codetype varchar(30),

 pagecount int4,

 CONSTRAINT t_item_pkey PRIMARY KEY (id)

)

只有一个xml,TItem.hbm.xml
<hibernate-mapping>
    <class name="com.persist.tablePerConcreteClass.TItem" table="t_item">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="sequence">
             <param name="sequence">t_table_id_seq</param>
            </generator>
        </id>
        <discriminator>
            <column name="category" length="10" />
        </discriminator>
        <property name="name" type="java.lang.String">
            <column name="name" length="50" />
        </property>
        <property name="manufacturer" type="java.lang.String">
            <column name="manufacturer" length="50" />
        </property>        
        <subclass name="com.persist.tablePerConcreteClass.TBook" discriminator-value="1">
         <property name="pagecount" column="pagecount">
         </property>
        </subclass>
        <subclass name="com.persist.tablePerConcreteClass.TDvd" discriminator-value="2" >
         <property name="codetype" column="codetype">
         </property>
        </subclass>
    </class>
</hibernate-mapping>
注解的修改为
1.TItem的注解修改为

@Entity
@Table(name = "t_item")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="category", discriminatorType=DiscriminatorType.STRING, length=30)
2.AbstractTBook, AbstractTDvd的注解修改为
@Inheritance
3.TBook,TDvd的注解修改为
@Entity
@DiscriminatorValue(value="2")



</script>

posted on 2007-08-12 16:47 helloworld2008 阅读(3016) 评论(1)  编辑  收藏 所属分类: java - hibernate

评论

# re: (1) Hibernate的3种继承形式 2015-01-09 13:33 tangzhulong
多谢分享!  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: