Hibernate继承关系有如下3映射类型对应:
1.table per concrete class
也就是表与子类之间独立的一对一关系。即每个子类对应一张表。
2.table per subclass
每个子类对应一张子表,并与主类共享主表
3. table per class hierarchy
表与类的一对多关系
第二种映射策略举例:
先看数据库文件:
-- 删除表
DROP TABLE TItem ;
create table TItem
(
id varchar(32) not null primary key,
name varchar(20) not null,
manufacturer varchar(20)
);
drop table TBook;
create table TBook
(
id varchar(32) not null primary key,
pagecount int
);
drop table TDvd;
create table TDvd
(
id varchar(32) not null primary key,
regionCode varchar(2)
);
commit;
然后是TBook.java TDVD.java TItem.java代码:
package wjr.hibernate.demo19;
public class TItem {
private String id ;
private String name ;
private String manufacturer ;
public String getId() {
return id;
}
public void setId(String 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;
}
}
**************************
package wjr.hibernate.demo19;
public class TBook extends TItem {
private int pageCount;
public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
}
***************************************
package wjr.hibernate.demo19;
public class TDVD extends TItem {
private String regionCode;
public String getRegionCode() {
return regionCode;
}
public void setRegionCode(String regionCode) {
this.regionCode = regionCode;
}
}
*****************************************
然后定义个操作类:
package wjr.hibernate.demo19;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
public class TItemOperate {
private Session session;
public TItemOperate()
{
this.session = (new Configuration()).configure().buildSessionFactory().openSession();
}
public void insert(TItem titem)
{
session.save(titem);
session.beginTransaction().commit();
session.close();
}
}
*****************************************************
public class TestDemo04 {
public static void main(String[] args) {
TItemOperate to = new TItemOperate() ;
/*
TBook book = new TBook() ;
book.setId("ml001") ;
book.setName("JAVA EE从入门到精通") ;
book.setManufacturer("魔乐在线") ;
book.setPageCount(888) ;
TDVD dvd = new TDVD() ;
dvd.setId("lxh002") ;
dvd.setName("JAVA EE学习视频") ;
dvd.setManufacturer("MLDN") ;
dvd.setRegionCode("6") ;
// 向数据库中执行插入操作
to.insert(dvd) ;
*/
TBook book = (TBook)to.queryById("ml001") ;
System.out.println(book.getName()) ;
}
}
虽然有3张表 但是只有一个映射文件,这就是实体层划分。
最后是配置文件内容:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
<class name="wjr.hibernate.demo19.TItem" table="TITEM" schema="SCOTT">
<id name="id" type="java.lang.String">
<column name="ID" length="32" />
<generator class="assigned"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="NAME" length="20" not-null="true" />
</property>
<property name="manufacturer" type="java.lang.String">
<column name="MANUFACTURER" length="20" />
</property>
<joined-subclass name="wjr.hibernate.demo19.TBook" table="TBook">
<key column="ID"></key>
<property name="pageCount" type="java.lang.Integer" column="pagecount"></property>
</joined-subclass>
<joined-subclass name="wjr.hibernate.demo19.TDVD" table="TDvd">
<key column="ID"></key>
<property name="regionCode" type="java.lang.String" column="regionCode"></property>
</joined-subclass>
</class>
</hibernate-mapping>
第三种映射策略举例:
上面这种并不是唯一解决方法。实际开发中,可通过冗余字段表达同类型数据可能是用户在绝大数
情况下的选择。对于上面示例而言,也就意味着,通过一个包含所有子类字段的T_Item表。
例如:
CREATE TABLE TItem
(
id varchar(32) not null primary key ,
-- 通过此字段用于区分保存的是 Book还是 DVD
category varchar(2) not null ,
name varchar(20) not null ,
manufacturer varchar(20) not null ,
regionCode varchar(2) ,
pageCount int
) ;
比如上面表的category字段为1时,就表示Book,pageCount 就设置相应值,而regionCode就为null,
相反,category字段为2时,就表示DVD,pageCount值就为null,而regionCode就设为相应的值。
但是这种操作只能在数据库层次上操作,与程序本身无关,详情看后面的类文件和配置文件。
首先是数据库表:
-- 删除表
DROP TABLE TItem19_2 ;
-- 创建表
CREATE TABLE TItem19_2
(
id varchar(32) not null primary key ,
-- 通过此字段用于区分保存的是 Book还是 DVD
category varchar(2) not null ,
name varchar(20) not null ,
manufacturer varchar(20) not null ,
regionCode varchar(2) ,
pageCount int
) ;
-- 事务提交
commit ;
***********************
我们会发现POJO类跟上面是一样的:
package wjr.hibernate.demo19_2;
public class TItem {
private String id ;
private String name ;
private String manufacturer ;
public String getId() {
return id;
}
public void setId(String 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;
}
}
***********************
package wjr.hibernate.demo19_2;
public class TBook extends TItem {
private int pageCount;
public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
}
***********************
package wjr.hibernate.demo19_2;
public class TDVD extends TItem {
private String regionCode;
public String getRegionCode() {
return regionCode;
}
public void setRegionCode(String regionCode) {
this.regionCode = regionCode;
}
}
***********************
最后是配置文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
<class name="wjr.hibernate.demo19_2.Titem192" table="TITEM19_2"
schema="SCOTT">
<id name="id" type="java.lang.String">
<column name="ID" length="32" />
<generator class="assigned" />
</id>
<discriminator column="category" type="java.lang.String"></discriminator>
<property name="category" type="java.lang.String">
<column name="CATEGORY" length="2" not-null="true" />
</property>
<property name="name" type="java.lang.String">
<column name="NAME" length="20" not-null="true" />
</property>
<property name="manufacturer" type="java.lang.String">
<column name="MANUFACTURER" length="20" not-null="true" />
</property>
<subclass name="wjr.hibernate.demo19_2.TBook"
discriminator-value="1">
<property name="pagecount" type="java.lang.Long">
<column name="PAGECOUNT" precision="22" scale="0" />
</property>
</subclass>
<subclass name="wjr.hibernate.demo19_2.TDVD"
discriminator-value="2">
<property name="regioncode" type="java.lang.String">
<column name="REGIONCODE" length="2" />
</property>
</subclass>
</class>
</hibernate-mapping>