hibernate之主键生成策略

一、主键类型
1.自然主键(主键本身就是表中的一个字段,实体中一个具体的属性)
表中已经具有某字段,并且该字段具有业务含义作为主键,称之为自然主键。

例如:在person表中的身份证号,既是唯一的,又可以单独标识一个person

2.代理主键(主键不是实体中某个具体的属性,而是一个不相关的字段)
表中原本不存在的字段,且不具备业务含义的字段作为主键,称之为代理主键。更合理的方式是使用代理主键。

二、主键生成策略
主键生成策略,就是每条记录录入时,主键的生成规则。Hibernate中,提供了几个内置的主键生成策略,其常用主键生成策略的名称和描述如下

1.代理主键
identity(主键自增)
适用于long、short或int类型主键,采用底层数据库本身提供的主键生成标识符。在DB2、MySQL、MS SQL Server、Sybase和HypersonicSQL数据库中可以使用该生成器,该生成器要求在数据库中把主键定义成为自增类型。Oracle没有自动增长

sequence(序列)
适用于long、short或int类型主键,Hibernate根据底层数据库序列生成标识符。条件是数据库支持序列。如oralce、DB、SAP DB、PostgerSQL、McKoi中的sequence,MySQL这种不支持sequence

increment(主键自增,单线程,maxID+1)
适用于long、short或int类型主键,由Hibernate提供自动递增的方式生成唯一标识符,每次增量为1。只有当没有其他进程向同一张表中插入数据时才可以使用,不能再多线程环境下使用

hilo(主键自增,高低位算法)
hilo(高低位方式high low)是hibernate中最常用的一种生成方式,需要一张额外的表保存hi的值。保存hi值的表至少有一条记录(只与第一条记录有关),否则会出现错误。跨数据库,hilo算法生成的标志只能在一个数据库中保证唯一

native(hilo+identity+sequence三选一)
根据底层数据库对自动生成标识符的能力来选择i dentity、sequence、hilo三种生成器中的一种,适合跨数据库平台开发

uuid(随机字符串作主键)
Hibernate采用128位的UUID算法来生成标识符。该算法能够在网络环境中生成唯一的字符串标识符,其UUID被编码为一个长度为32位的十六进制字符串。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字

uuid长度大,占用空间大,跨数据库,不用访问数据库就生成主键值,所以效率高且能保证唯一性,移植非常方便,推荐使用。

guid(全球唯一标识符)
全球唯一标识符,也称作 UUID,是一个128位长的数字,用16进制表示。算法的核心思想是结合机器的网卡、当地时间、一个随即数来生成GUID。

Hibernate在维护主键时,先查询数据库,获得一个uuid字符串,该字符串就是主键值,该值唯一,缺点长度较大,支持数据库有限,优点同uuid,跨数据库,但是仍然需要访问数据库。注意:长度因数据库不同而不同。

需要数据库支持查询uuid,生成时需要查询数据库,效率没有uuid高,推荐使用uuid。

2.自然主键
assigned(用户手动录入)
由Java程序负责生成标识符,Hibernate不管理主键,用户手动设置主键的值。如果不指定id元素的generator属性,则默认使用该主键生成策略。



内容:

1 assigned
数据类型不限、保存前必须赋值

2 identity
数字,无需赋值

3 sequence
数字,无需赋值, 默认使hibernate_sequence这个序列,
也可以通过sequence/sequence_name参数赋值

4 increment
数字,无需赋值

5 uuid/uuid.hex (是由容器自动生成的一个32位的字符串,.hex代表的是十六进制)
32位的字符串,无需赋值,

6 native
等于identity+sequence

导入SessionFactoryUtils类

 1 public class SessionFactoryUtils {
 2     private static SessionFactory sessionFactory;
 3 //    存放当前会话
 4     private static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
 5     static {
 6         Configuration cfg = new Configuration();
 7         Configuration configure = cfg.configure("/hibernate.cfg.xml");
 8         sessionFactory = configure.buildSessionFactory();
 9     }
10
11     public static Session openSession() {
12         Session session = threadLocal.get();
13         if (null == session) {
14             session = sessionFactory.openSession();
15             threadLocal.set(session);
16         }
17         return session;
18     }
19
20     public static void closeSession() {
21         Session session = threadLocal.get();
22         if (null != session) {
23             if (session.isOpen()) {
24                 session.close();
25             }
26             threadLocal.set(null);
27         }
28     }
29
30     public static void main(String[] args) {
31         Session session = openSession();
32         System.out.println(session.isConnected());
33         closeSession();
34     }
35
36 }

