JDBC之结果集元数据、事务控制、批量执行、返回自动主键
来源:互联网 发布:php url encode 在线 编辑:程序博客网 时间:2024/06/16 08:20
结果集元数据
ResultSetMetaData用于描述查询结果的相关信息, 其中包含列名称, 列数量, 类数据类型等.
原理:
使用案例:
public static void main(String[] args) { Connection conn = null; try { conn = DBUtils.getConnection(); String sql = "select * from " + "robin_user"; Statement st = conn.createStatement(); ResultSet rs=st.executeQuery(sql); //结果集元数据 ResultSetMetaData meta= rs.getMetaData(); int n = meta.getColumnCount(); for(int i=1; i<=n; i++){ // i = 1 ... n String name= meta.getColumnName(i); System.out.println(name); } } catch (Exception e) { e.printStackTrace(); } finally { DBUtils.close(conn); }}
作业:
/** * 打印一个SQL查询结果的全部列名 * @param sql */public static void print(String sql){ //...}
JDBC 事务控制
数据库提供了事务控制功能, 支持ACID特性.
JDBC提供了API, 方便的调用数据库的事务功能, 其方法有:
相关API:
- Connection.getAutoCommit():获得当前事务的提交方式,默认为true
- Connection.setAutoCommit():设置事务的提交属性,参数是
- true:自动提交;false:不自动提交
- Connection.commit():提交事务
- Connection.rollback():回滚事务
事务API调用模板:
Connection conn = null;try { conn = DBUtils.getConnection(); //取消自动提交, 后续手动提交 conn.setAutoCommit(false); //SQL... update //SQL... update // 余额不足 抛出异常 throw e; //SQL... update conn.commit();} catch (Exception e) { e.printStackTrace(); DBUtils.rollback(conn);} finally { DBUtils.close(conn);}
提示: 事务API经典的用法是采用如上模板, 其中DBUtils.rollback()方法封装了回滚方法, 其声明如下:
public static void rollback(Connection conn) { if(conn!=null){ try { conn.rollback(); } catch (Exception e) { e.printStackTrace(); } }}
事务测试案例数据:
create table r_account( id number(6), name varchar2(100), balance number(8,2));insert into r_account (id, name, balance) values (1, '范老师', 500);insert into r_account (id, name, balance) values (2, '刘老师', 1500);insert into r_account (id, name, balance) values (3, '何仙姑', 2000);commit;
汇款案例:
public static void main(String[] args) { pay(1, 4, 500); System.out.println("ok"); }public static void pay( int from , int to, double money){ String sql1="update r_account " + "set balance=balance+? " + "where id=?"; String sql2="select balance from " + "r_account where id=?"; Connection conn = null; try { conn = DBUtils.getConnection(); conn.setAutoCommit(false); PreparedStatement ps= conn.prepareStatement(sql1); //减钱 ps.setDouble(1, -money); ps.setInt(2, from); int n = ps.executeUpdate(); if(n!=1){ throw new Exception("扣错了"); } //增加 ps.setDouble(1, money); ps.setInt(2, to); n = ps.executeUpdate(); if(n!=1){ throw new Exception("加错了"); } ps.close(); //检查 ps = conn.prepareStatement(sql2); ps.setInt(1, from); ResultSet rs=ps.executeQuery(); while(rs.next()){ double bal=rs.getDouble(1); if(bal<0){ throw new Exception("透支"); } } conn.commit(); } catch (Exception e) { e.printStackTrace(); DBUtils.rollback(conn); }finally{ DBUtils.close(conn); }}
批量执行
批处理:发送到数据库作为一个单元执行的一组更新语句
批处理降低了应用程序和数据库之间的网络调用
相比单个SQL语句的处理,批处理更为有效
API方法:
- addBatch(String sql)
- Statement类的方法, 可以将多条sql语句添加Statement对象的SQL语句列表中
- addBatch()
- PreparedStatement类的方法, 可以将多条预编译的sql语句添加到PreparedStatement对象的SQL语句列表中
- executeBatch()
- 把Statement对象或PreparedStatement对象语句列表中的所有SQL语句发送给数据库进行处理
- clearBatch()
- 清空当前SQL语句列表
案例: 批量执行DDL
public static void main(String[] args) { String sql1="create table log_01 " + "(id number(8), " + "msg varchar2(100))"; String sql2="create table log_02 " + "(id number(8), " + "msg varchar2(100))"; String sql3="create table log_03 " + "(id number(8), " + "msg varchar2(100))"; //执行一批SQL Connection conn = null; try { conn = DBUtils.getConnection(); Statement st=conn.createStatement(); //sql1 添加到Statement的缓存中 st.addBatch(sql1); st.addBatch(sql2); st.addBatch(sql3); //执行一批SQL int[] ary=st.executeBatch(); System.out.println(Arrays.toString(ary)); System.out.println("OK"); } catch (Exception e) { e.printStackTrace(); } finally { DBUtils.close(conn); }}
案例: 批量插入数据
public static void main(String[] args) { String sql="insert into robin_user " + "( id, name, pwd ) " + "values (?,?,?)"; Connection conn = null; try { conn = DBUtils.getConnection(); PreparedStatement ps= conn.prepareStatement(sql); for(int i=0; i<100; i++){ //替换参数 ps.setInt(1, i); ps.setString(2,"name"+i); ps.setString(3, "123"); //将参数添加到ps缓存区 ps.addBatch(); } //批量执行 int[] ary=ps.executeBatch(); System.out.println(Arrays.toString(ary)); } catch (Exception e) { e.printStackTrace(); } finally { DBUtils.close(conn); }}
防止批量过大出现OutOfMemory错误:
如果Preparedstatement对象中的缓存列表包含过多的待处理数据, 可能会产生OutOfMemory错误, 分段处理缓存列表.
案例:
public static void main(String[] args) { String sql="insert into robin_user " + "( id, name, pwd ) " + "values (?,?,?)"; Connection conn = null; try { conn = DBUtils.getConnection(); PreparedStatement ps= conn.prepareStatement(sql); for(int i=0; i<100; i++){ //替换参数 ps.setInt(1, i); ps.setString(2,"name"+i); ps.setString(3, "123"); //将参数添加到ps缓存区 ps.addBatch(); //i = 0 1 2 3 4 5 6 7 8 9 .. // ...15...23...31 if((i+1)%8==0){ int[] ary= ps.executeBatch(); ps.clearBatch(); System.out.println( Arrays.toString(ary)); } } //批量执行 int[] ary=ps.executeBatch(); System.out.println(Arrays.toString(ary)); } catch (Exception e) { e.printStackTrace(); } finally { DBUtils.close(conn); }}
返回自动主键
JDBC API 提供了返回插入数据期间自动生成ID的API,
API方法:
- stmt = con.prepareStatement(sql, 列名列表);
- rs = stmt.getGeneratedKeys();
准备数据:
create table r_post( id number(8), content varchar2(100), K_id number(8));create sequence p_seq;create table r_keywords( id number(8), word varchar2(8));create sequence k_seq;
需要执行的SQL:
insert into r_keywords (id, word) values (k_seq.nextval, ?)insert into r_post (id, content, k_id) values (p_seq.nextval, ?, ?)
案例:
public static void main(String[] args) { Connection conn = null; try { conn = DBUtils.getConnection(); conn.setAutoCommit(false); String sql="insert into r_keywords " + "(id, word) values " + "(k_seq.nextval, ?)"; String[] cols={"id"};//列名 //自动生成序号的的列名 PreparedStatement ps= conn.prepareStatement(sql, cols); ps.setString(1, "雾霾"); int n = ps.executeUpdate(); if(n!=1){ throw new Exception("话题添加失败"); } //获取自动生成的ID ResultSet rs = ps.getGeneratedKeys(); int id=-1; while(rs.next()){ id = rs.getInt(1); } rs.close(); ps.close(); sql = "insert into r_post " + "(id, content, k_id) " + "values (p_seq.nextval, ?, ?)"; ps=conn.prepareStatement(sql); ps.setString(1, "今天天气不错,晚上有雾霾!"); ps.setInt(2, id); n = ps.executeUpdate(); if(n!=1){ throw new Exception("天气太糟"); } conn.commit(); System.out.println("OK"); } catch (Exception e) { e.printStackTrace(); DBUtils.rollback(conn); } finally { DBUtils.close(conn); }}
0 0
- JDBC之结果集元数据、事务控制、批量执行、返回自动主键
- JDBC-ResultSet之滚动结果集-光标与元数据
- JDBC之用元数据将结果集封装为List对象
- JDBC之用元数据将结果集封装为List对象
- JDBC之事务、批量处理
- JDBC的事务控制和批量处理
- JDBC的事务控制和批量处理
- JDBC的事务控制和批量处理
- JDBC 插入数据返回数据主键
- JDBC 插入数据返回数据主键
- JDBC 插入数据返回数据主键
- 转摘 JDBC 插入数据返回数据主键
- JDBC之元数据
- [疯狂Java]JDBC:ResultSetMetaData(结果集元数据分析)
- JDBC中如何通过结果集获取元数据
- 批量更新数据之hibernate或者jdbc执行效果对比
- 【JDBC】day04_事务_批处理_自动主键_DAO
- JDBC之元数据分析
- 1032. 挖掘机技术哪家强(20)
- 尝试配置本地yum源
- 使用广义表创建二叉树
- 在Eclipse中安装和使用Git Plugin
- nginx https配置后无法访问,可能防火墙在捣鬼
- JDBC之结果集元数据、事务控制、批量执行、返回自动主键
- Git - 在本次commit上再次修改
- android 中处理崩溃异常并重启程序出现页面重叠的问题
- 修改tomcat端口号
- anaconda安装报错解决
- struts2总结
- 利用grub2.0/grub4dos实现双硬盘双(多)系统
- java webstruct2 学习
- android复习路之fragment篇