Oracle的sequence实现非常灵活,所以也带来一些易用性问题,如何取到新插入记录生成的sequence值与其它数据库有较大差别,本文详国介绍了5种实现读取新插入记录sequence值的方法。

测试用的数据库脚本:

SQL> create table T12  (3    ID NUMBER4  );Table created
SQL> create sequence SEQ_T1;Sequence created

//公共代码:得到数据库连接
public Connection getConnection() throws Exception{Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:dbname", "username", "password");return conn;
}//方法一
//先用select seq_t1.nextval as id from dual 取到新的sequence值。
//然后将最新的值通过变量传递给插入的语句:insert into t1(id) values(?)
//最后返回开始取到的sequence值。
//这种方法的优点代码简单直观,使用的人也最多,缺点是需要两次sql交互,性能不佳。
public int insertDataReturnKeyByGetNextVal() throws Exception {Connection conn = getConnection();String vsql = "select seq_t1.nextval as id from dual";PreparedStatement pstmt =(PreparedStatement)conn.prepareStatement(vsql);ResultSet rs=pstmt.executeQuery();rs.next();int id=rs.getInt(1);rs.close();pstmt.close();vsql="insert into t1(id) values(?)";pstmt =(PreparedStatement)conn.prepareStatement(vsql);pstmt.setInt(1, id);pstmt.executeUpdate();System.out.print("id:"+id);return id;
}//方法二
//先用insert into t1(id) values(seq_t1.nextval)插入数据。
//然后使用select seq_t1.currval as id from dual返回刚才插入的记录生成的sequence值。
//注:seq_t1.currval表示取出当前会话的最后生成的sequence值,由于是用会话隔离,只要保证两个SQL使用同一个Connection即可,对于采用连接池应用需要将两个SQL放在同一个事务内才可保证并发安全。
//另外如果会话没有生成过sequence值,使用seq_t1.currval语法会报错。
//这种方法的优点可以在插入记录后返回sequence,适合于数据插入业务逻辑不好改造的业务代码,缺点是需要两次sql交互,性能不佳,并且容易产生并发安全问题。
public int insertDataReturnKeyByGetCurrVal() throws Exception {Connection conn = getConnection();String vsql = "insert into t1(id) values(seq_t1.nextval)";PreparedStatement pstmt =(PreparedStatement)conn.prepareStatement(vsql);pstmt.executeUpdate();pstmt.close();vsql="select seq_t1.currval as id from dual";pstmt =(PreparedStatement)conn.prepareStatement(vsql);ResultSet rs=pstmt.executeQuery();rs.next();int id=rs.getInt(1);rs.close();pstmt.close();System.out.print("id:"+id);return id;
}//方法三
//采用pl/sql的returning into语法,可以用CallableStatement对象设置registerOutParameter取得输出变量的值。
//这种方法的优点是只要一次sql交互,性能较好,缺点是需要采用pl/sql语法,代码不直观,使用较少。
public int insertDataReturnKeyByPlsql() throws Exception {Connection conn = getConnection();String vsql = "begin insert into t1(id) values(seq_t1.nextval) returning id into :1;end;";CallableStatement cstmt =(CallableStatement)conn.prepareCall ( vsql); cstmt.registerOutParameter(1, Types.BIGINT);cstmt.execute();int id=cstmt.getInt(1);System.out.print("id:"+id);cstmt.close();return id;
}//方法四
//采用PreparedStatement的getGeneratedKeys方法
//conn.prepareStatement的第二个参数可以设置GeneratedKeys的字段名列表,变量类型是一个字符串数组
//注:对Oracle数据库这里不能像其它数据库那样用prepareStatement(vsql,Statement.RETURN_GENERATED_KEYS)方法,这种语法是用来取自增类型的数据。
//Oracle没有自增类型,全部采用的是sequence实现,如果传Statement.RETURN_GENERATED_KEYS则返回的是新插入记录的ROWID,并不是我们相要的sequence值。
//这种方法的优点是性能良好,只要一次sql交互,实际上内部也是将sql转换成oracle的returning into的语法,缺点是只有Oracle10g才支持,使用较少。
public int insertDataReturnKeyByGeneratedKeys() throws Exception {Connection conn = getConnection();String vsql = "insert into t1(id) values(seq_t1.nextval)";PreparedStatement pstmt =(PreparedStatement)conn.prepareStatement(vsql,new String[]{"ID"});pstmt.executeUpdate();ResultSet rs=pstmt.getGeneratedKeys();rs.next();int id=rs.getInt(1);rs.close();pstmt.close();System.out.print("id:"+id);return id;
}//方法五
//和方法三类似,采用oracle特有的returning into语法,设置输出参数,但是不同的地方是采用OraclePreparedStatement对象,因为jdbc规范里标准的PreparedStatement对象是不能设置输出类型参数。
//最后用getReturnResultSet取到新插入的sequence值,
//这种方法的优点是性能最好,因为只要一次sql交互,oracle9i也支持,缺点是只能使用Oracle jdbc特有的OraclePreparedStatement对象。
public int insertDataReturnKeyByReturnInto() throws Exception {Connection conn = getConnection();String vsql = "insert into t1(id) values(seq_t1.nextval) returning id into :1";OraclePreparedStatement pstmt =(OraclePreparedStatement)conn.prepareStatement(vsql);pstmt.registerReturnParameter(1, Types.BIGINT);pstmt.executeUpdate();ResultSet rs=pstmt.getReturnResultSet();rs.next();int id=rs.getInt(1);rs.close();pstmt.close();System.out.print("id:"+id);return id;
}

