随笔 - 59  文章 - 70  trackbacks - 0
<2009年1月>
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567

常用链接

留言簿(5)

随笔分类

随笔档案

搜索

  •  

积分与排名

  • 积分 - 172081
  • 排名 - 338

最新评论

阅读排行榜

评论排行榜

复合主键,由多个字段组成主键,例如,使用一个用户的firstname和lastname组成主键。

可以通过两种方式确定主键,一种是基于实体类的复合主键,另一种是通过定义主键类来实现。
不管通过哪种方式,复合主键都需要实现equals方法和hashcode方法,以作为不同数据之间是别的标志。

一.基于实体类属性的复合主键
主键由实体类中的属性组成。

1.映射文件TUser.hbm.xml

xml 代码
  1. <? xml   version = "1.0" ?>   
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"   
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >   
  4. < hibernate-mapping >   
  5.      < class   name = "cn.blogjava.start.TUser"   table = "t_user"   catalog = "sample" >   
  6.          < composite-id >   
  7.              < key-property   name = "lastname"   column = "lastname"   type = "string"   />   
  8.              < key-property   name = "firstname"   column = "firstname"   type = "string"   />   
  9.          </ composite-id >   
  10.   
  11.          < property   name = "age"   type = "integer"   column = "age" />   
  12.      </ class >   
  13. </ hibernate-mapping >   

2.TUser.java

java 代码
  1. package  cn.blogjava.start;   
  2.   
  3. import  org.apache.commons.lang.builder.EqualsBuilder;   
  4. import  org.apache.commons.lang.builder.HashCodeBuilder;   
  5.   
  6. /**  
  7.  * TUser generated by hbm2java  
  8.  */   
  9.   
  10. public   class  TUser  implements  java.io.Serializable {   
  11.   
  12.      // Fields       
  13.   
  14.      private  Integer age;   
  15.   
  16.      private  String firstname;   
  17.   
  18.      private  String lastname;   
  19.   
  20.      public  Integer getAge() {   
  21.          return  age;   
  22.     }   
  23.   
  24.      public   void  setAge(Integer age) {   
  25.          this .age = age;   
  26.     }   
  27.   
  28.      public  String getFirstname() {   
  29.          return  firstname;   
  30.     }   
  31.   
  32.      public   void  setFirstname(String firstname) {   
  33.          this .firstname = firstname;   
  34.     }   
  35.   
  36.      public  String getLastname() {   
  37.          return  lastname;   
  38.     }   
  39.   
  40.      public   void  setLastname(String lastname) {   
  41.          this .lastname = lastname;   
  42.     }   
  43.        
  44.      public   boolean  equals(Object obj) {   
  45.          if (!(obj  instanceof  TUser)) {   
  46.              return   false ;   
  47.         }   
  48.            
  49.         TUser user = (TUser)obj;   
  50.          return   new  EqualsBuilder()           // EqualsBuilder 和HashCodeBuilder均为apache common lang包中的工具类   
  51.             .appendSuper( super .equals(obj))   
  52.             .append( this .lastname, user.lastname)   
  53.             .append( this .firstname, user.firstname)   
  54.             .isEquals();           
  55.     }   
  56.        
  57.      public   int  hasCode() {   
  58.          return   new  HashCodeBuilder(- 528253723 , - 475504089 )   
  59.             .appendSuper( super .hashCode())   
  60.             .append( this .lastname).append( this .firstname)   
  61.             .toHashCode();   
  62.                
  63.     }   
  64.   
  65. }  

3.测试类HibernateTest.java

