Hibernate学习篇03——Oracle sequence

来源:互联网 发布:prim算法有什么用? 编辑:程序博客网 时间:2024/05/16 00:46

表结构

drop table user2;create table USER2(  ID       number(6),  USERNAME VARCHAR2(32),  PASSWORD VARCHAR2(32),  NAME     VARCHAR2(32));create sequence SEQ_USER2_ID start with 1increment by 1minvalue 1maxvalue 999999nocyclenocache;/*create or replace trigger TR_USER2_BEFORE_INSERT before insert on user2for each rowbeginselect SEQ_USER2_ID.nextval into :new.id from dual;end;*/commit;

User.hbm.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="com.masteringhibernate.a03oid"><class name="User" lazy="true" table="USER2"><!--<id name="id" type="long"><generator class="increment" /></id> --><id name="id" type="long"><generator class="sequence"><param name="sequence">SEQ_USER2_ID</param></generator></id><property name="username" /><property name="password" /><property name="name" /></class></hibernate-mapping>
User.java

package com.masteringhibernate.a03oid;public class User {private long id;private String username;private String password;private String name;public long getId() {return id;}public void setId(long id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getName() {return name;}public void setName(String name) {this.name = name;}}
Test.java

package com.masteringhibernate.a03oid;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;public class Test {private static SessionFactory sessionFactory;public static void main(String[] args) {Configuration configuration = new Configuration().configure("com/masteringhibernate/a03oid/hibernate.cfg.xml");SessionFactory sessionFactory = configuration.buildSessionFactory();Session session = sessionFactory.openSession();Transaction tx = session.beginTransaction();User user1 = new User();user1.setUsername("zhangsan");user1.setPassword("111111");user1.setName("zs");User user2 = new User();user2.setUsername("lisi");user2.setPassword("222222");user2.setName("ls");session.save(user1);session.save(user2);System.out.println(user1.getId());System.out.println(user2.getId());tx.commit();session.close();}}
日志:

Hibernate: select SEQ_USER2_ID.nextval from dual
Hibernate: select SEQ_USER2_ID.nextval from dual
1
2
Hibernate: insert into USER2 (username, password, name, id) values (?, ?, ?, ?)
Hibernate: insert into USER2 (username, password, name, id) values (?, ?, ?, ?)

再看下数据中的数据。


从以上我们可以看出,hibernate给user.id赋值的时候是从序列中找到nextval。

我们再想一下,如果oracle设置了序列,会是什么结果呢?也就是把上面表结构里面的注释给放开,日志如下

Hibernate: select SEQ_USER2_ID.nextval from dual
Hibernate: select SEQ_USER2_ID.nextval from dual
1
2
Hibernate: insert into USER2 (username, password, name, id) values (?, ?, ?, ?)
Hibernate: insert into USER2 (username, password, name, id) values (?, ?, ?, ?)

我们发现没有日志是没有区别的,但是再查看数据库成下面这样了。


为什么呢?其实很好理解,hibernate在清理缓存的时候才会真正的与数据库进行交互做一些增删改的操作。hibernate在save的时候需要为user生成一个oid,我们在hibernate配置文件中指定了使用序列来生成oid,所以向数据库查询了两次nextval。所以当save完成的时候,user1.id和user2.id分别为1,2.数据库中此时的currval为2,nextval为3.

那么在清理缓存的时候会发送两条这样的语句

insert into USER2 (username, password, name, id) values ('zhangsan', '111111', 'zs', 1)

insert into USER2 (username, password, name, id) values ('lisi'    , '222222', 'ls', 2)

但是oracle在插入的时候触发了触发器,所以在触发器中又查询了一次nextval来重新给id赋值。所以最后的值为3,4.




0 0
原创粉丝点击