Hibernate学习笔记——主键的配置

本文介绍了Hibernate框架中ID生成策略的配置方法,包括单主键和联合主键的配置示例,并详细解释了如何使用注解定义不同的ID生成策略。

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

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

然后也可以实现相同的效果。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值