一、Hibernate中常用的主键生成方式有如下几种:
1)identity: 用于自动生成主键方式,除了 Oracle 不支持,其他数据库一般都支持(较常用)
2)sequence: Oracle 中使用,用序列生成 ID 主键
3)native: 主键生成方式如果是 native,那就看配置文件 hibernate.cfg.xml 中方言<property name="dialect">是什么,如果方言是 Mysql,相当于 identity,如果方言是 Oracle,相当于 sequence
4)increment: 不常用
5)assigned: 不常用,手动生成 id
二、案例:5种主键生成方式演示
1、项目结构
2、新建Foo:用于测试的POJO
package com.xsyu.tts.po; public class Foo { private Integer id; private String value; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
- identity:使用最频繁,除了Oracle,其他数据库一般都有
3、数据库表t_foo:主键生成方式为自动生成主键
DROP TABLE IF EXISTS t_foo; CREATE TABLE t_foo ( t_id int(11) NOT NULL AUTO_INCREMENT, t_value varchar(50) NOT NULL, PRIMARY KEY (t_id) ) ENGINE=InnoDB;
4、新建Foo.hbm.xml:如果数据库支持自动生成主键方式,则可以使用identity, mysql数据库常用此方式。
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.tarena.tts.po"> <class name="Foo" table="t_foo"> <id name="id" type="java.lang.Integer" column="t_id"> <!-- 用来指明主键的生成方式 --> <generator class="identity"></generator> </id> <property name="value" type="java.lang.String" column="t_value" /> </class> </hibernate-mapping>
5、hibernate.cfg.xml中进行配置
<mapping resource="com/xsyu/tts/po/Foo.hbm.xml" />6、新建TestPersistence
public class TestPersistence { /** * 用于测试Hibernate主键生成方式 主键生成方式: identity sequence native */ @Test public void testGenerator() { Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); // identity // 不需要指定id Foo foo = new Foo(); foo.setValue("foo_value1"); session.save(foo); tx.commit(); session.close(); } }7、测试
8、查询数据库
- sequence:Oracle数据库常用
9、创建Oracle数据库表并创建生成ID的sequence
10、修改配置文件hibernate.cfg.xml :修改成Oracle数据库的
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- 数据库连接信息 --> <property name="connection.url"> jdbc:oracle:thin:@192.168.0.26:1521:tarena </property> <property name="connection.username">openlab</property> <property name="connection.password">open123</property> <property name="connection.driver_class"> oracle.jdbc.driver.OracleDriver </property> <!-- Hibernate配置信息 --> <!-- dialect方言,用亍配置生成针对哪个数据库的SQL语句 --> <property name="dialect"> <!--方言类,Hibernate提供的,用亍封装某种特定数据库的方言 --> org.hibernate.dialect.OracleDialect </property> <property name="hibernate.show_sql">true</property> <!-- 在配置文件中关联映射文件 --> <mapping resource="com/xsyu/tts/po/User.hbm.xml" /> <mapping resource="com/xsyu/tts/po/Foo.hbm.xml" /> </session-factory> </hibernate-configuration>11、修改映射文件Foo.hbm.xml :修改为sequence方式连接
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.tarena.tts.po"> <class name="Foo" table="t_foo"> <id name="id" type="java.lang.Integer" column="t_id"> <!-- 用来指明主键的生成方式 --> <generator class="sequence"> <param name="sequence">foo_seq</param> </generator> </id> <property name="value" type="java.lang.String" column="t_value" /> </class> </hibernate-mapping>12、测试
13、查看数据库
- native :native根据配置文件的方言选择是identity还是squence
<!-- 用来指明主键的生成方式 --> <generator class="native"> <param name="sequence">foo_seq</param> </generator>
如果是 mysql 数据库,
<param name="sequence">foo_seq</param>是不起作用的,但也不会出错;
如果是 oracle 数据库,
<param name="sequence">foo_seq</param>就会起作用,
所以一般我们会加上这句话,这样通用性更强。
- increment :不常用,如果主键生成方式为increment

新建数据库表t_foo时不需要写“auto_increment"
插入数据时,同样也不需要指定ID
查看控制台,Hibernate执行了2条SQL
increment生成主键的方式是先“select max(t_id) from t_foo",从t_foo中找到最大的id,之后将max(t_id)加1,这样就保证了主键唯一。但是这样也有风险,当并发访问时会有风险。不建议使用。
- assigned: 没有任何自动方式,需要用户自己指定,使用也较少
设置主键为assigned
必须手动设置ID