Table per class hierarchy
前两种方式,都要进行多表操作,这样带来的性能的消耗量是相当可观的,不利于高并发量的数据存取。
Table per class hierarchy提供了另外一中选择。
实际开发中,通过冗余字段表达同类型数据是很多情况下的选择。
建立一个数据表T_Item包含了所有商品可能用到的字段。另外,为了区分不同的商品,还需要引入一个用于区分的字段。
1.数据表如下图:
2.数据表定义sql
use sample;
DROP TABLE T_Item;
CREATE TABLE T_Item (
id INT NOT NULL AUTO_INCREMENT
, category VARCHAR(10)
, name VARCHAR(50)
, manufacturer VARCHAR(50)
, regioncode VARCHAR(30)
, pagecount INT
, PRIMARY KEY (id)
);
3.配置文件
TItem.hbm.xml:
注意,discriminator定义要紧跟在id定义之后。如果在property之后定义,会报错误。
(meta*,subselect?,cache?,synchronize*,comment?,tuplizer
*,(id|composite-id),discriminator?,natural-id?,(version|timestamp)?,(property|many-to-one|one-to-one|component|dynamic-component|properties|any|map|set|list|bag|idbag|array|primitive-array)*,((join*,subclass*)|joined-subclass*|union-subclass*),loader?,sql-insert?,sql-update?,sql-delete?,filter*,resultset*,(query|sql-query)*)
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.blogjava.start">
<class name="TItem" table="T_Item" catalog="sample">
<id name="id" column="id">
<generator class="native" />
</id>
<discriminator column="category" type="string"></discriminator>
<property name="name" column="name"/>
<property name="manufacturer" column="manufacturer"/>
<subclass name="TBook" discriminator-value="1">
<property name="pageCount" column="pagecount"></property>
</subclass>
<subclass name="TDVD" discriminator-value="2">
<property name="regionCode" column="regioncode"></property>
</subclass>
</class>
</hibernate-mapping>
4.测试代码
package cn.blogjava.start;
import java.util.Iterator;
import java.util.List;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class HibernateTest extends TestCase {
Session session = null;
protected void setUp() {
try {
Configuration config = new Configuration().configure();
SessionFactory sessionFactory = config.buildSessionFactory();
session = sessionFactory.openSession();
} catch (HibernateException e) {
e.printStackTrace();
}
}
protected void tearDown() {
try {
session.close();
} catch (HibernateException e) {
e.printStackTrace();
}
}
public void testInsert() {
Transaction tran = null;
try {
tran = session.beginTransaction();
TBook book1 = new TBook();
book1.setManufacturer("byf");
book1.setName("Java beginner");
book1.setPageCount(501);
TBook book2 = new TBook();
book2.setManufacturer("yyy");
book2.setName("Thinking in java");
book2.setPageCount(1201);
TDVD dvd1 = new TDVD();
dvd1.setManufacturer("columnibia");
dvd1.setName("Lord king");
dvd1.setRegionCode("5 area");
TDVD dvd2 = new TDVD();
dvd2.setManufacturer("sony");
dvd2.setName("Forrest gump");
dvd2.setRegionCode("3 area");
session.save(book1);
session.save(book2);
session.save(dvd1);
session.save(dvd2);
session.flush();
tran.commit();
Assert.assertEquals(book1.getId().intValue()>0, true);
Assert.assertEquals(book2.getId().intValue()>0, true);
Assert.assertEquals(dvd1.getId().intValue()>0, true);
Assert.assertEquals(dvd2.getId().intValue()>0, true);
} catch (HibernateException e) {
// TODO: handle exception
e.printStackTrace();
Assert.fail(e.getMessage());
if(tran != null) {
try {
tran.rollback();
} catch (Exception e1) {
// TODO: handle exception
e1.printStackTrace();
}
}
}
}
public void testSelect(){
List list = session.createQuery(" from TBook").list();
Iterator it = list.iterator();
while (it.hasNext()) {
TBook book = (TBook)it.next();
System.out.println(book.getName());
}
list = session.createQuery(" from TDVD").list();
it = list.iterator();
while (it.hasNext()) {
TDVD dvd = (TDVD)it.next();
System.out.println(dvd.getName());
}
}
}
4.查询结果