前一次做个系统用的oracle数据库,使用hibernate生成主键的策略是SEQUENCE,当时觉得很累,因为不知道怎么的,oracle+sequence+trigger怎么也取不到新增数据时的主键值。
这次就把重点放这里了,同时还有两个新的问题,
1。到底哪种hibernate生成主键的策略,性能优一点;
2。主键生成策略最好是能跨数据库的。
大家都说性能,oracle都是用的sequence,所以主键还是想用这个方式生成。
接着就是返回新增数据的主键
native
根据底层数据库的能力选择 identity、sequence 或者 hilo 中的一个;
也就是说,主键生成,由hibernate选择。
对于内部支持标识字段的数据库(DB2、MySQL、Sybase 和 MS SQL),你可以使用 identity 关
键字生成。对于内部支持序列的数据库(DB2、Oracle、PostgreSQL、Interbase、McKoi 和 SAP
DB),你可以使用 sequence 风格的关键字生成。这两种方式对于插入一个新的对象都需要两次
SQL 查询。
查询了一下更多的网上资料,不知道在哪里看到了,这种生成主键的策略,如果是mysql,他会选择auto_increment方式生成主键;如果是oracle,他会选择sequence方式;只是在使用oracle数据库时,需要创建一个hibernate_sequence,这是hibernate保留的,不建会报错(测试过)。
如下是完全的代码:
Model:
package com.gwtjs.model;
/**
* @hibernate.class table="t_user"
*/
public class User {
/**
* @hibernate.id generator-class="native" length="32"
*/
private int id;
/**
* @hibernate.property type="string" length="32" unique="true" not-null="true"
*/
private String userName;
/**
* @hibernate.property type="string" length="32" not-null="true"
*/
private String userPwd;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
}
hibernate mapping
oracle表创建脚本:
-- Create table
create table T_USER
(
id NUMBER(10) not null,
username VARCHAR2(32) not null,
userpwd VARCHAR2(32) not null
)
tablespace FOUNDDB
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
-- Create/Recreate primary, unique and foreign key constraints
alter table T_USER
add primary key (ID)
using index
tablespace FOUNDDB
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
alter table T_USER
add unique (USERNAME)
using index
tablespace FOUNDDB
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
hibernate_sequence创建脚本
-- create user table sequence
create sequence t_user_seq
minvalue 1
maxvalue 9999999999
start with 1
increment by 1
nocache;
-- 公用的主键标识seq
CREATE SEQUENCE HIBERNATE_SEQUENCE MINVALUE 1 MAXVALUE 999999999999999999999999 INCREMENT BY 1 NOCYCLE;
-- 插入用户的触发器
create or replace trigger tri_insert_user
before insert on t_user
for each row
begin
select t_user_seq.nextval into :new.id from dual;
end;
Hibernate DAO
public class UserManagerImpl extends AbstractSearch implements UserManager {
public void saveOrUpdate(User u){
getHibernateTemplate().saveOrUpdate(u);
}
public void delete(int id){
getHibernateTemplate().delete(getUser(id));
}
public User getUser(int id){
return (User)getHibernateTemplate().get(User.class,id);
}
}
DAO TEST Base Class
public class DaoTestBase extends AbstractTransactionalDataSourceSpringContextTests {
protected String[] getConfigLocations() {
this.setAutowireMode(AUTOWIRE_BY_NAME);
this.setDefaultRollback(false);
return new String[]{
"classpath:spring-config.xml",
"classpath:/config/spring/applicationContext-dao.xml"
};
}
public void testConfig(){
assertNotNull("spring-mock context has bean init ",this.applicationContext);
}
}
User DAO Test
public class UserManagerTest extends DaoTestBase {
private UserManager userManager;
public void testSave(){
User u = new User();
u.setUserName("admin888");
u.setUserPwd("654123");
userManager.saveOrUpdate(u);
logger.info(u.getId());
System.out.println("高度啊: "+u.getId());
userManager.delete(u.getId());
}
public void setUserManager(UserManager userManager){
this.userManager = userManager;
}
}
spring bean
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
完美的测试成功