Hibernate笔记之3复合主键

本文介绍如何在Hibernate中实现复合主键,包括实体类定义、配置文件设置及操作类编写。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

要实现复合主键必须满足如下要求:
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) ;
 }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值