Hibernate 主键生成策略
主键生成策略
Hibernate提供相应的API能自动生成数据库表,说到表,一定会设计到的一个概念就是主键,主键是由程序自动生成的,不应该由用户自己输入,那么Hibernate在往表中填充数据库时,主键是怎么生成的那,Hibernat提供了主键生成策略,下面主要讲一下常用的几种,配置形式如下:
首先我们来看一下实体类的配置文件,里面有很多生成主键的方式
<class name="com.hu.two.entity.Student" table="t_hibernate_student">
<id name="sid" type="java.lang.Integer" column="sid">
<!-- <generator class="assigned" /> --><!-- 自己定义主键,没有就包错 -->
<!-- <generator class="increment" /> --> <!-- 自动增长(Hibernate维护) -->
<!-- <generator class="identity" /> --> <!-- 自动增长(数据库维护) -->
<!--<generator class="native" />--> <!-- 数据库自行判断采用identity、sequence其中一种作为主键生成方式,灵活性很强 -->
<!-- <generator class="uuid" /> --> <!-- 自动生成32位的字符串,做唯一标识 -->
<!-- <generator class="sequence" > <param name="sequence_name">aaa</param> </generator> --><!-- 指定使用那个序列 ->
<!-- <generator class="com.javaxl.two.id.Myts" /> --><!-- 自定义增长 -->
</id>
<property name="sname" type="java.lang.String" column="sname">
</property>
</class>
若主键是int类型
1. assigned
assigned主键增长方式很少使用,这个是需要自己手动增加,不管你的数据库是不是定义了自动增长。
特点:数据类型不限、保存前必须赋值
2.increment(常用)
Increment方式对主键值采取自动增长的方式生成新的主键值,但要求底层数据库的主键类型为long,int等数值型。主键按数值顺序递增,增量为1。
特点:integer类型,无需赋值
3.identity(常用)
identity是由底层数据库自己生成的标识符,但这个主键必须设置为自增长,由数据库生成,使用identity的前提条件是底层数据库支持自动增长字段类型,如SQL Server、MySQL等,Oracle这类没有自增字段的则不支持。如果使用MySQL数据库,则主键字段必须设置成auto_increment(此句上网查得的),但是自己试验得出,Hibernate在创建MySql中的表时会自动将该字段设置成auto_increment,该字段必须设置为是能自增的数据类型,否则会报错:ERROR SchemaExport:274 - Unsuccessful: create table User (id varchar(255) not null auto_increment
特点:integer类型,无需赋值。
4.native(常用)
native由hibernate根据使用的数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式,灵活性很强,这样以来如果一个项目中使用多个数据库时,就可以使用这种方式
5.sequence
只适用于支持sequence机制生成主键的数据库,主键值由数据库生成,如MySql就不支持,Oracle就支持
若主键是varchar类型
1.uuid
Universally Unique Identifier的缩写,通用唯一识别码,UUID是由一组32位数的16进制数字所构成是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的; Hibernate在保存对象时,生成一个uuid字符串作为主键,保证了唯一性,但其无任何业务逻辑意义; 适用与所有的数据库,但是生成的主键占用的存储空间较大
2.自定义主键
实现org.hibernate.id.IdentifierGenerator接口即可
package com.hu.two.id;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentifierGenerator;
/**
* 自定义生成主键
* @author Administrator
*
*/
public class Myts implements IdentifierGenerator {
@Override
public Serializable generate(SharedSessionContractImplementor arg0, Object arg1) throws HibernateException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
return "zking_shop_book_"+sdf.format(new Date());
}
}
对数据库的依赖性
1.UUID,increment、Hilo、assigned:对数据库无依赖
2.identity:依赖Mysql或sql server,主键值不由hibernate维护
3.sequence:适合于oracle等支持序列的dbms,主键值不由hibernate维护,由序列产生
4.native:根据底层数据库的具体特性选择适合的主键生成策略,如果是mysql或sqlserver,选择5.identity,如果是oracle,选择sequence
实例
我这里就测试一下自定义的增长方式,测试的方法都一样,只是实体类的主键方式不一样。
package com.hu.two.dao.DemoDao;
import java.io.Serializable;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.hu.two.entity.Student;
import com.hu.two.entity.Worker;
import com.hu.two.util.SessionFactoryUtils;
public class StudentDao {
/**
* 添加学生
* @param stu
* @return
*/
public Serializable addStudent(Student stu) {
Session session = SessionFactoryUtils.openSession();
Transaction transaction = session.beginTransaction();
Serializable saveId = session.save(stu);
transaction.commit();
session.close();
return saveId;
}
/**
* 添加功能
* @param work
* @return
*/
public Serializable addWork(Worker work) {
Session session = SessionFactoryUtils.openSession();
Transaction transaction = session.beginTransaction();
Serializable saveId = session.save(work);
transaction.commit();
session.close();
return saveId;
}
public static void main(String[] args) {
StudentDao dao = new StudentDao();
Worker work = new Worker();
work.setWname("我就是不一样");
System.out.println(dao.addWork(work));
}
}
控制台打印结果
数据库结果:
插入成功