JDBC读取新插入Oracle数据库Sequence值的5种方法.docx

上传人:b****6 文档编号:3457558 上传时间:2022-11-23 格式:DOCX 页数:10 大小:16.94KB
下载 相关 举报
JDBC读取新插入Oracle数据库Sequence值的5种方法.docx_第1页
第1页 / 共10页
JDBC读取新插入Oracle数据库Sequence值的5种方法.docx_第2页
第2页 / 共10页
JDBC读取新插入Oracle数据库Sequence值的5种方法.docx_第3页
第3页 / 共10页
JDBC读取新插入Oracle数据库Sequence值的5种方法.docx_第4页
第4页 / 共10页
JDBC读取新插入Oracle数据库Sequence值的5种方法.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

JDBC读取新插入Oracle数据库Sequence值的5种方法.docx

《JDBC读取新插入Oracle数据库Sequence值的5种方法.docx》由会员分享,可在线阅读,更多相关《JDBC读取新插入Oracle数据库Sequence值的5种方法.docx(10页珍藏版)》请在冰豆网上搜索。

JDBC读取新插入Oracle数据库Sequence值的5种方法.docx

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

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

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

测试用的数据库脚本:

viewplaincopytoclipboardprint?

SQL>createtableT1

2(

3IDNUMBER

4);

Tablecreated

SQL>createsequenceSEQ_T1;

SequencecreatedSQL>createtableT1

2(

3IDNUMBER

4);

Tablecreated

SQL>createsequenceSEQ_T1;

Sequencecreatedviewplaincopytoclipboardprint?

//公共代码:

得到数据库连接

