本文共 7384 字,大约阅读时间需要 24 分钟。
1.ResultSetMetaData
ResultSetMetaData:数据结果集的元数据
和查询出来的结果集相关,从结果集(ResultSet)中获取。
ResultSetMetaData用于描述列信息
例子:
DbUtils.java:
package com.lcz.jdbc.day03;import java.io.InputStream;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;import org.apache.commons.dbcp.BasicDataSource;/** * 连接池版本的数据库连接管理工具类 * 适合于并发场合 * @author LvChaoZhang * */public class DbUtils { private static String driver; private static String url; private static String username; private static String password; private static int initSize; private static int maxActive; private static BasicDataSource bs; static { //连接池 bs=new BasicDataSource(); Properties cfg=new Properties(); try { InputStream in =DbUtils.class.getClassLoader().getResourceAsStream("db.properties"); cfg.load(in); //初始化参数 driver=cfg.getProperty("jdbc.driver"); url=cfg.getProperty("jdbc.url"); username=cfg.getProperty("jdbc.user"); password=cfg.getProperty("jdbc.password"); initSize=Integer.parseInt(cfg.getProperty("initSize")); maxActive=Integer.parseInt(cfg.getProperty("maxActive")); in.close(); //初始化连接池 bs.setDriverClassName(driver); bs.setUrl(url); bs.setUsername(username); bs.setPassword(password); bs.setInitialSize(initSize); bs.setMaxActive(maxActive); } catch (Exception e) { throw new RuntimeException(e); } } public static Connection getConnection() { try { //getConnection()从连接池中获取重用的连接,如果连接池满了,则等待,如果有连接归还,则获取重用的连接 Connection conn = bs.getConnection(); return conn; } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException(); } } public static void rollback(Connection conn) { if(conn!=null) { try { conn.rollback(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void close(Connection conn) { if(conn!=null) { try { //将用过的连接归还到连接池中 conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }}
package com.lcz.jdbc.day03;import java.sql.Connection;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.Statement;/** * 结果集 * @author LvChaoZhang * */public class Demo01 { public static void main(String[] args) { Connection conn=null; try { conn=DbUtils.getConnection(); String sql="select * from student"; Statement st=conn.createStatement(); ResultSet rs = st.executeQuery(sql); ResultSetMetaData meta = rs.getMetaData(); int n=meta.getColumnCount(); for(int i=1;i<=n;i++) { String name=meta.getColumnName(i); System.out.println(name); } } catch (Exception e) { e.printStackTrace(); }finally { DbUtils.close(conn); } }}
2.事务(Transaction)
事务:数据库中保证交易可靠的机制
JDBC支持数据库中的事务概念;在JDBC中,事务默认是自动提交的
事务特性ACID:
(1)原子性:事务必须是原子工作单位;对于其数据修改,要么全都执行,要么全都不执行
(2)一致性:事务在完成时,必须使所有的数据都保持一致状态。
(3)隔离性:由并发事务所作的修改必须与任何其他并发事务所作的修改隔离
(4)持久性:事务完成之后,它对于系统的影响是永久性的。
JDBC事务API
相关API:
Connection.getAutoCommit():获得当前事务的提交方式,默认为true
Connection.setAutoCommit():设置事务的提交属性,参数是true:默认提交;false:不自动提交
Connection.commit():提交事务
例子:转账
package com.lcz.jdbc.day03;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;public class Demo2 { public static void main(String[] args) { pay(2,1,1000); System.out.println("ok"); } public static void pay(int from,int to,double money) { Connection conn=null; String sql1="update lcz_account set balance=balance+? where id=?"; String sql2="select balance from lcz_account where id=?"; 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("balance"); if(bal<0) { throw new Exception("原账号透支"); } } conn.commit(); } catch (Exception e) { e.printStackTrace(); DbUtils.rollback(conn); }finally { DbUtils.close(conn); } }}
3.批量更新
addBatch(String sql):Statement类的方法,可以将多条sql语句添加Statement的SQL语句列表中。
addBatch():PreparedStament类的方法,可以将多条预编译的sql语句添加到PreparedStatement对象的SQL语句列表中。
executeBatch():把Statement对象或PreparedStatement对象语句列表中的所有SQL语句发送给数据库进行处理。
clearBatch():清空当前SQL语句列表
防止OutOfMemory:如果PreparedStatement对象中的SQL列表包含过多的待处理的SQL语句会产生OutOfMemeory错误,分段处理SQL语句列表。
例子:批量处理DDL
package com.lcz.jdbc.day03;import java.sql.Connection;import java.sql.Statement;/** * 执行一批DDL * @author LvChaoZhang * */public class Demo03 { public static void main(String[] args) {// String sql1="create table log_01(id int(8),msg varchar(100))";// String sql2="create table log_02(id int(8),msg varchar(100))";// String sql3="create table log_03(id int(8),msg varchar(100))"; String sql1="insert log_01(id,msg) values(1,'I')"; String sql2="insert log_02(id,msg) values(2,'LOVE')"; String sql3="insert log_03(id,msg) values(3,'U')"; //执行一批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[] arr = st.executeBatch(); System.out.println("OK"); } catch (Exception e) { e.printStackTrace(); }finally { DbUtils.close(conn); } }}
例子:执行批量参数处理
package com.lcz.jdbc.day03;import java.sql.Connection;import java.sql.PreparedStatement;import java.util.Arrays;/** * 执行批量参数处理 * @author LvChaoZhang * */public class Demo04 { public static void main(String[] args) { String sql="insert into 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, "123456"); //将参数添加到缓冲区 ps.addBatch(); //防止OutOfMemory if((i+1)%8==0) { ps.executeBatch(); ps.clearBatch(); } } //批量执行 int[] arr = ps.executeBatch(); System.out.println(Arrays.toString(arr)); } catch (Exception e) { e.printStackTrace(); }finally { DbUtils.close(conn); } }}
4.返回自动主键
package com.lcz.jdbc.day03;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;/** * 数据库中 * * @author LvChaoZhang * */public class Demo5 { public static void main(String[] args) { Connection conn=null; try { conn=DbUtils.getConnection(); conn.setAutoCommit(false); //第一个sql String sql1="insert into r_keywords(word) values(?)"; String[] cols= {"id"};//自动生成序号的列名 PreparedStatement ps = conn.prepareStatement(sql1,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); } //第二个sql String sql2="insert into r_post(content,k_id) values(?,?)"; ps=conn.prepareStatement(sql2); 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); } }}
转载地址:https://codingchaozhang.blog.csdn.net/article/details/79688883 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!