hibernate insert 时 无主键使用复合主键

标签: hibernate insert 主键 | 发表时间:2013-09-27 14:15 | 作者:
出处:http://eric-gcm.iteye.com

复合主键,由多个字段组成主键,例如,使用一个用户的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. }   


已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [hibernate insert 主键] 推荐:

hibernate insert 时 无主键使用复合主键

- -
复合主键,由多个字段组成主键,例如,使用一个用户的firstname和lastname组成主键. 可以通过两种方式确定主键,一种是基于实体类的复合主键,另一种是通过定义主键类来实现. 不管通过哪种方式,复合主键都需要实现equals方法和hashcode方法,以作为不同数据之间是别的标志. 一.基于实体类属性的复合主键.

hibernate annotation 之 主键生成策略

- - BlogJava_首页
Hibernate 默认总共支持 13 种生成策略 :. 下面介绍几个较为常用的策略 :. ① identity [ 自然递增 ].          支持 DB2,MySQL,SQL Server,Sybase 和HypersonicSQL 数据库, 用于为 long 或 short 或 int 类型生成唯一标识.

MySQL insert性能优化

- - Rebill's Blog
对于一些数据量较大的系统,面临的问题除了是查询效率低下,还有一个很重要的问题就是插入时间长. 我们就有一个业务系统,每天的数据导入需要4-5个钟. 这种费时的操作其实是很有风险的,假设程序出了问题,想重跑操作那是一件痛苦的事情. 因此,提高大数据量系统的MySQL insert效率是很有必要的. 经过对MySQL的测试,发现一些可以提高insert效率的方法,供大家参考参考.

Oracle中Merge Into 代替Insert/Update的应用

- - 数据库 - ITeye博客
在进行SQL语句编写时,我们经常会遇到大量的同时进行Insert/Update的语句 ,也就是说当存在记录时,就更新(Update),不存在数据时,就插入(Insert). 在一个同时存在Insert和Update语法的Merge语句中,总共Insert/Update的记录数,就是Using语句中的记录数.

Hibernate面试题

- - ITeye博客
什么是Hibernate的并发机制. Hibernate并发机制:. a、Hibernate的Session对象是非线程安全的,对于单个请求,单个会话,单个的工作单元(即单个事务,单个线程),它通常只使用一次,. 如果一个Session 实例允许共享的话,那些支持并发运行的,例如Http request,session beans将会导致出现资源争用.

Hibernate Lazy属性

- - 博客园_首页
  Hibernate 的延迟加载(lazy load)是一个被广泛使用的技术. 这种延迟加载保证了应用只有在需要时才去数据库中抓取相应的记录. 通过延迟加载技术可以避免过多、过早地加载数据表里的数据,从而降低应用的内存开销. Hibernate 的延迟加载本质上就是代理模式的应用,当程序通过 Hibernate 装载一个实体时,默认情况下,Hibernate 并不会立即抓取它的集合属性、关联实体所以对应的记录,而是通过生成一个代理来表示这些集合属性、关联实体,这就是代理模式应用带来的优势.

Hibernate 缓存

- - ITeye博客
1数据缓存:(date caching) 是一种将数据暂时存于内存缓存去中的技术,缓存通常是影响系统性能的关键因素. 2.ORM的数据缓存策略有3中.   1.事务级缓存:  分为 数据库事务和 应用级事务,是基于Session的生命周期的实现,每个session都会在内部维持一个数据缓存, 随session的创建和消亡.

hibernate优化

- - 开源软件 - ITeye博客
原文 http://developer.51cto.com/art/200906/129539.htm. 文章分为十三个小块儿对Hibernate性能优化技巧进行总结性分析,分析如下:. 一、在处理大数据量时,会有大量的数据缓冲保存在Session的一级缓存中,这缓存大太时会严重显示性能,所以在使用Hibernate处理大数据量的,可以使用session.

JPA & Hibernate 注解

- - CSDN博客编程语言推荐文章
必须,name为可选,对应数据库中一的个表 . 可选,通常和@Entity配合使用,只能标注在实体的class定义处,表示实体对应的数据库表的信息 . name:可选,表示表的名称.默认地,表名和实体名称一致,只有在不一致的情况下才需要指定表名 . catalog:可选,表示Catalog名称,默认为Catalog(""). .

hibernate 大对象类型的hibernate映射

- - CSDN博客推荐文章
在 Java 中, java.lang.String 可用于表示长字符串(长度超过 255), 字节数组 byte[] 可用于存放图片或文件的二进制数据. 此外, 在 JDBC API 中还提供了 java.sql.Clob 和 java.sql.Blob 类型, 它们分别和标准 SQL 中的 CLOB 和 BLOB 类型对应.