【JDBC】day04_事务_批处理_自动主键_DAO
2015-09-21 21:04
393 查看
【JDBC】day04_事务_批处理_自动主键_DAO
1)事务特性介绍:ACID
原子性(Atomicity):事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行
一致性(Consistency):事务在完成时,必须使所有的数据都保持一致状态
隔离性(Isolation):由并发事务所作的修改必须与任何其它并发事务所作的修改隔离
持久性(Durability):事务完成之后,它对于系统的影响是永久性的
2)标准写法:
Connection conn = null;
try{
conn = DBUtil.getConnection();
//关闭自动提交(开启事务)
conn.setAutoCommit(false);
//一系列SQL ...
conn.commit(); //提交 结束事务
}catch(Exception e){
if(conn!=null){ //避免空指针异常
conn.rollback(); //回滚 结束事务
}
e.printStackTrace();
throw e;
}finally{
if(conn!=null){
conn.close();
}
}
3)何时使用事务:
在一个原子业务操作中 有多条SQL(DML DQL) 时候需要使用 事务将 业务过程进行保护起来,
保证: 所有SQL都正确执行,或者都回退,不能出现执行一半的情况!
addBatch(String sql)
Statement类的方法, 可以将多条sql语句添加Statement对象的SQL语句列表中
addBatch()
PreparedStatement类的方法, 可以将多条预编译的sql语句添加到PreparedStatement对象的SQL语句列表中
executeBatch()
把Statement对象或PreparedStatement对象语句列表中的所有SQL语句发送给数据库进行处理
clearBatch()
清空当前SQL语句列表
2)大量数据示例:
----executeBatch()返回影响数据库多少条数据(-2表示成功执行不确定影响多少条数据,-3表示未成功执行)
方法一:先通过序列的nextval获取序列的下一个值,再作为参数插入到主表和从表。
这种方式操作简单,但需要额外多一次访问数据库,影响性能。
方法二(建议):利用PreparedStatement的getGeneratedKeys方法获取自增类型的数据,性能良好,只要一次SQL交互。
代码示例:
目的:数据访问逻辑和业务逻辑分开。
2)
为了建立一个健壮的Java应用,需将所有对数据源的访问操作抽象封装在一个公共API中,需要:
建立一个接口,接口中定义了应用程序中将会用到的所有事务方法
建立接口的实现类,实现接口对应的所有方法,和数据库直接交互
在应用程序中,当需要和数据源交互时则使用DAO接口,不涉及任何数据库的具体操作。DAO通常包括:
1. 一个DAO工厂类;
2. 一个DAO接口;
3. 一个实现DAO接口的具体类;
4. 数据传递对象(实体对象(Entity)或值对象(Value Object,简称VO)).
3)实体对象
DAO层需要定义对数据库中表的访问。
对象关系映射(ORM:Object/Relation Mapping)描述对象和数据表之间的映射,将Java程序中的对象对应到关系数据库的表中:
表和类对应
表中的字段和类的属性对应
记录和对象对应
1.事务
事务(Transaction):数据库中保证交易可靠的机制。JDBC支持数据库中的事务概念,并且在JDBC中,事务默认是自动提交的。1)事务特性介绍:ACID
原子性(Atomicity):事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行
一致性(Consistency):事务在完成时,必须使所有的数据都保持一致状态
隔离性(Isolation):由并发事务所作的修改必须与任何其它并发事务所作的修改隔离
持久性(Durability):事务完成之后,它对于系统的影响是永久性的
2)标准写法:
Connection conn = null;
try{
conn = DBUtil.getConnection();
//关闭自动提交(开启事务)
conn.setAutoCommit(false);
//一系列SQL ...
conn.commit(); //提交 结束事务
}catch(Exception e){
if(conn!=null){ //避免空指针异常
conn.rollback(); //回滚 结束事务
}
e.printStackTrace();
throw e;
}finally{
if(conn!=null){
conn.close();
}
}
3)何时使用事务:
在一个原子业务操作中 有多条SQL(DML DQL) 时候需要使用 事务将 业务过程进行保护起来,
保证: 所有SQL都正确执行,或者都回退,不能出现执行一半的情况!
2.批处理
1)常用方法addBatch(String sql)
Statement类的方法, 可以将多条sql语句添加Statement对象的SQL语句列表中
addBatch()
PreparedStatement类的方法, 可以将多条预编译的sql语句添加到PreparedStatement对象的SQL语句列表中
executeBatch()
把Statement对象或PreparedStatement对象语句列表中的所有SQL语句发送给数据库进行处理
clearBatch()
清空当前SQL语句列表
2)大量数据示例:
package day03; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Statement; import day02.DBUtil; public class JDBCDemo4 { public static void main(String[] args) { Connection conn = null; try{ conn = DBUtil.getConnection(); String sql = "insert into account_qxl " + "(aname,balance) values(?,?) "; PreparedStatement ps = conn.prepareStatement(sql); for(int i=0;i<10000000;i++){ String name="n"+i; ps.setString(1,name); ps.setDouble(2,500); ps.addBatch(); if(i%1000000==0){ int[] ary = ps.executeBatch(); for(int j=0;j<ary.length;j++){ if(ary[j]==Statement.EXECUTE_FAILED){ throw new SQLException("出错了!"); } } } } int[] ary = ps.executeBatch(); for(int j=0;j<ary.length;j++){ if(ary[j]==Statement.EXECUTE_FAILED){ throw new SQLException("出错了!"); } } conn.close(); }catch(Exception e){ e.printStackTrace(); DBUtil.rollback(conn); }finally{ DBUtil.close(conn); } } }
----executeBatch()返回影响数据库多少条数据(-2表示成功执行不确定影响多少条数据,-3表示未成功执行)
3.返回自动主键
1)JDBC自动返回主键方法:方法一:先通过序列的nextval获取序列的下一个值,再作为参数插入到主表和从表。
这种方式操作简单,但需要额外多一次访问数据库,影响性能。
方法二(建议):利用PreparedStatement的getGeneratedKeys方法获取自增类型的数据,性能良好,只要一次SQL交互。
代码示例:
package day03; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import day02.DBUtil; public class JDBCDemo5 { public static void main(String[] args) { Connection conn = null; try{ conn = DBUtil.getConnection(); conn.setAutoCommit(false); String sql1 = "insert into qxl_dept " + "(deptno,dname) values(seq_qxl_dept.nextval,?)"; String sql2 = "insert into qxl_emp " + "(empno,ename,salary,deptno) " + "values(seq_qxl_emp.nextval,?,?,?)"; System.out.println(sql1+"\n"+sql2); //第二个参数是生成列的列名 PreparedStatement ps = conn.prepareStatement(sql1,new String[]{"deptno"}); ps.setString(1,"IOS"); ps.executeUpdate(); //获取自动生成的(Generated)deptno ResultSet rs = ps.getGeneratedKeys(); int deptNo = -1; while(rs.next()){ deptNo = rs.getInt(1); //只能利用序列号获取结果 } System.out.println("deptno:"+deptNo); ps.close(); ps = conn.prepareStatement(sql2); ps.setString(1,"Tom"); ps.setDouble(2,3000); ps.setInt(3,deptNo); ps.executeUpdate(); conn.commit(); }catch(Exception e){ e.printStackTrace(); DBUtil.rollback(conn); }finally{ DBUtil.close(conn); } } }
4.DAO
1)DAO (Data Access Object):数据访问对象,是建立在数据库和业务层之间,封装所有对数据库的访问。目的:数据访问逻辑和业务逻辑分开。
2)
为了建立一个健壮的Java应用,需将所有对数据源的访问操作抽象封装在一个公共API中,需要:
建立一个接口,接口中定义了应用程序中将会用到的所有事务方法
建立接口的实现类,实现接口对应的所有方法,和数据库直接交互
在应用程序中,当需要和数据源交互时则使用DAO接口,不涉及任何数据库的具体操作。DAO通常包括:
1. 一个DAO工厂类;
2. 一个DAO接口;
3. 一个实现DAO接口的具体类;
4. 数据传递对象(实体对象(Entity)或值对象(Value Object,简称VO)).
3)实体对象
DAO层需要定义对数据库中表的访问。
对象关系映射(ORM:Object/Relation Mapping)描述对象和数据表之间的映射,将Java程序中的对象对应到关系数据库的表中:
表和类对应
表中的字段和类的属性对应
记录和对象对应
相关文章推荐
- 数据库概论学习笔记------数据的完整性约束
- nefu1037回文子序列数
- C++ 版本的 行为树的简单实现
- Android学习进阶路线导航线路(Android源码分享) ...
- HDOJ2063过山车 匈牙利算法
- 问题-XE8客户端访问Webservice时报“no selected dom vendor”
- [codevs2419]ISBN号码
- CUDA VS2008 win32 控制台 创建static device lib 库
- Objective-C入门12:字符串
- POJ 2828 线段树
- 设计模式之适配器模式
- 叉积判断点在多边形内外 & poj2318
- 关于打印浮点数的一个问题
- C#软件开发实例.私人订制自己的屏幕截图工具(十)在截图中包含鼠标指针形状
- hdu 1051-Wooden Sticks
- 代码中特殊的注释技术——TODO、FIXME和XXX的用处
- 春暖花会开
- java三元运算a?b:c(2015年9月20日)
- usaco Riding the Fences
- git pull冲突解决