JDBC与DAO篇--03 JDBC高级编程、DAO
发布日期:2021-06-29 15:41:37 浏览次数:4 分类:技术文章

本文共 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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:面向对象篇(OOP)--07 面向对象思想设计原则及常见设计模式
下一篇:【Java面试题十】一套完整的java面试题

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年04月02日 21时45分00秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章