zoukankan      html  css  js  c++  java
  • 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方法类运行:

    显示如下:

  • 相关阅读:
    【小贴士】zepto find元素以及ios弹出键盘可能让你很头疼
    【iScroll源码学习04】分离IScroll核心
    【iScroll源码学习03】iScroll事件机制与滚动条的实现
    展望14,献给困惑的初级前端,理想不甘消磨,目标不能停滞!
    【iScroll源码学习02】分解iScroll三个核心事件点
    原生andriod浏览器回退后dom(click)事件全体失效问题探究
    【iScroll源码学习01】准备阶段
    【iScroll源码学习00】模拟iScroll
    【再探backbone 03】博客园单页应用实例(提供源码)
    【再探backbone 02】集合-Collection
  • 原文地址:https://www.cnblogs.com/AluoKa/p/11185135.html
Copyright © 2011-2022 走看看