Hibernate系列之Id生成策略
来源:互联网 发布:计划表软件 编辑:程序博客网 时间:2024/04/29 10:52
一、概述
hibernate中使用两种方式实现主键生成策略,分别是XML生成id和注解方式(@GeneratedValue),下面逐一进行总结。
二、XML配置方法
这种方式是在XX.hbm.xml文件中对generator进行配置,eg:
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.test.demo"> <class name="Student"> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> <property name="age"></property> </class></hibernate-mapping>
常用的生成策略有以下几种:
identity:对DB2,Mysql,MS SQL Server等的内置标识字段提供支持,返回的标识符是long,short或者int类型
native:可以是identity类型、sequence类型或者hilo类型,取决于不同的底层数据库
sequence:在Oracle,SAP DB中使用序列(sequence)
uuid:使用一种128位的UUID算法产生的字符类型标识,像IP地址一样全网唯一
三、注解方式生成ID:@GeneratorValue
标准的annotation方式的主键生成策略如下:
- AUTO:可以是identity类型或者是sequence类型或者是table类型,取决于底层的数据库
- TABLE:使用表保存id值,即会为应用的表创建一张专门保存id的表
- IDENTITY:identity column
- SEQUENCE:sequence
四、联合主键生成策略
有的时候我们需要将一个实体的2个或多个字段联合起来作为主键,就是说,不能有2个或多个对象的这几个字段值都相同的情况发生。现在我们要将Person字段的id和name字段联合作为主键:
@Entitypublic class Person{ //现在id和name组成联合主键 private int id; private String name; private int age; ...}
- 首先将联合主键的属性提取出来,重新编写一个pojo类(原pojo类中的id,name要删除 并新加入属性“PersonPK”)
- 新建pojo类必须实现 java.io.Serializable 序列化接口
- 新pojo类要重写equals和hashCode方法
public class PersonPK implements Serializable{ private String name; private int id; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public int hashCode() { return this.name.hashCode(); } @Override public boolean equals(Object obj) { if(obj instanceof PersonPK) { PersonPK pk = (PersonPK)obj; if(this.id == pk.getId() && this.name.equals(pk.getName())) { return true; } } return false; }}
联合主键生成策略XML配置方法:
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.test.demo"> <class name="Person"> <composite-id name="personPK" class="com.test.demo.PersonPK"> <key-property name="id"></key-property> <key-property name="name"></key-property> </composite-id> <property name="age" /> </class></hibernate-mapping>
联合主键ID生成策略的Annotation版本,共有三种方式,前三步骤一样,另外:
方法1、在新类PersonPK前写@Embeddable,在原Person类的新属性PersonPK的get方法前写@id
@Embeddablepublic class PersonPK implements Serializable{ private static final long serialVersionUID = -7068850328521576106L; private String name; private int id; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public int hashCode() { return this.name.hashCode(); } @Override public boolean equals(Object obj) { if(obj instanceof PersonPK) { PersonPK pk = (PersonPK)obj; if(this.id == pk.getId() && this.name.equals(pk.getName())) { return true; } } return false; }}
Person类中:
@Entitypublic class Person{ private PersonPK personPK; private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Id public PersonPK getPersonPK() { return personPK; } public void setPersonPK(PersonPK personPK) { this.personPK = personPK; }}
方法2、新类无需添加注解,只需在原类Person新属性PersonPK的get方法前写@EmbeddID即可
@Entitypublic class Person{ private PersonPK personPK; private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } @EmbeddedId public PersonPK getPersonPK() { return personPK; } public void setPersonPK(PersonPK personPK) { this.personPK = personPK; }}
方法3、新pojo类无需加注解,原pojo类的id,name属性保留不变,也无需新增“TercherPK”属性。 只在id,name的get方法前都加@Id,并在原pojo类前加@IdClass(PersonPK.class):
原类Person:
@Entity@IdClass(PersonPK.class)public class Person{ private int age; private String name; private int id; @Id public String getName() { return name; } public void setName(String name) { this.name = name; } @Id public int getId() { return id; } public void setId(int id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }}
运行测试程序(针对上述三种方法,测试用例需要稍作修改,这里不在赘述):
public class PersonTest{ private static SessionFactory sf=null; @BeforeClass public static void beforeClass() { sf=new AnnotationConfiguration().configure().buildSessionFactory(); } @Test public void test() { PersonPK personPK=new PersonPK(); personPK.setId(1); personPK.setName("xujian"); Person p=new Person(); p.setAge(23); p.setPersonPK(personPK); Session session=sf.openSession(); session.beginTransaction(); session.save(p); //提交事物 session.getTransaction().commit(); session.close(); sf.close(); } @AfterClass public static void afterClass() { sf.close(); }}
可以看到:
生成的Person表中id和name组成联合主键
- Hibernate系列之Id生成策略
- hibernate之ID生成策略
- Hibernate之ID主键生成策略
- Hibernate进阶之ID主键生成策略
- Hibernate ID 生成策略
- hibernate id 生成策略
- hibernate ID生成策略
- Hibernate ID 生成策略
- Hibernate id生成策略
- hibernate---ID生成策略
- hibernate id生成策略
- hibernate id 生成策略
- hibernate--ID生成策略
- Hibernate 03 - Hibernate 之 延时加载 以及 ID 生成策略
- Hibernate的ID生成策略
- hibernate的ID生成策略
- Hibernate + Oracle id 生成策略
- hibernate id设置生成策略
- java的Split函数如何区分多个空格
- JavaScript权威指南_170_第17章_事件处理_17.4-文档加载事件
- DynamoRIO(一)
- 分享软件测试就业前景(结合他人观点)
- 【Python 笔记】selenium 简介
- Hibernate系列之Id生成策略
- JavaScript权威指南_171_第17章_事件处理_17.5-鼠标事件
- [sicily]1342. 开心的金明
- libevent
- 使用VS2015编译FreeGLUT
- Linux中网络字节序和主机字节序
- 【转】linearLayout 和 relativeLayout的属性区别
- 支持向量机SVM(二)
- ubuntu14.04 修改键盘映射 CapsLock->Ctrl