JDBC的事务 Druid开源连接池的使用 C3P0开源连接池的使用 DBUtils

 事务的概念:

事务指的是逻辑上的一组操作,组成这组操作各个逻辑单元要么全都成功,要么全都失败。

 事务环境准备

 创建数据库和表

create database web_test;
use web_test;
create table account(
	id int primary key auto_increment,
	name varchar(20),
	money double
);
insert into account values (null,'aaa',10000);
insert into account values (null,'bbb',10000);
insert into account values (null,'ccc',10000);

 JDBC的事务管理

 转账案例代码实现

	@Test
	/**
	 * 完成转账的案例
	 */
	public void demo1(){
		Connection conn = null;
		PreparedStatement pstmt  = null;
		try{
			/**
			 * 完成转账代码:
			 * * 扣除某个账号的钱
			 * * 给另外一个账号加钱
			 */
			// 获得连接:
			conn = JDBCUtils.getConnection();
			// 编写SQL语句:
			String sql = "update account set money = money + ? where name = ?";
			// 预编译SQL:
			pstmt = conn.prepareStatement(sql);
			// 设置参数:
			// 用aaa账号给bbb账号转1000元
			pstmt.setDouble(1, -1000);
			pstmt.setString(2, "aaa");
			// 执行SQL:扣除aaa账号1000元
			pstmt.executeUpdate();
			
//			int i = 1 / 0;
			
			// 给bbb账号加1000
			pstmt.setDouble(1, 1000);
			pstmt.setString(2, "bbb");
			pstmt.executeUpdate();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JDBCUtils.release(pstmt, conn);
		}
	}

在转账中没有添加事务的管理,出现aaa账号的钱被转丢了,但是bbb账号的钱没有任何变化。需要给转账的功能添加事务的管理。

 在转账中添加事务管理:

 事务管理的API

在转账中添加事务管理

@Test
	/**
	 * 完成转账的案例
	 */
	public void demo(){
		Connection conn = null;
		PreparedStatement pstmt  = null;
		try{
			/**
			 * 完成转账代码:
			 * * 扣除某个账号的钱
			 * * 给另外一个账号加钱
			 */
			// 获得连接:
			conn = JDBCUtils.getConnection();
			// 开启事务
			conn.setAutoCommit(false);
			// 编写SQL语句:
			String sql = "update account set money = money + ? where name = ?";
			// 预编译SQL:
			pstmt = conn.prepareStatement(sql);
			// 设置参数:
			// 用aaa账号给bbb账号转1000元
			pstmt.setDouble(1, -1000);
			pstmt.setString(2, "aaa");
			// 执行SQL:扣除aaa账号1000元
			pstmt.executeUpdate();
			
			int i = 1 / 0;
			
			// 给bbb账号加1000
			pstmt.setDouble(1, 1000);
			pstmt.setString(2, "bbb");
			pstmt.executeUpdate();
			
			// 提交事务:
			conn.commit();
		}catch(Exception e){
			// 回滚事务:
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}finally{
			JDBCUtils.release(pstmt, conn);
		}
	}

 连接池的概述

 什么是连接池

连接池是装有连接的容器,使用连接的话,可以从连接池中进行获取,使用完成之后将连接归还给连接池。

 为什么要学习连接池

连接对象创建和销毁是需要耗费时间的,在服务器初始化的时候就初始化一些连接。把这些连接放入到内存中,使用的时候可以从内存中获取,使用完成之后将连接放入连接池中。从内存中获取和归还的效率要远远高于创建和销毁的效率。(提升性能)。

 连接池原理

 Druid开源连接池的使用

 Druid的概述

Druid阿里旗下开源连接池产品,使用非常简单,可以与Spring框架进行快速整合。

 Druid的使用

