zoukankan      html  css  js  c++  java
  • Hibernate之主键生成策略

    hibernate的主键生成器:
    generator元素:表示了一个主键生成器,它用来为持久化类实例生成唯一的标识 。


    1 程序员自己控制:assigned

    2 数据库控制: identity(标识列/自动增长) sequence

    3 hibernate控制:increment uuid/uuid.hex

    4 其它:native

    assigned:

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

    <id name="sid" type="java.lang.Integer" column="sid">

    <generator class="assigned" />

    </id>

    特点:可以跨数据库,人为控制主键生成。

    increment:

    由Hibernate从数据库中取出主键的最大值(每个session只取1次),以该值为基础,每次增量为1,在内存中生成主键,不依赖于底层的数据库,因此可以跨数据库。

    <id name="sid" type="java.lang.Integer" column="sid">

    <generator class="increment" />

    </id>

    Hibernate调用org.hibernate.id.IncrementGenerator类里面的generate()方法,使用select max(idColumnName) from tableName语句获取主键最大值。该方法被声明成了synchronized,所以在一个独立的Java虚拟机内部是没有问题的,然而,在多个JVM同时并发访问数据库select max时就可能取出相同的值,再insert就会发生Dumplicate entry的错误。所以只能有一个Hibernate应用进程访问数据库,否则就可能产生主键冲突,所以不适合多进程并发更新数据库,适合单一进程访问数据库,不能用于群集环境。

    特点:跨数据库,不适合多进程并发更新数据库,适合单一进程访问数据库,不能用于群集环境。

    identity:

    identity由底层数据库生成标识符。identity是由数据库自己生成的,但这个主键必须设置为自增长,使用identity的前提条件是底层数据库支持自动增长字段类型

    <id name="id" column="id">

    <generator class="identity" />

    例:如果使用MySQL数据库,则主键字段必须设置成auto_increment。

    id int(11) primary key auto_increment

    特点:只能用在支持自动增长的字段数据库中使用,如MySQL。

    sequence:

    采用数据库提供的sequence机制生成主键,需要数据库支持sequence。

    <generator class="sequence" >
    <param name="sequence_name">aaa</param>
    </generator> -->

    Hibernate生成主键时,查找sequence并赋给主键值,主键值由数据库生成,Hibernate不负责维护,使用时必须先创建一个sequence,如果不指定sequence名称,则使用Hibernate默认的sequence,名称为hibernate_sequence,前提要在数据库中创建该sequence。

    特点:只能在支持序列的数据库中使用。


    案例演示:

    1.在数据库中建好测试的表(这里用的MYSQL)

    表的实体类:

    package com.psy.two.entity;
    
    import java.io.Serializable;
    
    public class Student implements Serializable{
    
        private Integer sid;
        private String sname;
        public Integer getSid() {
            return sid;
        }
        public void setSid(Integer sid) {
            this.sid = sid;
        }
        public String getSname() {
            return sname;
        }
        public void setSname(String sname) {
            this.sname = sname;
        }
        public Student(Integer sid, String sname) {
            super();
            this.sid = sid;
            this.sname = sname;
        }
        public Student() {
            super();
            // TODO Auto-generated constructor stub
        }
        @Override
        public String toString() {
            return "Student [sid=" + sid + ", sname=" + sname + "]";
        }
        
    }
    package com.psy.two.entity;
    
    public class Worker {
    
        private String wid;
        private String wname;
        public String getWid() {
            return wid;
        }
        public void setWid(String wid) {
            this.wid = wid;
        }
        public String getWname() {
            return wname;
        }
        public void setWname(String wname) {
            this.wname = wname;
        }
        public Worker(String wid, String wname) {
            super();
            this.wid = wid;
            this.wname = wname;
        }
        public Worker() {
            super();
            // TODO Auto-generated constructor stub
        }
        @Override
        public String toString() {
            return "Worker [wid=" + wid + ", wname=" + wname + "]";
        }
        
    }

    实体映射文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name="com.psy.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="sequence" /> --> <!--  由数据库控制-->
                <!-- <generator class="identity" > 
                <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>
    </hibernate-mapping>
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name="com.psy.two.entity.Worker" table="t_hibernate_worker">
            <id name="wid" type="java.lang.String" column="wid">
                <!-- <generator class="assigned" /> -->
                <!-- <generator class="uuid" />  -->
                <!-- <generator class="sequence" > <param name="sequence_name">aaa</param> 
                    </generator> -->
                <generator class="com.psy.two.id.Myts" />
            </id>
    
            <property name="wname" type="java.lang.String" column="wname">
            </property>
        </class>
    </hibernate-mapping>

    SessionFactoryUtils工具类(用来检测所写映射文件是否正确)

    package com.psy.two.util;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    
    /**
     * 
     * 
     * 
     * 作用:
     * 可以用来检测所写的映射文件是否正确
     * @author Admin
     *
     */
    public class SessionFactoryUtils {
        private static SessionFactory sessionFactory;
    //    存放当前会话
        private static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
        static {
            Configuration cfg = new Configuration();
            Configuration configure = cfg.configure("/hibernate.cfg.xml");
            sessionFactory = configure.buildSessionFactory();
        }
        
        public static Session openSession() {
            Session session = threadLocal.get();
            if (null == session) {
                session = sessionFactory.openSession();
                threadLocal.set(session);
            }
            return session;
        }
    
        public static void closeSession() {
            Session session = threadLocal.get();
            if (null != session) {
                if (session.isOpen()) {
                    session.close();
                }
                threadLocal.set(null);
            }
        }
    
        public static void main(String[] args) {
            Session session = openSession();
            System.out.println(session.isConnected());
            closeSession();
        }
        
    }

    主配置文件hibernate.cfg.xml

    <!-- 讲解主键生成策略 -->
            <mapping resource="com/psy/two/entity/Worker.hbm.xml" />
            <mapping resource="com/psy/two/entity/Student.hbm.xml" />
            

    测试类:

    package com.psy.two.dao;
    
    import java.io.Serializable;
    
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    
    import com.psy.two.entity.Student;
    import com.psy.two.entity.Worker;
    import com.psy.two.util.SessionFactoryUtils;
    
    public class DemoDao {
    
        /**
         * |添加学生
         * @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 worker
         * @return
         */
        public Serializable addWorker(Worker worker) {
            Session session = SessionFactoryUtils.openSession();
            Transaction transaction = session.beginTransaction();
            Serializable saveId = session.save(worker);
            
            transaction.commit();
            session.close();
            
            return saveId;
        }
        
        
        public static void testStudent(String[] args) {
            DemoDao dao=new DemoDao();
            Student stu =new Student();
            stu.setSid(22);
            stu.setSname("辣鸡");
            System.out.println(dao.addStudent(stu));
        }
        
        public static void main(String[] args) {
            DemoDao dao=new DemoDao();
            Worker worker=new Worker();
            worker.setWname("enh");
            
            System.out.println(dao.addWorker(worker));
        }
        
        
        
    }
  • 相关阅读:
    cron表达式解释
    mysql explain执行计划
    基于Groovy编写Ngrinder脚本常用方法
    JVM内存结构、参数调优和内存泄露分析
    Jmeter教程 简单的压力测试
    jmeter接口测试之登录测试
    jmeter之线程组的使用
    使用ANT自动执行JMeter用例
    Jmeter参数化随机取值实现
    Jmeter测试接口文档
  • 原文地址:https://www.cnblogs.com/psyu/p/11185149.html
Copyright © 2011-2022 走看看