要实现复合主键必须满足如下要求:
1.类必须实现Serializable接口
2.复写equals和hashCode方法
public boolean equals(Object obj)
{
if(this==obj)
{
return true;
}
if(!obj.instanceOf(Person))
{
return false;
}
return super.equals(obj);
}
public int hashCode()
{
return super.hashCode();
}
对于复写2方法可使用第三方插件:
commons-lang-1.0.jar
public boolean equals(Object obj)
{
if(this==obj)
{
return true;
}
if(!obj.instanceOf(Person))
{
return false;
}
Person p = (Person)obj;
return new EqualsBuilder().append(this.id,p.id).append(this.name,p.name).append(this.age,p.age).isEquals();
}
public int hashCode()
{
return new HashCodeBuilder().append(this.id).append(this.name).append(this.age).toHashCode();
}
例如我们现在有张person表:
create table person
(
name varchar(100) not null,
phone varchar(50),
age int,
primary key(name,phone)
);
那么person表对应的POJO类该如何写呢?
package org.lxh.hibernate02;
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
public class Person implements Serializable {
private String name;
private String phone;
private int age;
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Person)) {
return false;
}
Person p = (Person) obj;
return new EqualsBuilder().append(this.name, p.name).append(this.phone,
p.phone).append(this.age, p.age).isEquals();
}
public int hashCode() {
return new HashCodeBuilder().append(this.name).append(this.age).append(
this.phone).toHashCode();
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
一切准备工作做好之后就是生成配置文件了,配置并修改文件为:
<class name="Person" table="PERSON">
<composite-id>
<key-property name="name" column="NAME" type="string"/>
<key-property name="phone" column="PHONE" type="string"/>
</composite-id>
<property name="age" column="AGE" type="int" />
</class>
剩下就是编写操作类了:
package wjr.hibernate.demo18;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
public class PersonOperate {
private Session session = null;
public PersonOperate()
{
Configuration config = new Configuration().configure();
session = config.buildSessionFactory().openSession();
}
public void insert(Person p)
{
// 将数据存放到数据库之中
this.session.save(p) ;
// 事务提交
this.session.beginTransaction().commit() ;
}
//更新tel或者zipcode:
public void update(Person p)
{
session.update(p);
session.beginTransaction().commit();
session.close();
}
public List queryAll()
{
String hql = "FROM Person as p" ;
Query q = this.session.createQuery(hql) ;
List l = q.list() ;
return l ;
}
}
*********************************************************
package wjr.hibernate.demo18;
public class TestPerson {
public static void main(String[] args) {
Person p = new Person() ;
p.setName("李兴华") ;
p.setPhone("6666666") ;
p.setAge(28) ;
PersonOperate po = new PersonOperate() ;
po.insert(p) ;
}
}
测试成功。
但是一般开发中在生成配置文件时,会自动生成一个主键类,复合主键就是在生成配置文件时,会自动生成一个单独的PersonPK.java主键类,
这时composite节点定义为:<composite-id name="id" class="wjr.hibernate.demo18_2.PersonPK">
一般情况下在PersonPK.java这个类中会自动生成复写了的equals和hashCode方法,如果没有就自己写吧。
然后在Person.java类中这样定义:private PersonPK id;就OK了。
开发中一般都采用此种方法。而不使用一般的实体映射,主要是为了保证复合关键字段能一次都被加入。
这时Person类变为:
package wjr.hibernate.demo18_2;
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
public class Person implements Serializable {
private PersonPK id;
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public PersonPK getId() {
return id;
}
public void setId(PersonPK id) {
this.id = id;
}
}
PersonPK.java类为:
package wjr.hibernate.demo18_2;
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
public class PersonPK implements Serializable
{
private volatile int hashValue = 0;
private java.lang.String name;
private java.lang.String phone;
public PersonPK()
{
}
public java.lang.String getName()
{
return name;
}
public void setName(java.lang.String name)
{
hashValue = 0;
this.name = name;
}
public java.lang.String getPhone()
{
return phone;
}
public void setPhone(java.lang.String phone)
{
hashValue = 0;
this.phone = phone;
}
public boolean equals(Object obj)
{
if (this == obj) {
return true;
}
if (!(obj instanceof Person)) {
return false;
}
PersonPK p = (PersonPK) obj;
return new EqualsBuilder().append(this.name, p.getName()).append(this.phone,
p.getPhone()).isEquals();
}
public int hashCode()
{
return new HashCodeBuilder().append(this.name).append(
this.phone).toHashCode();
}
}
然后是写测试类了:
package org.lxh.hibernate03;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
public class PersonOperate {
private Session session ;
public PersonOperate()
{
this.session = new Configuration().configure().buildSessionFactory().openSession() ;
}
public void insert(Person p)
{
this.session.save(p) ;
this.session.beginTransaction().commit() ;
}
}
***********************************************************
package org.lxh.hibernate03;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO 自动生成方法存根
Person p = new Person() ;
PersonKey pk = new PersonKey() ;
pk.setName("MLDN") ;
pk.setPhone("888888") ;
p.setAge(28) ;
p.setId(pk) ;
PersonOperate po = new PersonOperate() ;
po.insert(p) ;
}
}