Hibernate的ID生成策略有很多种,具体的类型可以直接查阅Hibernate的doc。简单介绍一下几个常用的id。
Hibernate的配置文件:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!--
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:HYLOCAL</property>
<property name="connection.username">HYLOCAL</property>
<property name="connection.password">123</property>
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
-->
<!-- JDBC connection pool (use the built-in) -->
<!-- <property name="connection.pool_size">1</property>-->
<property name="javax.persistence.validation.mode">none</property>
<!-- <property name="javax.persistence.validation.mode">none</property> -->
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup 这个配置会校验数据库 validate 创建表 create 更新表 update 结束后drop create-drop Automatically validates or exports schema DDL to the database when the SessionFactory is created. With create-drop, the database schema will be dropped when the SessionFactory is closed explicitly. -->
<property name="hbm2ddl.auto">create</property>
<!-- <mapping resource="com/smile/hibernate/model/Student.hbm.xml"/> -->
<mapping class="com.smile.hibernate.model.Teacher"/>
</session-factory>
</hibernate-configuration>
1、单主键的配置:
Teacher.java:
package com.smile.hibernate.model;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name="Teacher")
public class Teacher {
private int id;
private String name;
private String title;
private Date birthDate;
private Title teacherTitle;
@Enumerated(EnumType.STRING)
public Title getTeacherTitle() {
return teacherTitle;
}
public void setTeacherTitle(Title teacherTitle) {
this.teacherTitle = teacherTitle;
}
//默认为datatime类型 @Temporal(TemporalType.DATE) TemporalType.TIME TemporalType.TIMESTAMP
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name="name")
public String getName() {
return name;
}
//不想持久化的时候 使用 @Transient
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
这里使用的是注解的方式,首先一个实例需要添加注解@Entity才可以进行持久化。可以通过@Table的注解来指明对应的表名称,如果不指定则默认表名与类名一致。在主键的get方法或者是声明的地方用@Id来表名这是一个主键。同时使用
@GeneratedValue(strategy=GenerationType.SEQUENCE)
来指定ID的生成策略。
也可以使用一个表来存储主键,比较适合于跨数据库的服务:
package com.smile.hibernate;
import java.util.Date;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.SequenceGenerator;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
@Entity
public class Teacher {
private TeacherPK pk;
private int id;
private String name;
private String title;
private String yourWifeName;
private Date birthDate;
private boolean good;
private Gender gender;
@Enumerated(EnumType.STRING)
@Column(name="t_sex")
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public boolean isGood() {
return good;
}
public void setGood(boolean good) {
this.good = good;
}
@Transient
public String getYourWifeName() {
return yourWifeName;
}
public void setYourWifeName(String yourWifeName) {
this.yourWifeName = yourWifeName;
}
@Id
@GeneratedValue(strategy=GenerationType.TABLE, generator="Teacher_GEN")
@javax.persistence.TableGenerator(
name="Teacher_GEN",
table="GENERATOR_TABLE",
pkColumnName = "pk_key",
valueColumnName = "pk_value",
pkColumnValue="Teacher",
allocationSize=1
)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Temporal(TemporalType.TIME)
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
}
对于oracle来说也可以直接通过注解声明一个sequence,后面来使用:
@SequenceGenerator(name="teacherSEQ", sequenceName="teacherSEQ_DB")
2、联合主键的配置
联合主键的实现需要一个创建一个类来实现:
package com.smile.hibernate;
import javax.persistence.Embeddable;
@Embeddable
public class TeacherPK implements java.io.Serializable{
private int id;
private String name;
// @Column(name = "t_id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
// @Column(name = "t_name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if(o instanceof TeacherPK) {
TeacherPK pk = (TeacherPK)o;
if(this.id == pk.getId() && this.name.equals(pk.getName())) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
return this.name.hashCode();
}
}
这个类有几个需要注意的地方:1、实现Serializable接口。2、重写equals方法用于判定主键的重复与否。3、重写hashCode方法已便于查找。同时添加注解@Embeddable。
修改Teacher.java:
package com.smile.hibernate;
import java.util.Date;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.SequenceGenerator;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
@Entity
public class Teacher {
private TeacherPK pk;
private String title;
private String yourWifeName;
private Date birthDate;
private boolean good;
private Gender gender;
@Enumerated(EnumType.STRING)
@Column(name="t_sex")
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public boolean isGood() {
return good;
}
public void setGood(boolean good) {
this.good = good;
}
@Transient
public String getYourWifeName() {
return yourWifeName;
}
public void setYourWifeName(String yourWifeName) {
this.yourWifeName = yourWifeName;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Temporal(TemporalType.TIME)
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
@EmbeddedId
@AttributeOverrides( {
@AttributeOverride(name = "id", column = @Column(name = "t_id")),
@AttributeOverride(name = "name", column = @Column(name = "t_name")) })
public TeacherPK getPk() {
return pk;
}
public void setPk(TeacherPK pk) {
this.pk = pk;
}
}
在Teacher中添加TeacherPK类型的属性并且在get方法中增加注解@EmbeddedId。同时可以指定对应的列名。
还有另外一种实现方式:
package com.smile.hibernate;
import java.util.Date;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.SequenceGenerator;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
@Entity
@IdClass(TeacherPK.class)
public class Teacher {
private TeacherPK pk;
private int id;
private String name;
private String title;
private String yourWifeName;
private Date birthDate;
private boolean good;
private Gender gender;
@Enumerated(EnumType.STRING)
@Column(name="t_sex")
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public boolean isGood() {
return good;
}
public void setGood(boolean good) {
this.good = good;
}
@Transient
public String getYourWifeName() {
return yourWifeName;
}
public void setYourWifeName(String yourWifeName) {
this.yourWifeName = yourWifeName;
}
@Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Id
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Temporal(TemporalType.TIME)
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
}
在Teacher上添加注解:
@IdClass(TeacherPK.class)
同时指定id name为ID
然后也可以实现相同的效果。