`
txf2004
  • 浏览: 6869244 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JDBC之批处理、事务、存储过程

 
阅读更多

当需要向数据库发送一批SQL语句执行时,应避免向数据库一条条的发送执行,而应采用JDBC的批处理机制,以提升执行效率。;

实现批处理有两种方式,第一种方式:

Statement.addBatch(sql)list

执行批处理SQL语句

executeBatch()方法:执行批处理命令

clearBatch()方法:清除批处理命令

例:

Connectionconn=null;

Statementst=null;

ResultSetrs=null;

try{

conn=JDBCManager.getConnection();

Stringsql1="insertintouser(name,password,email,birthday)

values('kkk','123','abc@sina.com','1978-08-08')";

Stringsql2="updateusersetpassword='123456'whereid=3";

st=conn.createStatement();

st.addBatch(sql1);//SQL语句加入到批命令中

st.addBatch(sql2);//SQL语句加入到批命令中

st.executeBatch();

}finally{

JDBCManager.DBclose(con,st,rs);

}

采用Statement.addBatch(sql)方式实现批处理:

优点:可以向数据库发送多条不同的SQL语句。

缺点:

SQL语句没有预编译。

当向数据库发送多条语句相同,但仅参数不同的SQL语句时,需重复写上很多条SQL语句。例如:

Insertintouser(name,password)values(aa,111);

Insertintouser(name,password)values(bb,222);

Insertintouser(name,password)values(cc,333);

Insertintouser(name,password)values(dd,444);

2、实现批处理的第二种方式:

PreparedStatement.addBatch();

例:

conn=JDBCManager.getConnection();//获取工具;

Stringsql="insertintouser(name,password,email,birthday)values(?,?,?,?)";

st=conn.prepareStatement(sql);//预处理sql语句;

for(inti=0;i<50000;i++){

st.setString(1,"aaa"+i);

st.setString(2,"123"+i);

st.setString(3,"aaa"+i+"@sina.com");

st.setDate(4,newDate(1980,10,10));

st.addBatch();//将一组参数添加到此PreparedStatement对象的批处理命令中。

if(i%1000==0){

st.executeBatch();

st.clearBatch();清空此Statement对象的当前SQL命令列表。

}

}

st.executeBatch();将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。返回数组的int元素的排序对应于批中的命令,批中的命令根据被添加到批中的顺序排序

采用PreparedStatement.addBatch()实现批处理

优点:发送的是预编译后的SQL语句,执行效率高。

缺点:只能应用在SQL语句相同,但参数不同的批处理中。因此此种形式的批处理经常用于在同一个表中批量插入数据,或批量更新表的数据。

获得数据库自动生成的主键:

Connectioncon=null;

PreparedStatementps=null;

con=JDBCManager.getConnection();

Stringsql="insertintousers(name,password)values(?,?)";

try{

ps=con.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);//获取返回的主键;

ps.setString(1,"qq");

ps.setString(2,"123");

ps.executeUpdate();

ResultSetrs=ps.getGeneratedKeys();//返回一个结果集,保存着产生的key的结果集,

while(rs.next()){

System.out.println(rs.getObject(1));//结果集只有一个值;

}

}catch(SQLExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}finally{

JDBCManager.DBclose(con,ps,null);

}

JDBC调用存储过程

存储过程的创建

createprocedure存储过程名(参数)

存储过程体

编写一个存储过程,查询学生表中的所有信息。

delimiter$$

createproceduremyproc1()

begin

select*formxs;

end$$

delimiter;

执行:callmyproc1();

参数

in:输入参数

out:输出参数

inout:输入输出参数

要求:编写一个存储过程,通过学号查询某学生的信息。

delimiter$$

createprocedureselect_student(inxhchar(6))

begin

select*fromxswhere学号=xh;

end$$

delimiter;

执行:callselect_student('081101');

要求:编写一个存储过程,统计学生的总人数

delimiter$$

createprocedurecount_xs(outnumberint)

begin

selectcount(*)intonumberfromxs;

end$$

delimiter;

执行:callcount_xs(@rs);

查询:select@rs;

createprocedure存储过程名(in|out|inout参数名类型。。。。);

JDBC调用存数过程(创建好存储过程体)

当值是输入函数时:

例:

Connectioncon=null;

CallableStatementcs=null;

con=JDBCManager.getConnection();

try{

cs=con.prepareCall("{callpd(?,?)}");//存储过程语句;

cs.setString(1,"yy");

cs.setString(2,"msn");

cs.execute();//执行

System.out.println("执行成功");

}catch(SQLExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}finally{

JDBCManager.DBclose(con,cs,null);

}

当输入和输出同时:

Connectioncon=null;

CallableStatementcs=null;

con=JDBCManager.getConnection();

try{

cs=con.prepareCall("{callpcall(?,?)}");

cs.setInt(1,10);

cs.registerOutParameter(2,Types.CHAR);//获取一下注册类型;

cs.execute();//执行

System.out.println(cs.getString(2));//获取第二个String类型的参数值;

cs.execute();

System.out.println("执行成功");

}catch(SQLExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}finally{

JDBCManager.DBclose(con,cs,null);

}

事务的概念

事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功。

例如:A——B转帐,对应于如下两条sql语句

updatefromaccountsetmoney=money+100wherename=‘b’;

updatefromaccountsetmoney=money-100wherename=‘a’;

数据库开启事务命令

starttransaction开启事务

Rollback回滚事务

Commit提交事务

当Jdbc程序向数据库获得一个Connection对象时,默认情况下这个Connection对象会自动向数据库提交在它上面发送的SQL语句。若想关闭这种默认提交方式,让多条SQL在一个事务中执行,可使用下列语句:

JDBC控制事务语句

Connection.setAutoCommit(false);starttransaction

Connection.rollback();rollback

Connection.commit();commit

创建JDBC的事务主要分以下步骤

1.设置事务的提交方式为非自动提交:

conn.setAutoCommit(false);

2.将需要添加事务的代码放入try,catch块中。

3.在try块内添加事务的提交操作,表示操作无异常,提交事务。

conn.commit();

4.在catch块内添加回滚事务,表示操作出现异常,撤销事务:

conn.rollback();

5.设置事务提交方式为自动提交:

conn.setAutoCommit(true);

事务的特性(ACID)

原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

一致性(Consistency)
事务必须使数据库从一个一致性状态变换到另外一个一致性状态。

隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

事务的隔离性:

脏读:

指一个事务读取了另外一个事务未提交的数据。

这是非常危险的,假设A向B转帐100元,对应sql语句如下所示

1.updateaccountsetmoney=money+100whilename=‘b’;

2.updateaccountsetmoney=money-100whilename=‘a’;

当第1条sql执行完,第2条还没执行(A未提交时),如果此时B查询自己的帐户,就会发现自己多了100元钱。如果A等B走后再回滚,B就会损失100元。

不可重复读:

在一个事务内读取表中的某一行数据,多次读取结果不同。

例如银行想查询A帐户余额,第一次查询A帐户为200元,此时A向帐户存了100元并提交了,银行接着又进行了一次查询,此时A帐户为300元了。银行两次查询不一致,可能就会很困惑,不知道哪次查询是准的。

和脏读的区别是,脏读是读取前一事务未提交的脏数据,不可重复读是重新读取了前一事务已提交的数据。

很多人认为这种情况就对了,无须困惑,当然是后面的为准。我们可以考虑这样一种情况,比如银行程序需要将查询结果分别输出到电脑屏幕和写到文件中,结果在一个事务中针对输出的目的地,进行的两次查询不一致,导致文件和屏幕中的结果不一致,银行工作人员就不知道以哪个为准了。

虚读(幻读)

是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。

如丙存款100元未提交,这时银行做报表统计account表中所有用户的总额为500元,然后丙提交了,这时银行再统计发现帐户为600元了,造成虚读同样会使银行不知所措,到底以哪个为准。

数据库共定义了四种隔离级别:

Serializable:可避免脏读、不可重复读、虚读情况的发生。(串行化)(序列化)

Repeatableread:可避免脏读、不可重复读情况的发生。(可重复读)

Readcommitted:可避免脏读情况发生(读已提交)。

Readuncommitted:最低级别,以上情况均无法保证。(读未提交)

settransactionisolationlevel设置事务隔离级别

select@@tx_isolation 查询当前事务隔离级别

例:

Connectioncon=null;

PreparedStatementst=null;

Stringsql1="insertintousers(name,password)values('bbbbb','bbbb')";

Stringsql2="deletefromuserswhereid=9";

try{

con=DBManager.getConnection();

con.setAutoCommit(false);//把自动提交方式变为人工

st=con.prepareStatement(sql1);

st.executeUpdate();

System.out.println("第一个语句成功了");

st=con.prepareStatement(sql2);

st.executeUpdate();

System.out.println("第二个语句成功了");

con.commit();

}catch(Exceptione){

try{

con.rollback();//出现异常进行回滚;

}catch(SQLExceptione1){

//TODOAuto-generatedcatchblock

e1.printStackTrace();

}

e.printStackTrace();

}finally{

try{

con.setAutoCommit(true);

}catch(SQLExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

DBManager.closeDB(con,st,null);

}

分享到:
评论

相关推荐

    JDBC笔记 JDBC笔记

    能够通过getMetaData方法获得数据库提供的信息、所支持的SQL语法、存储过程和此连接的功能等信息。代表了数据库。 java.sql.Driver 每个驱动程序类必需实现的接口,同时,每个数据库驱动程序都应该提供一个实现...

    Java_JDBC由浅入深

    第八节 JDBC对事务的支持 52 8.1 模拟转账 53 8.2 jdbc默认事务 54 8.3 事务提交与回滚 54 8.4 设置保存点 55 8.5 JTA事务的介绍 56 8.6 数据库的隔离级别介绍 56 8.6.1 未提交读 57 8.6.2 提交读 58 8.6.3 重复读 ...

    你不知道的JDBC高级应用

    5.储存过程和CRUD的操作,获得Statement可以添加的参数,最有用的是可以获得添加后的当前的自动增长的ID. 6.结果集:在JAVA中完全可以把结果集当作游标来处理,获得Statement可以添加的参数. 7.事务:设定事务的保存点,...

    JDBC核心技术精讲

    9、mysql的预处理功能开启 10、JDBC中日期时间类型讨论11、通过JDBC存储和取出音频和视频数据 12、批处理概述 13、事务概述及事务的四大特性 14、mysql中使用事务 15、jdbc中使用事务 16、数据库连接池的介绍和...

    JDBC连接操作Oracle及Mysql详解

    JDBC连接Oracle 11g及Mysql5,涉及传参,反射,读取属性文件,预处理,(预处理)批处理,带参数的存储过程,事务处理,可滚动的结果集,可更新的结果集

    jdbc连接数据库的方式2

    我们可以使用addBatch()和executeBatch()方法选择标准的JDBC批处理,或者通过利用PreparedStatement对象的setExecuteBatch()方法和标准的executeUpdate()方法选择速度更快的Oracle专有的方法。要使用Oracle专有的...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例238 优雅的JDBC代码 299 实例239 结果集与Bean列表 301 实例240 编写MD5查看器 302 实例241 基于Base64编码 304 实例242 基于Base64解码 305 实例243 发送简单的Email 306 实例244 发送带附件的Email 308 实例...

    Java语言基础下载

    使用存储过程 345 操作元数据 347 ResultSetMetaData(结果集元数据) 349 可滚动的和可更新的结果集 350 批处理更新 354 二进制大对象BLOB 357 RowSet 新特性 359 JdbcRowSet 360 FilteredRowSet 361 内容总结 363 ...

    MySQL 5.1参考手册

    14.6. 存储引擎和事务 14.7. 插入存储引擎 14.8. 拔出存储引擎 14.9. 插件式存储器的安全含义 15. 存储引擎和表类型 15.1. MyISAM存储引擎 15.1.1. MyISAM启动选项 15.1.2. 键所需的空间 15.1.3. MyISAM表的存储格式...

    mysql官方中文参考手册

    14.6. 存储引擎和事务 14.7. 插入存储引擎 14.8. 拔出存储引擎 14.9. 插件式存储器的安全含义 15. 存储引擎和表类型 15.1. MyISAM存储引擎 15.1.1. MyISAM启动选项 15.1.2. 键所需的空间 15.1.3. MyISAM表的存储格式...

    MYSQL中文手册

    3.5. 在批处理模式下使用mysql 3.6. 常用查询的例子 3.6.1. 列的最大值 3.6.2. 拥有某个列的最大值的行 3.6.3. 列的最大值:按组 3.6.4. 拥有某个字段的组间最大值的行 3.6.5. 使用用户变量 3.6.6. 使用外键 ...

    MySQL 5.1参考手册中文版

    3.5. 在批处理模式下使用mysql 3.6. 常用查询的例子 3.6.1. 列的最大值 3.6.2. 拥有某个列的最大值的行 3.6.3. 列的最大值:按组 3.6.4. 拥有某个字段的组间最大值的行 3.6.5. 使用用户变量 3.6.6. 使用外键 ...

    MySQL 5.1参考手册 (中文版)

    14.6. 存储引擎和事务 14.7. 插入存储引擎 14.8. 拔出存储引擎 14.9. 插件式存储器的安全含义 15. 存储引擎和表类型 15.1. MyISAM存储引擎 15.1.1. MyISAM启动选项 15.1.2. 键所需的空间 15.1.3. MyISAM表的存储格式...

    MySQL5.1参考手册官方简体中文版

    3.5. 在批处理模式下使用mysql 3.6. 常用查询的例子 3.6.1. 列的最大值 3.6.2. 拥有某个列的最大值的行 3.6.3. 列的最大值:按组 3.6.4. 拥有某个字段的组间最大值的行 3.6.5. 使用用户变量 3.6.6. 使用外键 3.6.7. ...

    JAVA 范例大全 光盘 资源

    实例190 调用存储过程 617 实例191 图片文件存入数据库 620 实例192 数据库图片的输出 622 实例193 利用console控制台运行类中的汉字处理方案 624 实例194 Servlet中的汉字处理方案 625 实例195 JSP中的汉字...

Global site tag (gtag.js) - Google Analytics