@Test
	/**
	 * Druid的使用:
	 * * 手动设置参数的方式
	 */
	public void demo1(){
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try{
			// 使用连接池:
			DruidDataSource dataSource = new DruidDataSource();
			// 手动设置数据库连接的参数:
			dataSource.setDriverClassName("com.mysql.jdbc.Driver");
			dataSource.setUrl("jdbc:mysql:///web_test4");
			dataSource.setUsername("root");
			dataSource.setPassword("abc");
			// 获得连接:
//			conn = JDBCUtils.getConnection();
			conn = dataSource.getConnection();
			// 编写SQL:
			String sql = "select * from account";
			// 预编译SQL:
			pstmt = conn.prepareStatement(sql);
			// 设置参数:
			// 执行SQL:
			rs = pstmt.executeQuery();
			while(rs.next()){
				System.out.println(rs.getInt("id")+" "+rs.getString("name")+" "+rs.getDouble("money"));
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JDBCUtils.release(rs, pstmt, conn);
		}
	}

 Druid开源连接池的使用二

 使用配置方式完成连接池的使用

@Test
	/**
	 * Druid的使用:
	 * * 配置方式设置参数
	 * Druid配置方式可以使用属性文件配置的。
	 * * 文件名称没有规定但是属性文件中的key要一定的。
	 */
	public void demo(){
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try{
			// 使用连接池:
			// 从属性文件中获取:
			Properties properties = new Properties();
			properties.load(new FileInputStream("src/druid.properties"));
			DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
			// 获得连接:
//			conn = JDBCUtils.getConnection();
			conn = dataSource.getConnection();
			// 编写SQL:
			String sql = "select * from account";
			// 预编译SQL:
			pstmt = conn.prepareStatement(sql);
			// 设置参数:
			// 执行SQL:
			rs = pstmt.executeQuery();
			while(rs.next()){
				System.out.println(rs.getInt("id")+" "+rs.getString("name")+" "+rs.getDouble("money"));
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JDBCUtils.release(rs, pstmt, conn);
		}
	}

 C3P0开源连接池的使用

 C3P0的连接池的概述

 C3P0的连接池的使用

手动设置参数的方式

	@Test
	/**
	 * 手动设置参数的方式:
	 */
	public void demo1(){
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try{
			// 获得连接:从连接池中获取:
			// 创建连接池:
			ComboPooledDataSource dataSource = new ComboPooledDataSource();
			// 设置连接参数:
			dataSource.setDriverClass("com.mysql.jdbc.Driver");
			dataSource.setJdbcUrl("jdbc:mysql:///web_test");
			dataSource.setUser("root");
			dataSource.setPassword("root");
			// 从连接池中获得连接:
			conn = dataSource.getConnection();
			// 编写SQL:
			String sql = "select * from account";
			// 预编译SQL:
			pstmt = conn.prepareStatement(sql);
			// 执行SQL:
			rs = pstmt.executeQuery();
			while(rs.next()){
				System.out.println(rs.getInt("id")+" "+rs.getString("name")+" "+rs.getDouble("money"));
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JDBCUtils.release(rs, pstmt, conn);
		}
	}

 C3P0开源连接池的使用二

 C3P0连接池的使用

 采用配置文件的方式:

 配置连接池

使用连接池
	@Test
	/**
	 * 采用配置文件的方式:
	 */
	public void demo2(){
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try{
			// 获得连接:从连接池中获取:
			// 创建连接池://创建连接池默认去类路径下查找c3p0-config.xml
			ComboPooledDataSource dataSource = new ComboPooledDataSource();
			// 从连接池中获得连接:
			conn = dataSource.getConnection();
			// 编写SQL:
			String sql = "select * from account";
			// 预编译SQL:
			pstmt = conn.prepareStatement(sql);
			// 执行SQL:
			rs = pstmt.executeQuery();
			while(rs.next()){
				System.out.println(rs.getInt("id")+" "+rs.getString("name")+" "+rs.getDouble("money"));
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JDBCUtils.release(rs, pstmt, conn);
		}
	}

 改写工具类

 工具类代码实现

连接池对象应该是一个应用只创建一次就可以的,不需要每次使用都创建一个新的连接池

工具类代码实现

 DBUtils的概述

 什么是DBUtils

JDBC的简单封装,而且没有影响性能。

为什么要学习DBUtils

因为JDBC手写比较麻烦,而且有非常多的代码是类似的。比如获得连接,预编译SQL,释放资源等..那么可以将这些代码抽取出来放到工具类中。将类似的代码进行抽取。大大简化JDBC的编程。

 DBUtilsAPI

 DBUtilsAPI的概述

 QueryRunner对象:核心运行类

 构造方法:


方法:




在一般情况下如果执行CRUD的操作:
构造:
QueryRunner(DataSource ds);
方法:
int update(String sql,Object… args);
T query(String sql,ResultSetHandler rsh,Object… args);
如果有事务管理的话使用另一套完成CRUD的操作
构造:
QueryRunner();
方法:
int update(Connection conn,String sql,Object… args);
T query(Connection conn,String sql,ResultSetHandler rsh,Object… args);

方法


DbUtils

 方法:

 DBUtils的使用之增删改的操作

 DBUtils的添加操作

	@Test
	/**
	 * 添加操作
	 */
	public void demo1() throws SQLException{
		// 创建核心类:QueryRunner:
		QueryRunner queryRunner = new QueryRunner(JDBCUtils2.getDataSource());
		queryRunner.update("insert into account values (null,?,?)", "ddd",10000);
	}
1.1.2DBUtils的修改操作
	@Test
	/**
	 * 修改操作
	 */
	public void demo2() throws SQLException{
		// 创建核心类:
		QueryRunner queryRunner = new QueryRunner(JDBCUtils2.getDataSource());
		queryRunner.update("update account set name=?,money=? where id =?", "eee",20000,4);
	}
1.1.3DBUtils的删除操作
	@Test
	/**
	 * 删除操作
	 */
	public void demo3() throws SQLException{
		// 创建核心类:
		QueryRunner queryRunner = new QueryRunner(JDBCUtils2.getDataSource());
		queryRunner.update("delete from account where id = ?", 3);
	}

 DBUtils的使用之查询的操作

 查询的代码实现

 查询一条记录

创建一个对象:Account

 查询代码实现

 查询多条记录

 DBUtils的使用之ResultSetHandler的实现类

 ArrayHandlerArrayListHandler

 ArrayHandler

一条记录封装到一个数组当中。这个数组应该是Object[]

 ArrayListHandler

将多条记录封装到一个装有Object[]List集合中。

 DBUtils的使用ResultSetHandler的实现类二

BeanHandlerBeanListHandler

 BeanHandler

将一条记录封装到一个JavaBean中。

 BeanListHandler

将多条记录封装到一个装有JavaBeanList集合中。

 DBUtils的使用之ResultSetHandler的实现类三

 MapHandlerMapListHandler

 MapHandler

将一条记录封装到一个Map集合中,Mapkey是列名,Mapvalue就是表中列的记录值。

 MapListHandler

将多条记录封装到一个装有MapList集合中。

 DBUtils的使用之ResultSetHandler的实现类四

 ColumnListHandlerScalarHandlerKeyedHandler

 ColumnListHandler

将数据中的某列封装到List集合中。

ScalarHandler

将单个值封装。

KeyedHandler(了解)

将一条记录封装到一个Map集合中。将多条记录封装到一个装有Map集合的Map集合中。而且外面的Mapkey是可以指定的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值