以上5种方法都可以实现功能,以下是5种方法的优缺点汇总,个人推荐性能要求一般的业务采用第一种方法,性能要求非常高业务采用第五种方法。

方法

简介

优点

缺点

方法一

先用seq.nextval取出值,然后用转入变量的方式插入

代码简单直观,使用的人也最多

需要两次sql交互,性能不佳

方法二

先用seq.nextval直接插入记录,再用seq.currval取出新插入的值

可以在插入记录后返回sequence,适合于数据插入业务逻辑不好改造的业务代码

需要两次sql交互,性能不佳,并且容易产生并发安全问题

方法三

用pl/sql块的returning into语法,用CallableStatement对象设置输出参数取到新插入的值

只要一次sql交互,性能较好

需要采用pl/sql语法,代码不直观,使用较少

方法四

设置PreparedStatement需要返回新值的字段名,然后用getGeneratedKeys取得新插入的值

性能良好,只要一次sql交互

只有Oracle10g才支持,使用较少

方法五

returning into语法,用OraclePreparedStatement对象设置输出参数,再用getReturnResultSet取得新增入的值

性能最好,因为只要一次sql交互,oracle9i也支持

只能使用Oracle jdbc特有的OraclePreparedStatement对象

转载:http://blog.csdn.net/yzsind/article/details/6918506

转载于:https://www.cnblogs.com/myjoan/p/4212688.html

