zoukankan      html  css  js  c++  java
  • 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();
  • 相关阅读:
    【BZOJ1067】【SCOI2007】降雨量(线段树)
    【BZOJ3489】A simple rmq problem(树套树)
    【BZOJ1146】【CTSC2008】网络管理
    【BZOJ3236】【Ahoi2013】作业
    计算几何的一些板
    【BZOJ3173】【Tjoi2013】最长上升子序列(树状数组)
    解决phpmyadmin导入长脚本超时
    make报错make: *** [sapi/cli/php] Error 1
    wampserver配置redis在phpinfo()里面找不到
    阿里云服务器安装Apache环境外网不能访问
  • 原文地址:https://www.cnblogs.com/orlion/p/5046702.html
Copyright © 2011-2022 走看看