java 代码
  1. package  cn.blogjava.start;   
  2.   
  3. import  junit.framework.Assert;   
  4. import  junit.framework.TestCase;   
  5.   
  6. import  org.hibernate.HibernateException;   
  7. import  org.hibernate.Session;   
  8. import  org.hibernate.SessionFactory;   
  9. import  org.hibernate.Transaction;   
  10. import  org.hibernate.cfg.Configuration;   
  11.   
  12.   
  13. public   class  HibernateTest  extends  TestCase {   
  14.        
  15.     Session session =  null ;   
  16.      /**  
  17.      * JUnit中的setUp方法在TestCase初始化的时候会自动调用  
  18.      * 一般用于初始化公用资源  
  19.      */   
  20.      protected   void  setUp() {   
  21.          try  {   
  22.              /**  
  23.              * 可以采用hibernate.properties或者hibernate.cfg.xml  
  24.              * 配置文件的初始化代码  
  25.              *   
  26.              * 采用hibernate.properties  
  27.              * Configuration config = new Configuration();  
  28.              * config.addClass(TUser.class);  
  29.              */   
  30.                
  31.              //采用hibernate.cfg.xml配置文件,与上面的方法对比,两个差异   
  32.              //1.Configuration的初始化方式   
  33.              //2.xml   
  34.             Configuration config =  new  Configuration().configure();   
  35.             SessionFactory sessionFactory = config.buildSessionFactory();   
  36.             session = sessionFactory.openSession();   
  37.                
  38.         }  catch  (HibernateException e) {   
  39.              // TODO: handle exception   
  40.             e.printStackTrace();   
  41.         }           
  42.     }   
  43.   
  44.      /**  
  45.      * JUnit中的tearDown方法在TestCase执行完毕的时候会自动调用  
  46.      * 一般用于释放资源  
  47.      */        
  48.      protected   void  tearDown() {   
  49.          try  {   
  50.             session.close();           
  51.         }  catch  (HibernateException e) {   
  52.              // TODO: handle exception   
  53.             e.printStackTrace();   
  54.         }           
  55.     }       
  56.        
  57.      /**  
  58.      * 对象持久化测试(Insert方法)  
  59.      */            
  60.      public   void  testInsert() {   
  61.         Transaction tran =  null ;   
  62.          try  {   
  63.             tran = session.beginTransaction();   
  64.             TUser user =  new  TUser();   
  65.             user.setFirstname( "bai" );   
  66.             user.setLastname( "yunfeng" );   
  67.             user.setAge( 26 );   
  68.             session.save(user);   
  69.             session.flush();   
  70.             tran.commit();   
  71.         }  catch  (HibernateException e) {   
  72.              // TODO: handle exception   
  73.             e.printStackTrace();   
  74.             Assert.fail(e.getMessage());   
  75.              if (tran !=  null ) {   
  76.                  try  {   
  77.                     tran.rollback();   
  78.                 }  catch  (Exception e1) {   
  79.                      // TODO: handle exception   
  80.                     e1.printStackTrace();   
  81.                 }   
  82.             }   
  83.         }   
  84.     }   
  85.        
  86.      /**  
  87.      * 对象读取测试(Select方法)  
  88.      */                
  89.      public   void  testSelect(){   
  90.         TUser user =  new  TUser();   
  91.         user.setFirstname( "bai" );   
  92.         user.setLastname( "yunfeng" );   
  93.            
  94.         user = (TUser)session.load(TUser. class , user);   
  95.         Assert.assertEquals(user.getAge().intValue(),  26 );   
  96.     }   
  97. }   

基于主键类的复合主键:
方法:将主键字段从POJO类中提出了,生成一个主键类。
可以将1中的例子加以改造,将firstname和lastname字段单独提取到一个主键类中。

1.
配置文件TUser.hbm.xml
composite-id节点的name指定了实体类中的主键类的属性名.

xml 代码
  1. <? xml   version = "1.0" ?>   
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"   
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >   
  4. < hibernate-mapping   package = "cn.blogjava.start" >   
  5.      < class   name = "TUser"   table = "t_user"   catalog = "sample" >   
  6.          < composite-id   name = "userPK"   class = "TUserPK" >   
  7.              < key-property   name = "lastname"   column = "lastname"   type = "string"   />   
  8.              < key-property   name = "firstname"   column = "firstname"   type = "string"   />   
  9.          </ composite-id >   
  10.   
  11.          < property   name = "age"   type = "integer"   column = "age" />   
  12.      </ class >   
  13. </ hibernate-mapping >   

2.POJO类

  1. package  cn.blogjava.start;   
  2.   
  3. /**  
  4.  * TUser generated by hbm2java  
  5.  */   
  6.   
  7. public   class  TUser  implements  java.io.Serializable {   
  8.   
  9.      // Fields       
  10.   
  11.      private  Integer age;   
  12.        
  13.      //配置文件composite-id的name属性   
  14.      private  TUserPK userPK;   
  15.   
  16.   
  17.      public  Integer getAge() {   
  18.          return  age;   
  19.     }   
  20.   
  21.      public   void  setAge(Integer age) {   
  22.          this .age = age;   
  23.     }   
  24.   
  25.      public  TUserPK getUserPK() {   
  26.          return  userPK;   
  27.     }   
  28.   
  29.      public   void  setUserPK(TUserPK userPK) {   
  30.          this .userPK = userPK;   
  31.     }   
  32. }  

3.主键类TUserPK.java