publicConnectiongetConnection()throwsException{

Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();

Connectionconn=DriverManager.getConnection("jdbc:

oracle:

thin:

@127.0.0.1:

1521:

dbname","username","password");

returnconn;

}

//方法一

//先用selectseq_t1.nextvalasidfromdual取到新的sequence值。

//然后将最新的值通过变量传递给插入的语句:

insertintot1(id)values(?

//最后返回开始取到的sequence值。

//这种方法的优点代码简单直观,使用的人也最多,缺点是需要两次sql交互,性能不佳。

publicintinsertDataReturnKeyByGetNextVal()throwsException{

Connectionconn=getConnection();

Stringvsql="selectseq_t1.nextvalasidfromdual";

PreparedStatementpstmt=(PreparedStatement)conn.prepareStatement(vsql);

ResultSetrs=pstmt.executeQuery();

rs.next();

intid=rs.getInt

(1);

rs.close();

pstmt.close();

vsql="insertintot1(id)values(?

)";

pstmt=(PreparedStatement)conn.prepareStatement(vsql);

pstmt.setInt(1,id);

pstmt.executeUpdate();

System.out.print("id:

"+id);

returnid;

}

//方法二

//先用insertintot1(id)values(seq_t1.nextval)插入数据。

//然后使用selectseq_t1.currvalasidfromdual返回刚才插入的记录生成的sequence值。

//注:

seq_t1.currval表示取出当前会话的最后生成的sequence值,由于是用会话隔离,只要保证两个SQL使用同一个Connection即可,对于采用连接池应用需要将两个SQL放在同一个事务内才可保证并发安全。

//另外如果会话没有生成过sequence值,使用seq_t1.currval语法会报错。

//这种方法的优点可以在插入记录后返回sequence,适合于数据插入业务逻辑不好改造的业务代码,缺点是需要两次sql交互,性能不佳,并且容易产生并发安全问题。

publicintinsertDataReturnKeyByGetCurrVal()throwsException{

Connectionconn=getConnection();

Stringvsql="insertintot1(id)values(seq_t1.nextval)";

PreparedStatementpstmt=(PreparedStatement)conn.prepareStatement(vsql);

pstmt.executeUpdate();

pstmt.close();

vsql="selectseq_t1.currvalasidfromdual";

pstmt=(PreparedStatement)conn.prepareStatement(vsql);

ResultSetrs=pstmt.executeQuery();

rs.next();

intid=rs.getInt

(1);

rs.close();

pstmt.close();

System.out.print("id:

"+id);

returnid;

}

//方法三

//采用pl/sql的returninginto语法,可以用CallableStatement对象设置registerOutParameter取得输出变量的值。

//这种方法的优点是只要一次sql交互,性能较好,缺点是需要采用pl/sql语法,代码不直观,使用较少。

publicintinsertDataReturnKeyByPlsql()throwsException{

Connectionconn=getConnection();

Stringvsql="begininsertintot1(id)values(seq_t1.nextval)returningidinto:

1;end;";

CallableStatementcstmt=(CallableStatement)conn.prepareCall(vsql);

cstmt.registerOutParameter(1,Types.BIGINT);

cstmt.execute();

intid=cstmt.getInt

(1);

System.out.print("id:

"+id);

cstmt.close();

returnid;

}

//方法四

//采用PreparedStatement的getGeneratedKeys方法

//conn.prepareStatement的第二个参数可以设置GeneratedKeys的字段名列表,变量类型是一个字符串数组

//注:

对Oracle数据库这里不能像其它数据库那样用prepareStatement(vsql,Statement.RETURN_GENERATED_KEYS)方法,这种语法是用来取自增类型的数据。

//Oracle没有自增类型,全部采用的是sequence实现,如果传Statement.RETURN_GENERATED_KEYS则返回的是新插入记录的ROWID,并不是我们相要的sequence值。

//这种方法的优点是性能良好,只要一次sql交互,实际上内部也是将sql转换成oracle的returninginto的语法,缺点是只有Oracle10g才支持,使用较少。

publicintinsertDataReturnKeyByGeneratedKeys()throwsException{

Connectionconn=getConnection();

Stringvsql="insertintot1(id)values(seq_t1.nextval)";

PreparedStatementpstmt=(PreparedStatement)conn.prepareStatement(vsql,newString[]{"ID"});

pstmt.executeUpdate();

ResultSetrs=pstmt.getGeneratedKeys();

rs.next();

intid=rs.getInt

(1);

rs.close();

pstmt.close();

System.out.print("id:

"+id);

returnid;

}

//方法五

//和方法三类似,采用oracle特有的returninginto语法,设置输出参数,但是不同的地方是采用OraclePreparedStatement对象,因为jdbc规范里标准的PreparedStatement对象是不能设置输出类型参数。

//最后用getReturnResultSet取到新插入的sequence值,

//这种方法的优点是性能最好,因为只要一次sql交互,oracle9i也支持,缺点是只能使用Oraclejdbc特有的OraclePreparedStatement对象。

publicintinsertDataReturnKeyByReturnInto()throwsException{

Connectionconn=getConnection();

Stringvsql="insertintot1(id)values(seq_t1.nextval)returningidinto:

1";

OraclePreparedStatementpstmt=(OraclePreparedStatement)conn.prepareStatement(vsql);

pstmt.registerReturnParameter(1,Types.BIGINT);

pstmt.executeUpdate();

ResultSetrs=pstmt.getReturnResultSet();

rs.next();

intid=rs.getInt

(1);

rs.close();

pstmt.close();

System.out.print("id:

"+id);

returnid;

}//公共代码:

得到数据库连接

publicConnectiongetConnection()throwsException{

Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();

Connectionconn=DriverManager.getConnection("jdbc:

oracle:

thin:

@127.0.0.1:

1521:

dbname","username","password");

returnconn;

}//方法一

//先用selectseq_t1.nextvalasidfromdual取到新的sequence值。

//然后将最新的值通过变量传递给插入的语句:

insertintot1(id)values(?

//最后返回开始取到的sequence值。

//这种方法的优点代码简单直观,使用的人也最多,缺点是需要两次sql交互,性能不佳。

publicintinsertDataReturnKeyByGetNextVal()throwsException{

Connectionconn=getConnection();

Stringvsql="selectseq_t1.nextvalasidfromdual";

PreparedStatementpstmt=(PreparedStatement)conn.prepareStatement(vsql);

ResultSetrs=pstmt.executeQuery();

rs.next();

intid=rs.getInt

(1);

rs.close();

pstmt.close();

vsql="insertintot1(id)values(?

)";

pstmt=(PreparedStatement)conn.prepareStatement(vsql);

pstmt.setInt(1,id);

pstmt.executeUpdate();

System.out.print("id:

"+id);

returnid;

}//方法二

//先用insertintot1(id)values(seq_t1.nextval)插入数据。

//然后使用selectseq_t1.currvalasidfromdual返回刚才插入的记录生成的sequence值。

//注:

seq_t1.currval表示取出当前会话的最后生成的sequence值,由于是用会话隔离,只要保证两个SQL使用同一个Connection即可,对于采用连接池应用需要将两个SQL放在同一个事务内才可保证并发安全。

//另外如果会话没有生成过sequence值,使用seq_t1.currval语法会报错。

//这种方法的优点可以在插入记录后返回sequence,适合于数据插入业务逻辑不好改造的业务代码,缺点是需要两次sql交互,性能不佳,并且容易产生并发安全问题。

publicintinsertDataReturnKeyByGetCurrVal()throwsException{

Connectionconn=getConnection();

Stringvsql="insertintot1(id)values(seq_t1.nextval)";

PreparedStatementpstmt=(PreparedStatement)conn.prepareStatement(vsql);

pstmt.executeUpdate();

pstmt.close();

vsql="selectseq_t1.currvalasidfromdual";

pstmt=(PreparedStatement)conn.prepareStatement(vsql);

ResultSetrs=pstmt.executeQuery();

rs.next();

intid=rs.getInt

(1);

rs.close();

pstmt.close();

System.out.print("id:

"+id);

returnid;

}//方法三

//采用pl/sql的returninginto语法,可以用CallableStatement对象设置registerOutParameter取得输出变量的值。

//这种方法的优点是只要一次sql交互,性能较好,缺点是需要采用pl/sql语法,代码不直观,使用较少。

publicintinsertDataReturnKeyByPlsql()throwsException{

Connectionconn=getConnection();

Stringvsql="begininsertintot1(id)values(seq_t1.nextval)returningidinto:

1;end;";

CallableStatementcstmt=(CallableStatement)conn.prepareCall(vsql);

cstmt.registerOutParameter(1,Types.BIGINT);

cstmt.execute();

intid=cstmt.getInt

(1);

System.out.print("id:

"+id);

cstmt.close();

returnid;

}//方法四

//采用PreparedStatement的getGeneratedKeys方法

//conn.prepareStatement的第二个参数可以设置GeneratedKeys的字段名列表,变量类型是一个字符串数组

//注:

对Oracle数据库这里不能像其它数据库那样用prepareStatement(vsql,Statement.RETURN_GENERATED_KEYS)方法,这种语法是用来取自增类型的数据。

//Oracle没有自增类型,全部采用的是sequence实现,如果传Statement.RETURN_GENERATED_KEYS则返回的是新插入记录的ROWID,并不是我们相要的sequence值。

//这种方法的优点是性能良好,只要一次sql交互,实际上内部也是将sql转换成oracle的returninginto的语法,缺点是只有Oracle10g才支持,使用较少。

publicintinsertDataReturnKeyByGeneratedKeys()throwsException{

Connectionconn=getConnection();

Stringvsql="insertintot1(id)values(seq_t1.nextval)";

PreparedStatementpstmt=(PreparedStatement)conn.prepareStatement(vsql,newString[]{"ID"});

pstmt.executeUpdate();

ResultSetrs=pstmt.getGeneratedKeys();

rs.next();

intid=rs.getInt

(1);

rs.close();

pstmt.close();

System.out.print("id:

"+id);

returnid;

}//方法五

//和方法三类似,采用oracle特有的returninginto语法,设置输出参数,但是不同的地方是采用OraclePreparedStatement对象,因为jdbc规范里标准的PreparedStatement对象是不能设置输出类型参数。

//最后用getReturnResultSet取到新插入的sequence值,

//这种方法的优点是性能最好,因为只要一次sql交互,oracle9i也支持,缺点是只能使用Oraclejdbc特有的OraclePreparedStatement对象。

publicintinsertDataReturnKeyByReturnInto()throwsException{

Connectionconn=getConnection();

Stringvsql="insertintot1(id)values(seq_t1.nextval)returningidinto:

1";

OraclePreparedStatementpstmt=(OraclePreparedStatement)conn.prepareStatement(vsql);

pstmt.registerReturnParameter(1,Types.BIGINT);

pstmt.executeUpdate();

ResultSetrs=pstmt.getReturnResultSet();

rs.next();

intid=rs.getInt

(1);

rs.close();

pstmt.close();

System.out.print("id:

"+id);

returnid;

}

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

方法

简介

优点

缺点

 

方法一

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

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

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

 

方法二

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

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

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

 

方法三

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

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

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

 

方法四

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

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

只有Oracle10g才支持,使用较少

 

方法五

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

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

只能使用Oraclejdbc特有的OraclePreparedStatement对象

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1