Hibernate实体层次设计(三)

Hibernate实体层次设计(三)

Table per subclass:

父类TItem单独映射到一张主表,为子类TBook、TDVD分别单独设立一张子表,子表中只包含子类所扩展的属性。同时,子表通过关系型数据库的外键相关联,如下图所示:

数据关系图如下:


1.表定义sql如下
use  sample;

DROP   TABLE  T_DVD;
DROP   TABLE  T_Book;
DROP   TABLE  T_Item;

CREATE   TABLE  T_Item (
       id 
INT   NOT   NULL  AUTO_INCREMENT
     , name 
VARCHAR ( 50 )
     , manufacturer 
VARCHAR ( 50 )
     , 
PRIMARY   KEY  (id)
);

CREATE   TABLE  T_Book (
       id 
INT   NOT   NULL
     , pagecount 
INT
     , 
PRIMARY   KEY  (id)
     , 
INDEX  (id)
     , 
CONSTRAINT  FK_T_Book_1  FOREIGN   KEY  (id)
                  
REFERENCES  T_Item (id)
);

CREATE   TABLE  T_DVD (
       id 
INT   NOT   NULL
     , regioncode 
VARCHAR ( 30 )
     , 
PRIMARY   KEY  (id)
     , 
INDEX  (id)
     , 
CONSTRAINT  FK_T_DVD_1  FOREIGN   KEY  (id)
                  
REFERENCES  T_Item (id)
);


2.配置文件
TItem.hbm.xml
<? 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 >
        
< property  name ="name"  column ="name" />
        
< property  name ="manufacturer"  column ="manufacturer" />         
        
        
< joined-subclass  name ="TDVD"  table ="T_DVD"  catalog ="sample" >
            
< key  column ="id"   />
            
< property  name ="regionCode"  column ="regioncode"   />
        
</ joined-subclass >
        
        
< joined-subclass  name ="TBook"  table ="T_Book"  catalog ="sample" >
            
< key  column ="id"   />
            
< property  name ="pageCount"  column ="pagecount"   />
        
</ joined-subclass >
               
    
</ class >
</ hibernate-mapping >

3.测试代码。
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(
" 电子工业 " );
            book1.setName(
" Java beginner " );
            book1.setPageCount(
501 );
            
            TBook book2 
=   new  TBook();
            book2.setManufacturer(
" 机械工业 " );
            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) {
            e.printStackTrace();
            Assert.fail(e.getMessage());
            
if (tran  !=   null ) {
                
try  {
                    tran.rollback();
                } 
catch  (Exception e1) {
                    e1.printStackTrace();
                }
            }
        }
    }
    
     public   void  testSelect(){
        List list 
=  session.createQuery( "  from TItem " ).list();
        
        Iterator it 
=  list.iterator();
        
while  (it.hasNext()) {
            TItem item 
=  (TItem)it.next();
            System.out.println(item.getName());
            
        }
    }
}

4.在HQL Scratchpad中输入 From TItem,在Hibernate Dynamic Query Translator中观察到如下的SQL语句:
select
  titem0_.id 
as  id16_,
  titem0_.name 
as  name16_,
  titem0_.manufacturer 
as  manufact3_16_,
  titem0_1_.regioncode 
as  regioncode17_,
  titem0_2_.pagecount 
as  pagecount18_,
  
case  
   
when  titem0_1_.id  is   not   null   then   1  
   
when  titem0_2_.id  is   not   null   then   2  
   
when  titem0_.id  is   not   null   then   0  
  
end   as  clazz_ 
 
from
  sample.T_Item titem0_ 
 
left   outer   join
  sample.T_DVD titem0_1_ 
   
on  titem0_.id = titem0_1_.id 
 
left   outer   join
  sample.T_Book titem0_2_ 
   
on  titem0_.id = titem0_2_.id

你可能感兴趣的:(Hibernate实体层次设计(三))