这个类在学习hibernate的过程中所用(整合SSH框架之前用)

作用:可以用来检测所写的映射文件是否正确;

然后创建好实体类和实体映射文件

学生类:

 1 public class Student implements Serializable  {
 2
 3       private Integer sid;
 4       private String sname;
 5         public Integer getSid() {
 6             return sid;
 7         }
 8         public void setSid(Integer sid) {
 9             this.sid = sid;
10         }
11         public String getSname() {
12             return sname;
13         }
14         public void setSname(String sname) {
15             this.sname = sname;
16         }
17         @Override
18         public String toString() {
19             return "Worker [sid=" + sid + ", sname=" + sname + "]";
20         }
21 }

工人类:

 1 public class Worker implements Serializable{
 2        private String wid;
 3        private String wname;
 4     public String getWid() {
 5         return wid;
 6     }
 7     public void setWid(String wid) {
 8         this.wid = wid;
 9     }
10     public String getWname() {
11         return wname;
12     }
13     public void setWname(String wname) {
14         this.wname = wname;
15     }
16     @Override
17     public String toString() {
18         return "Worker [wid=" + wid + ", wname=" + wname + "]";
19     }
20
21
22
23 }

两个实体映射文件:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping>
 6     <class name="two.entity.Student" table="t_hibernate_student">
 7         <id name="sid" type="java.lang.Integer" column="sid">
 8             <!-- <generator class="assigned" />-->
 9             <!-- <generator class="identity" />  -->
10              <generator class="increment" />
11             <!-- <generator class="sequence" /> -->
12             <!-- <generator class="sequence" > <param name="sequence_name">aaa</param>
13                 </generator> -->
14             <!-- <generator class="com.javaxl.two.id.Myts" /> -->
15         </id>
16         <property name="sname" type="java.lang.String" column="sname">
17         </property>
18     </class>
19 </hibernate-mapping>
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping>
 6     <class name="two.entity.Worker" table="t_hibernate_work">
 7         <id name="wid" type="java.lang.String" column="wid">
 8             <!-- <generator class="uuid" /> -->
 9             <!-- <generator class="sequence" /> -->
10             <!-- <generator class="sequence" > <param name="sequence_name">aaa</param>
11                 </generator> -->
12              <generator class="two.id.Myts" />
13         </id>
14
15         <property name="wname" type="java.lang.String" column="wname">
16         </property>
17     </class>
18 </hibernate-mapping>

dao方法

 1 public class DemoDao {
 2     /**
 3      * 添加学生
 4      * @param stu
 5      * @return
 6      */
 7        public Serializable addStudent(Student stu) {
 8            Session session=SessionFactoryUtils.openSession();
 9            Transaction transaction=session.beginTransaction();
10            Serializable saveId=session.save(stu);
11            transaction.commit();
12            session.close();
13            return saveId;
14        }
15        /**
16         * 添加工人
17         * @param worker
18         * @return
19         */
20        public Serializable addWork(Worker worker) {
21            Session session=SessionFactoryUtils.openSession();
22            Transaction transaction=session.beginTransaction();
23            Serializable saveId=session.save(worker);
24            transaction.commit();
25            session.close();
26            return saveId;
27        }
28
29
30
31 //       public static void teststudent(String[] args) {
32 //
33 //           DemoDao dao=new DemoDao();
34 //           Student stu=new Student();
35 ////           stu.setSid(4);
36 //           stu.setSname("张三");
37 //           dao.addStudent(stu);
38 //           System.out.println(dao.addStudent(stu));
39 //    }
40        public static void main(String[] args) {
41            DemoDao dao=new DemoDao();
42            Worker worker=new Worker();
43            worker.setWname("啊哈哈哈");
44            System.out.println(dao.addWork(worker));
45     }
46
47
48 }

各位大佬们可以一一去试

最后一个自定义主键生成器

需要创建一个类来设置你需要变成的id格式

如下:

public class Myts implements IdentifierGenerator {

    @Override
    public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
        // TODO Auto-generated method stub
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return "shop_book_"+sdf.format(new Date());
    }

}

在dao方法类运行:

显示如下:

原文地址:https://www.cnblogs.com/AluoKa/p/11185135.html

时间: 2024-07-31 20:43:02

hibernate之主键生成策略的相关文章

