Hibernate中如果在数据库表中涉及到关联到业务逻辑的组合主键时,最好的设计是使用基于实体类的组合主键,建立包含组合主键所有属性的实体类然后,在po类中指定主键类属性,在配置文件中配置主键类key—property属性,在hibernate的业务操作层可以直接按照主键类作为po识别的标志,在save,load,find等方法中其id值可以直接设置成主键类。实例代码如下:
Po类:
package com.inspur.po;
/**
* TUsers entity. @author MyEclipse Persistence Tools
*/
public class TUsers implements java.io.Serializable {
// Fields
private TUsersId id;
private Integer age;
// Constructors
/** default constructor */
public TUsers() {
}
/** minimal constructor */
public TUsers(TUsersId id) {
this.id = id;
}
/** full constructor */
public TUsers(TUsersId id, Integer age) {
this.id = id;
this.age = age;
}
// Property accessors
public TUsersId getId() {
return this.id;
}
public void setId(TUsersId id) {
this.id = id;
}
public Integer getAge() {
return this.age;
}
public void setAge(Integer age) {
this.age = age;
}
}
主键类:
package com.inspur.po;
/**
* TUsersId entity. @author MyEclipse Persistence Tools
*/
public class TUsersId implements java.io.Serializable {
// Fields
private String firstname;
private String lastname;
// Constructors
/** default constructor */
public TUsersId() {
}
/** full constructor */
public TUsersId(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
// Property accessors
public String getFirstname() {
return this.firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return this.lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public boolean equals(Object other) {
if ((this == other))
return true;
if ((other == null))
return false;
if (!(other instanceof TUsersId))
return false;
TUsersId castOther = (TUsersId) other;
return ((this.getFirstname() == castOther.getFirstname()) || (this
.getFirstname() != null
&& castOther.getFirstname() != null && this.getFirstname()
.equals(castOther.getFirstname())))
&& ((this.getLastname() == castOther.getLastname()) || (this
.getLastname() != null
&& castOther.getLastname() != null && this
.getLastname().equals(castOther.getLastname())));
}
public int hashCode() {
int result = 17;
result = 37 * result
+ (getFirstname() == null ? 0 : this.getFirstname().hashCode());
result = 37 * result
+ (getLastname() == null ? 0 : this.getLastname().hashCode());
return result;
}
}
.hbm.xm.文件配置如下:
<?xml version="1.0" encoding="utf-8"?>
<!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 Persistence Tools
-->
<hibernate-mapping>
<class name="com.inspur.po.TUsers" table="t_users" catalog="sample">
<composite-id name="id" class="com.inspur.po.TUsersId">
<key-property name="firstname" type="java.lang.String">
<column name="firstname" length="30" />
</key-property>
<key-property name="lastname" type="java.lang.String">
<column name="lastname" length="30" />
</key-property>
</composite-id>
<property name="age" type="java.lang.Integer">
<column name="age" />
</property>
</class>
</hibernate-mapping>
测试类:
package com.inspur.test;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.inspur.po.TUsers;
import com.inspur.po.TUsersId;
import junit.framework.TestCase;
public class Test extends TestCase {
Session session=null;
@Override
protected void setUp() throws Exception {
Configuration config=new Configuration().configure();
SessionFactory sessionFactory=config.buildSessionFactory();
session=sessionFactory.openSession();
}
@Override
protected void tearDown() throws Exception {
session.close();
}
public void testLoad(){
TUsersId id=new TUsersId();
id.setFirstname("liu");
id.setLastname("zhiq");
TUsers user=(TUsers)session.load(TUsers.class, id);
System.out.println(user.getAge());
}
public void testInsert(){
Transaction tran=null;
TUsersId id=new TUsersId();
id.setFirstname("liu");
id.setLastname("lulicy");
TUsers user=new TUsers();
user.setAge(30);
user.setId(id);
try{
tran=session.beginTransaction();
session.save(user);
session.flush();
tran.commit();
}catch(HibernateException e){
e.printStackTrace();
if(tran!=null){
try{
tran.rollback();
}catch(HibernateException e1){
e1.printStackTrace();
}
}
}
}
}
【二】:
如果使用基于实体类属性的组合主键时配置文件如下:
<?xml version="1.0" encoding="utf-8"?>
<!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 Persistence Tools
-->
<hibernate-mapping>
<class name="com.inspur.po.TUsers" table="t_users" catalog="sample">
<composite-id >
<key-property name="firstname" type="java.lang.String">
<column name="firstname" length="30" />
</key-property>
<key-property name="lastname" type="java.lang.String">
<column name="lastname" length="30" />
</key-property>
</composite-id>
<property name="age" type="java.lang.Integer">
<column name="age" />
</property>
</class>
</hibernate-mapping>
Po类代码:
package com.inspur.po;
import java.io.Serializable;
public class TUsers implements Serializable {
private int age;
private String firstName;
private String lastName;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public TUsers(int age, String firstName, String lastName) {
this.age = age;
this.firstName = firstName;
this.lastName = lastName;
}
public TUsers() {
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof TUsers)){
return false;
}
TUsers user=(TUsers)obj;
if(this.lastName.equals(user.lastName)&&this.firstName.equals(user.firstName)){
return true;
}else
return false;
}
@Override
public int hashCode() {
return super.hashCode();
}
}
测试类代码:
package com.inspur.test;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.inspur.po.TUsers;
import junit.framework.TestCase;
public class HibernateTest extends TestCase{
Session session=null;
@Override
protected void setUp() throws Exception {
Configuration config=new Configuration().configure();
SessionFactory sessionFactory=config.buildSessionFactory();
session=sessionFactory.openSession();
}
@Override
protected void tearDown() throws Exception {
session.close();
}
// public void testInsert(){
// Transaction tran=null;
// TUsers user=new TUsers();
// user.setAge(20);
// user.setFirstName("lzhq");
// user.setLastName("zhq");
// try{
// tran=session.beginTransaction();
// session.save(user);
// session.flush();
// tran.commit();
// }catch(HibernateException e){
// e.printStackTrace();
// if(tran!=null){
// try{
// tran.rollback();
// }catch(HibernateException e1){
// e1.printStackTrace();
// }
// }
//
// }
// }
public void testLoad(){
TUsers user=new TUsers();
user.setFirstName("liu");
user.setLastName("zhiq");
user=(TUsers)session.load(TUsers.class, user);
System.out.println(user.getAge());
}
}
在系统的设计中最好避免使用关联到业务逻辑的组合主键,一旦业务需求发生变化那么带来的将是数据库系统严重的修改,关键性的系统甚至是很难承受的。在修改遗留的系统时如果需要面对组合主键的话最好使用基于实体类的组合主键,使程序代码进一步的解耦。