当前位置: 首页 > news >正文

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();

 

转载于:https://www.cnblogs.com/orlion/p/5046702.html

相关文章:

  • 【iCore3 双核心板】例程十四:FATFS实验——文件操作
  • 配置Server.xml
  • 工作小记(五)----完工归来
  • jQuery API
  • MIT Introduction to Algorithms 学习笔记(四)
  • Java 自动装箱与拆箱(Autoboxing and unboxing)
  • Java多线程中wait, notify and notifyAll的使用
  • 用Android Studio构建及运行android app
  • ArchSummit北京2015精彩回顾
  • Ubuntu OS应用Runtime Enviroment
  • [转]如何判断js中的数据类型
  • 武汉Uber优步司机奖励政策(12月21日-12.27日)
  • Java基础学习总结(5)——多态
  • 【CURL】PHP的CURL开发项目最佳实践
  • WordPress 全方位优化指南(上)
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • 4. 路由到控制器 - Laravel从零开始教程
  • django开发-定时任务的使用
  • gitlab-ci配置详解(一)
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • Java方法详解
  • Object.assign方法不能实现深复制
  • SegmentFault 2015 Top Rank
  • SQL 难点解决:记录的引用
  • SQLServer之索引简介
  • 前端自动化解决方案
  • 嵌入式文件系统
  • 小程序button引导用户授权
  • 移动端解决方案学习记录
  • 用element的upload组件实现多图片上传和压缩
  • 正则与JS中的正则
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • #使用清华镜像源 安装/更新 指定版本tensorflow
  • #预处理和函数的对比以及条件编译
  • $(selector).each()和$.each()的区别
  • (C#)获取字符编码的类
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (Git) gitignore基础使用
  • (MATLAB)第五章-矩阵运算
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (十五)使用Nexus创建Maven私服
  • (实战篇)如何缓存数据
  • (四)库存超卖案例实战——优化redis分布式锁
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • (转载)CentOS查看系统信息|CentOS查看命令
  • .NET CF命令行调试器MDbg入门(三) 进程控制
  • .net对接阿里云CSB服务
  • .net反编译工具
  • .NET高级面试指南专题十一【 设计模式介绍,为什么要用设计模式】