• hibernate(四)ID生成策略


    一、ID生成策略配置

    1、ID生成方式在xml中配置方式:

    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
    <hibernate-mapping package="cn.orlion.hibernate.model">
        <class name="Student" table="student"><!-- 如果表名与类名相同可以不用写table属性 -->
            <!-- 用id映射主键 -->
            <id name="id"> <!-- 列名相同可以不指定column属性 -->
                <generator class="native"></generator><!-- 在这里设置id生成方式 -->
            </id>
            
            <property name="name" column="name"></property>
            <property name="age"></property>
        </class>
    </hibernate-mapping>

    2、ID用注解配置:

    在ID注解下添加注解@generatedValue,只有四种方式,默认的策略是auto

    配置方式:@genetatedValue(strategy=GenerationType.AUTO)

    (1)AUTO - 相当于采用xml中native方式

    (2)TABLE - 使用表保存id值

    (3)IDENTITY - identity column

    (4)SEQUENCE - sequence

    在类名上添加注解@SequenceGenerator(name="teacherSEQ" , sequenceName="teacherSEQ_DB");定义sequence生成器,name属性指定的是生成器名字,sequenceName指定的是sequence名字

    在getId()方法上添加注解@genetatoedValue(strategy=GenerationType.SEQUENCE , generator="teacherSEQ")表示采用sequence生成策略,采用生成器是teacherSEQ

    二、ID主要生成策略

    hibernate中id生成主要方式有:

    (1)native:根据不同的数据库采用不同的ID生成方式,例如:在SQL Server中采用identity; 在MySQL中采用auto_increment; 在ORACLE中就会采用sequence。

    (2)uuid:原理是使用128位的uuid算法产生主键,从而能够确保网络环境下的一致性。使用此生成策略时,实体类的主键是String类型的,映射成表中字段为varchar。适用所有数据库。

    (3)identity:这种策略在采用SQL Server时,相当于SQL Server的identity关键字。

    (4)sequence:在 Oracle中使用序列(sequence)。返回的标识符是long, short或者 int类型的。

    三、联合主键

    1、xml文件方式配置联合主键

    单独建一个类作为主键类,以Student类为例,假设student有两个主键id和name,那么可以建一个主键类StudentPK,主键类中包含两个属性即student的两个主键,而且要实现Serializable接口,覆盖equals和hashCode方法:

    package cn.orlion.hibernate.model;
    // 实现Serializable接口
    public class StudentPK implements java.io.Serializable{
    
        private int id;
        
        private String name;
    
        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;
        }
        // 覆盖equals方法
        public boolean equals(Object o){
            
            if (o instanceof StudentPK) {
                StudentPK pk = (StudentPK)o;
                return this.id == pk.getId() && this.name.equals(((StudentPK) o).getName());
            }
            
            return false;
        }
        // 覆盖hashCode方法
        public int hashCode(){
            return this.name.hashCode();
        }
    }

    这时Student应该去掉int和name属性然后加上StudentPK属性,如下:

    package cn.orlion.hibernate.model;
    
    public class Student {
        
        private StudentPK spk;
        
    //    private int id;
    //    
    //    private String name;
        
        public StudentPK getSpk() {
            return spk;
        }
    
        public void setSpk(StudentPK spk) {
            this.spk = spk;
        }
    
        private int age;
    
    //    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 int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }

    然后修改配置文件为:

    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
    <hibernate-mapping package="cn.orlion.hibernate.model">
        <class name="Student" table="student"><!-- 如果表名与类名相同可以不用写table属性 -->
      
         <!-- 在这里修改主键配置 --> <composite-id name="spk" class="cn.orlion.hibernate.model.StudentPK"> <key-property name="id"></key-property> <key-property name="name"></key-property> </composite-id> <property name="age"></property> </class> </hibernate-mapping>

    这样往数据库中插入一条数据就应该下new一个StudentPK,然后再new一个Student对象:

    StudentPK spk = new StudentPK();
            spk.setId(1);
            spk.setName("test1");
            Student t = new Student();
            t.setSpk(spk);
            // t.setName("test1");
            t.setAge(1);
            
            Session session = sf.openSession();
            
            session.beginTransaction();
            session.save(t);
            session.getTransaction().commit();
            
            session.close();

    2、注解方式配置联合主键

    共有三种方式:

    (1)将组件类注解为@Embeddable,并将组件的属性注解为@ID

    具体过程:

    创建组件类:TeacherPK(实现serializable接口,覆盖equals和hashCode方法)

    package cn.orlion.hibernate.model;
    
    import javax.persistence.Embeddable;
    
    @Embeddable
    public class TeacherPK implements java.io.Serializable{
    
        private int id;
        
        private String name;
    
        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;
        }
        // 覆盖equals方法
        public boolean equals(Object o){
                
            if (o instanceof StudentPK) {
                StudentPK pk = (StudentPK)o;
                return this.id == pk.getId() && this.name.equals(((StudentPK) o).getName());
            }
                
            return false;
        }
        // 覆盖hashCode方法
        public int hashCode(){
            return this.name.hashCode();
        }
    }

    然后Teacher类:(注释掉id和name属性,添加TeacherPK属性,并加上注解@Id)

    package cn.orlion.hibernate.model;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    
    @Entity
    public class Teacher{
        
        private TeacherPK tpk;
    
    //    private int id;
    //    
    //    private String name;
        @Id
        public TeacherPK getTpk() {
            return tpk;
        }
    
        public void setTpk(TeacherPK tpk) {
            this.tpk = tpk;
        }
    
        private String title;
    //    @Id
    //    @GeneratedValue(strategy = GenerationType.AUTO)
    //    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;
        }
    }

    保存teacher对象的时候:

    TeacherPK tpk = new TeacherPK();
            tpk.setId(1);
            tpk.setName("test1");
            Teacher t = new Teacher();
            t.setTpk(tpk);
    //        t.setName("test2");
            t.setTitle("title1");
            
            Session session = sf.openSession();
            
            session.beginTransaction();
            session.save(t);
            session.getTransaction().commit();
            
            session.close();

    可以看到建表:

    (2)在组件属性添加注解@EmbeddedId

    具体为:去掉TeacherPK类上的注解@Embeddable,然后在Teacher类中的getTpk()方法上的注解由@Id改为@EmbeddedId

    (3)将类注解为@IdClass,并将该实体中所有属于主键的属性都注解为@Id

    具体:

    修改Teacher类为:(注:id生成策略设为AUTO的时候会在TeacherPK的setId()方法上抛出一个异常IllegalArgumentException,"POST_INSERT_INDICATOR")

    package cn.orlion.hibernate.model;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.IdClass;
    
    @Entity
    @IdClass(TeacherPK.class)
    public class Teacher{
    
        private int id;
        
        private String name;
        
        private String title;
        @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;
        }
    }

    TeacherPK:

    package cn.orlion.hibernate.model;
    
    public class TeacherPK implements java.io.Serializable{
    
        private int id;
        
        private String name;
    
        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;
        }
        // 覆盖equals方法
        public boolean equals(Object o){
                
            if (o instanceof StudentPK) {
                StudentPK pk = (StudentPK)o;
                return this.id == pk.getId() && this.name.equals(((StudentPK) o).getName());
            }
                
            return false;
        }
        // 覆盖hashCode方法
        public int hashCode(){
            return this.name.hashCode();
        }
    }

    保存Teacher对象的时候:

    Teacher t = new Teacher();
            t.setName("test1");
            t.setId(1);
            t.setTitle("title1");
            
            Session session = sf.openSession();
            
            session.beginTransaction();
            session.save(t);
            session.getTransaction().commit();
            
            session.close();
  • 相关阅读:
    BZOJ1527 : [POI2005]Pun-point
    2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)
    2016-2017 ACM-ICPC Northwestern European Regional Programming Contest (NWERC 2016)
    NAIPC-2016
    BZOJ2498 : Xavier is Learning to Count
    ACM ICPC Vietnam National Second Round
    XVI Open Cup named after E.V. Pankratiev. GP of Ukraine
    XVI Open Cup named after E.V. Pankratiev. GP of Peterhof
    HDU5509 : Pattern String
    BZOJ4583 : 购物
  • 原文地址:https://www.cnblogs.com/orlion/p/5046702.html
Copyright © 2020-2023  润新知