JDBC读取新插入Oracle数据库Sequence值的5种方法相关推荐

  1. java代码读取dbsequence的值_JDBC读取新插入Oracle数据库Sequence值的5种方法

    //公共代码:得到数据库连接 public Connection getConnection() throwsException{ Class.forName("oracle.jdbc.dr ...

  2. oracle如何对数据库进行备份,对Oracle数据库进行备份的两种方法详解

    首页 > 演讲稿 > 自我介绍演讲稿 > 对Oracle数据库进行备份的两种方法详解 对Oracle数据库进行备份的两种方法详解 时间:2019-05-05   来源:自我介绍演讲稿 ...

  3. Oracle补历史数据存储过程,Oracle数据库数据丢失恢复的几种方法总结

    根据oracle数据库的特点和提供的工具,主要方法有以下几种方法: 利用逻辑备份使用import工具丢失数据的表 利用物理备份来通过还原数据文件并进行不完全恢复 利用dbms_logmnr包从redo ...

  4. oracle数据表丢失数据库,Oracle数据库数据丢失恢复的几种方法总结

    根据oracle数据库的特点和提供的工具,主要方法有以下几种方法: 利用逻辑备份使用import工具丢失数据的表 利用物理备份来通过还原数据文件并进行不完全恢复 利用dbms_logmnr包从redo ...

  5. oracle数据丢失怎么办,Oracle数据库数据丢失?这几种方法教你来恢复~

    无论是开发.测试还是运维过程中,大家都可能会因为误操作.连错数据库.用错用户.语句条件有误等原因,导致错误删除.错误更新等问题.当你恨不得剁掉按回车的那个指头.捶胸顿足.或者吓得腿软时,肯定希望有办法 ...

  6. Oracle数据库数据丢失恢复的几种方法总结

    根据oracle数据库的特点和提供的工具,主要方法有以下几种方法: 利用逻辑备份使用import工具丢失数据的表 利用物理备份来通过还原数据文件并进行不完全恢复 利用dbms_logmnr包从redo ...

  7. Oracle数据库删除表的几种方法

    删除表(记录和结构)的语名:delete -- truncate -- drop delete (删除数据表里记录的语句) delete from 表名 where 条件;     注意:删除记录并不 ...

  8. mysql 读取oracle_RobotFramework读取mysql和oracle数据库

    一.robotframework连接mysql数据库 1.安装databaselibrary.pymysql 通过cmd命令执行:pip install robotframework-database ...

  9. jdbc链接mysql按照id查询_使用jdbc连接并操作Oracle数据库(增删改查IDUS)

    使用jdbc连接并操作Oracle数据库(增删改查IDUS) [oracle@zaibei-db ~]$ sqlplus /nolog SQL*Plus: Release 11.2.0.4.0 Pro ...

最新文章

  1. 机器学习入门(17)— 输入 4 维数据、基于 im2col 展开来实现卷积层
  2. mysql用户控制登录_MySql用户权限控制_MySQL
  3. linux chattr命令
  4. FTP与TFTP的区别
  5. springcloud上传文件_Spring Cloud实战:服务链路追踪Spring Cloud Sleuth
  6. 最轻快的人脸检测yoloface
  7. linux虚拟机ip地址更改
  8. 一个游戏美术写给策划的快速入门
  9. 2021中国企业招聘科技趋势报告
  10. 如何避免单元测试陷阱?
  11. 17.3.13--pycharm2和3的常识问题
  12. python dash html.table_阅读 Python dash 代码的时候有个问题, 那个包的调用有问题?
  13. C++:封装 继承 多态
  14. 2021-2027全球与中国电动汽车PTC加热器市场现状及未来发展趋势
  15. php判断汉子首字母的函数,php获取汉字首字母的函数
  16. pta 计算机通信(并查集)
  17. Qt 显示图片 放大 缩小 移动
  18. 【Windows 11】系统安装修改版 Subsystem for Android 安卓子系统,并用 Magisk Root
  19. [ioredis] Unhandled error event: Error: connect ETIMEDOUT报错的解决办法
  20. 天津达内:大数据自学可以学会吗

热门文章

  1. jmeter基本测试步骤
  2. Eclipse+Maven+SpringMVC+Mybatis+MySql搭建总结
  3. bzoj3270 博物馆
  4. 借助 Debugging Tools 分析蓝屏故障原因
  5. 基础环境搭建--原始mavenWeb项目
  6. JavaScript text highlighting JQuery plugin
  7. 浅谈悲催的“期末考试”
  8. $(window).load(function() {})和$(document).ready(function(){})的区别
  9. webpack 优化笔记
  10. freeBSD挂载光驱