hibernate id主键生成策略

数据库的设计和操作中,我们通常会给表建立主键. 主键,可以分为自然主键和代理主键. 自然主键表示:采用具有业务逻辑含义的字段作为表的主键.比如在用户信息表中,采用用户的身份证号码作为主键.但是这样一来,随着业务逻辑的变化,主键就有可能要更改.比如,假设哪天身份证号码升级成19,2位,那....... 代理主键:在表中人为的增加一个字段,该字段并没有表示任何的业务逻辑,仅仅用来标识一行数据.比如说在用户信息表中,增加一个用户ID的字段.用来表示该条用户信息的记录. 通常情况下,用的比较多的是代理主

hibernate annotation 主键生成策略的相关配置

Hibernate 默认总共支持 13 种生成策略 : 1. increment 2.  identity 3. sequence 4. hilo 5. seqhilo 6. uuid 7. uuid.hex 8. guid 9. native 10. assigned 11. select 12. foreign 13. sequence-identity 下面介绍几个较为常用的策略 : ① identity [ 自然递增 ] 支持 DB2,MySQL,SQL Server,Sybase 和H

Hibernate常用主键生成策略

1.assign:适合于应用程序维护的自然主键. 2.increment:代理主键,适合于所有数据库,由hibernate维护主键自增,和底层数据库无关,但是不适合于2个或以上hibernate进程. 3.identity:代理主键,适合于mysql或ms sql server等支持自增的dbms,主键值不由hibernate维护. 4.sequence:代理主键,适合于oracle等支持序列的dbms,主键值不由hibernate维护,由序列产生. 5.native:代理主键,根据底层数据库的

Hibernate各种主键生成策略与配置详解

1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据库都无关,可以跨数据库.在存储对象前,必须要使用主键的setter方法给主键赋值,至于这个值怎么生成,完全由自己决定,这种方法应该尽量避免. <id name="id" column="id"> <generator class="assigned" /> </id&g

大家一起撸代码之——Hibernate各种主键生成策略与配置详解

1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据库都无关,可以跨数据库.在存储对象前,必须要使用主键的setter方法给主键赋值,至于这个值怎么生成,完全由自己决定,这种方法应该尽量避免. <id name="id" column="id"> <generator class="assigned" /> </id&g

Hibernate各种主键生成策略与配置详解【附1--&lt;generator class=&quot;foreign&quot;&gt;】

1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据库都无关,可以跨数据库.在存储对象前,必须要使用主键的setter方法给主键赋值,至于这个值怎么生成,完全由自己决定,这种方法应该尽量避免. <id name="id" column="id"> <generator class="assigned" /> </id&g

Hibernate 之主键生成策略小总结

主键生成策略大致分两种: 手工控制策略 自动生成策略[框架自动生成和数据库自动生成] 手工控制策略: assigned:类型是任意的,需要在 save() 到数据库前,编码人员手工设置主键值,也就是调用对象的 setter方法进行赋值操作. 注:可以跨数据库,但是手动控制不能保证不重复,不推荐使用. 自动生成策略: 1 . uuid:自动生成 32 位及以上的随机字符串,生成的依据包括但不限于网卡地址,时间值等. 注:可以跨数据库,效率高,能保证唯一性,推荐使用[虽然占用空间大] 2 . inc

从实例看hibernate的主键生成策略

学习了hibernate会发现,hibernate中有实体类,实体类的映射文件,但是我们怎么样才能知道实体类的主键是怎样的生成方式呢?hibernate提供的主键生成策略帮我们完美地解答了这个疑问.下面让我们一起从实例开始认识hibernate的实体生成策略. 一.首先通过User实体类和映射文件的实例 ?User的实体类 package com.bjpowernode.hibernate; import java.util.Set; public class User { private in

Hibernate各种主键生成策略与配置详解(转)

原文链接:http://www.cnblogs.com/hoobey/p/5508992.html 1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据库都无关,可以跨数据库.在存储对象前,必须要使用主键的setter方法给主键赋值,至于这个值怎么生成,完全由自己决定,这种方法应该尽量避免. <id name="id" column="id"> <ge

Hibernate各种主键生成策略与配置详解《转》

1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据库都无关,可以跨数据库.在存储对象前,必须要使用主键的setter方法给主键赋值,至于这个值怎么生成,完全由自己决定,这种方法应该尽量避免. <id name="id" column="id"> <generator class="assigned" /> </id&g