java 代码
  1. package  cn.blogjava.start;   
  2.   
  3. import  java.io.Serializable;   
  4.   
  5. import  org.apache.commons.lang.builder.EqualsBuilder;   
  6. import  org.apache.commons.lang.builder.HashCodeBuilder;   
  7.   
  8. public   class  TUserPK  implements  Serializable {   
  9.   
  10.      private  String firstname;   
  11.      private  String lastname;   
  12.   
  13.      public  String getFirstname() {   
  14.          return  firstname;   
  15.     }   
  16.   
  17.      public   void  setFirstname(String firstname) {   
  18.          this .firstname = firstname;   
  19.     }   
  20.   
  21.      public  String getLastname() {   
  22.          return  lastname;   
  23.     }   
  24.   
  25.      public   void  setLastname(String lastname) {   
  26.          this .lastname = lastname;   
  27.     }   
  28.        
  29.      public   boolean  equals(Object obj) {   
  30.          if (!(obj  instanceof  TUserPK)) {   
  31.              return   false ;   
  32.         }   
  33.            
  34.         TUserPK userPK = (TUserPK)obj;   
  35.          return   new  EqualsBuilder()   
  36.             .appendSuper( super .equals(obj))   
  37.             .append( this .lastname, userPK.lastname)   
  38.             .append( this .firstname, userPK.firstname)   
  39.             .isEquals();           
  40.     }   
  41.        
  42.      public   int  hasCode() {   
  43.          return   new  HashCodeBuilder(- 528253723 , - 475504089 )   
  44.             .appendSuper( super .hashCode())   
  45.             .append( this .lastname).append( this .firstname)   
  46.             .toHashCode();               
  47.     }   
  48. }   

4.测试代码HibernateTest.java

java 代码
  1. package  cn.blogjava.start;   
  2.   
  3. import  junit.framework.Assert;   
  4. import  junit.framework.TestCase;   
  5.   
  6. import  org.hibernate.HibernateException;   
  7. import  org.hibernate.Session;   
  8. import  org.hibernate.SessionFactory;   
  9. import  org.hibernate.Transaction;   
  10. import  org.hibernate.cfg.Configuration;   
  11.   
  12.   
  13. public   class  HibernateTest  extends  TestCase {   
  14.        
  15.     Session session =  null ;   
  16.      /**  
  17.      * JUnit中的setUp方法在TestCase初始化的时候会自动调用  
  18.      * 一般用于初始化公用资源  
  19.      */   
  20.      protected   void  setUp() {   
  21.          try  {   
  22.              /**  
  23.              * 可以采用hibernate.properties或者hibernate.cfg.xml  
  24.              * 配置文件的初始化代码  
  25.              *   
  26.              * 采用hibernate.properties  
  27.              * Configuration config = new Configuration();  
  28.              * config.addClass(TUser.class);  
  29.              */   
  30.                
  31.              //采用hibernate.cfg.xml配置文件,与上面的方法对比,两个差异   
  32.              //1.Configuration的初始化方式   
  33.              //2.xml   
  34.             Configuration config =  new  Configuration().configure();   
  35.             SessionFactory sessionFactory = config.buildSessionFactory();   
  36.             session = sessionFactory.openSession();   
  37.                
  38.         }  catch  (HibernateException e) {   
  39.              // TODO: handle exception   
  40.             e.printStackTrace();   
  41.         }           
  42.     }   
  43.   
  44.      /**  
  45.      * JUnit中的tearDown方法在TestCase执行完毕的时候会自动调用  
  46.      * 一般用于释放资源  
  47.      */        
  48.      protected   void  tearDown() {   
  49.          try  {   
  50.             session.close();           
  51.         }  catch  (HibernateException e) {   
  52.              // TODO: handle exception   
  53.             e.printStackTrace();   
  54.         }           
  55.     }       
  56.        
  57.      /**  
  58.      * 对象持久化测试(Insert方法)  
  59.      */            
  60.      public   void  testInsert() {   
  61.         Transaction tran =  null ;   
  62.          try  {   
  63.             tran = session.beginTransaction();   
  64.             TUser user =  new  TUser();   
  65.             TUserPK userPK =  new  TUserPK();   
  66.             userPK.setFirstname( "yu" );   
  67.             userPK.setLastname( "yy" );   
  68.             user.setUserPK(userPK);   
  69.             user.setAge( 25 );   
  70.             session.save(user);   
  71.             session.flush();   
  72.             tran.commit();   
  73.         }  catch  (HibernateException e) {   
  74.              // TODO: handle exception   
  75.             e.printStackTrace();   
  76.             Assert.fail(e.getMessage());   
  77.              if (tran !=  null ) {   
  78.                  try  {   
  79.                     tran.rollback();   
  80.                 }  catch  (Exception e1) {   
  81.                      // TODO: handle exception   
  82.                     e1.printStackTrace();   
  83.                 }   
  84.             }   
  85.         }   
  86.     }   
  87.        
  88.      /**  
  89.      * 对象读取测试(Select方法)  
  90.      */                
  91.      public   void  testSelect(){   
  92.         TUserPK userPK =  new  TUserPK();   
  93.         userPK.setFirstname( "yu" );   
  94.         userPK.setLastname( "yy" );   
  95.            
  96.         TUser user = (TUser)session.load(TUser. class , userPK);   
  97.         Assert.assertEquals(user.getAge().intValue(),  25 );   
  98.     }   
  99. }   
posted on 2009-01-05 15:49 JasonChou 阅读(2939) 评论(0)  编辑  收藏 所属分类: j2ee

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


网站导航: