事务&数据库连接池&DBUtils

事务:

Transaction   其实指的一组操作,里面包含许多个单一的逻辑。只要有一个逻辑没有执行成功,那么都算失败。所有的数据都回归到最初的状态(回滚)

作用:为了确保逻辑的成功。例子:银行的转账

使用命令行方式演示事务:
开启事务
        start transaction;
提交或者回滚事务
        commit;提交事务,数据将会写到磁盘上的数据库
        rollback;数据回滚,回到最初的状态
使用代码方式演示事务:
1.通过conn.setAutoCommit(false)来关闭自动提交的设置
2.提交事务  conn.commit();
3.回滚事务  conn.rollback();

事务的特性:

原子性、一致性、隔离性、持久性

按效率划分,从高到低:

读未提交 > 读已提交 >可重复读 > 可串行化

按拦截程度,从高到底:

可串行化 > 可重复读 > 读已提交 > 读未提交

事务总结:

1.在代码里面会使用事务

2.事务只是针对连接连接对象,如果再开一个连接对象,那么那是默认的提交

3.事务是会自动提交的

解决丢失更新:

悲观锁:可以在查询的时候,加入for update

乐观锁:要求程序员自己控制

 

数据库连接池:

1.数据库的连接对象创建工作,比较消耗性能

2.一开始先在内存中开辟一块空间(集合),一开始先往池子里面放置多个连接对象。后面需要连接的话,直接从池子里面去取。不要去自己创建连接了。使用完毕,要记得归还连接。确保连接对象能循环利用。

解决自定义数据库连接池出现的问题:

1.由于多了一个addBack方法,所以使用这个连接池的地方,需要额外记住这个方法,并且还不能面向接口编程

2.我们打算修改接口中的那个close方法,原来的Connection对象的Close方法,是真的关闭连接。

3.打算修改这个close方法,以后在调用close,并不是真的关闭,而是归还连接对象。

 

如何扩展某一个方法?
1.直接改源码 无法实现

2.继承,必须得知道这个接口的具体实现是谁

3.使用装饰者模式

4.动态代理

 

DBCP:

1.导入jar文件

2.不使用配置文件方式:

package com.itheima.dbcp;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.apache.commons.dbcp.BasicDataSource;
import org.junit.Test;

import com.itheima.util.JDBCUtil;

public class DBCPDemo {
	@Test
	public void testDBCP01() {
		Connection conn=null;
		PreparedStatement ps=null;
		
		try {
			//1.构建数据源对象
			BasicDataSource dataSource = new BasicDataSource();
			//连的是什么类型的数据库,访问的是哪个数据库,用户名,密码
			dataSource.setDriverClassName("com.mysql.jdbc.Driver");
			dataSource.setUrl("jdbc:mysql://localhost/stus");
			dataSource.setUsername("root");
			dataSource.setPassword("root");
			//2.得到连接对象
			 conn = dataSource.getConnection();
			String sql = "insert into t_user values(null,?,?)";
			 ps = conn.prepareStatement(sql);
			ps.setString(1, "admin");
			ps.setString(2, "333");
			ps.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			JDBCUtil.release(conn, ps);
		}
	}
}

2.使用配置文件方式:

package com.itheima.dbcp;

import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.junit.Test;

import com.itheima.util.JDBCUtil;

public class DBCPDemo02 {
	@Test
	public void testDBCP02() {
		/*BasicDataSource dataSource = new BasicDataSource();
		dataSource.setConnectionProperties("dbcpconfig.properties");*/
		
		Connection conn=null;
		PreparedStatement ps=null;
		
		try {
			BasicDataSourceFactory factory = new BasicDataSourceFactory();
			Properties properties = new Properties();
			InputStream is = new FileInputStream("src//dbcpconfig.properties");
			properties.load(is);
			DataSource dataSource=factory.createDataSource(properties);
			//2.得到连接对象
			 conn = dataSource.getConnection();
			String sql = "insert into t_user values(null,?,?)";
			 ps = conn.prepareStatement(sql);
			ps.setString(1, "hmx");
			ps.setString(2, "123");
			ps.executeUpdate();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			JDBCUtil.release(conn, ps);
		}
	}
}

C3P0:

1.导入jar文件

2.不使用配置文件方式:

package com.itheima.c3p0;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.junit.Test;

import com.itheima.util.JDBCUtil;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0Demo {
	@Test
	public void testC3P0() {
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			//1.创建datasource
			ComboPooledDataSource dataSource = new ComboPooledDataSource();
			//2.设置连接数据的信息
			dataSource.setDriverClass("com.mysql.jdbc.Driver");
			dataSource.setJdbcUrl("jdbc:mysql://localhost/stus");
			dataSource.setUser("root");
			dataSource.setPassword("root");
			//2.得到连接对象
			 conn = dataSource.getConnection();
			String sql = "insert into t_user values(null,?,?)";
			 ps = conn.prepareStatement(sql);
			ps.setString(1, "admin");
			ps.setString(2, "12333");
			ps.executeUpdate();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			JDBCUtil.release(conn, ps);
		}
		
	}
}

2.使用配置文件方式:c3p0-config.xml

package com.itheima.c3p0;

import java.sql.Connection;
import java.sql.PreparedStatement;

import org.junit.Test;

import com.itheima.util.JDBCUtil;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0Demo02 {
	@Test
	public void testC3p0() {
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			//
			ComboPooledDataSource dataSource = new ComboPooledDataSource();
			//2.得到连接对象
			 conn = dataSource.getConnection();
			String sql = "insert into t_user values(null,?,?)";
			 ps = conn.prepareStatement(sql);
			ps.setString(1, "admin");
			ps.setString(2, "1233333");
			ps.executeUpdate() ;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			JDBCUtil.release(conn, ps);
		}
	}
}
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
  <default-config>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost/stus</property>
    <property name="user">root</property>
    <property name="password">root</property>
    
    <property name="initialPoolSize">10</property>
    <property name="maxIdleTime">30</property>
    <property name="maxPoolSize">100</property>
    <property name="minPoolSize">10</property>
    <property name="maxStatements">200</property>
  </default-config>

  
</c3p0-config>

DBUtils:

package com.itheima.dbutils;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.junit.Test;

import com.itheima.domain.Account;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class TestDBUtils {
	
	@Test
	public void testInsert() throws SQLException {
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		//dbutils只是帮我们简化了CRUD的代码,但是连接的创建以及获取工作,不在他的考虑范围
		QueryRunner queryRunner = new QueryRunner(dataSource);
		//针对增加、删除、修改
		//queryRunner.update(sql);
		//针对查询
		//queryRunner.query(sql, rsh);
		//queryRunner.update("insert into t_user values (null,?,?)", "HMX","111");
		//queryRunner.update("delete from t_user where id = ?", 5);
		//queryRunner.update("update t_user set password = ? where id = ?","Hmx",6);
		//去执行查询,查询到的数据还是在那个result里面,然后调用下面的handle方法,由用户手动封装
		/*Account account = queryRunner.query("select * from t_user where id = ?", new ResultSetHandler<Account>() {
				
			@Override
			public Account handle(ResultSet rs) throws SQLException {
				Account account = new Account();
				while(rs.next()) {
					String name = rs.getString("username");
					String password = rs.getString("password");
					account.setName(name);
					account.setPassword(password);
				}
				
				return account;
			}
			
		}, 6);
		System.out.println(account.toString());*/
		//通过类的字节码得到该类的实例
		//Account a = new Account();
		//创建一个类的实例
		//Account a1 = Account.class.newInstance();
		//Account account=queryRunner.query("select * from t_user where id = ?", new BeanHandler<Account>(Account.class), 3);
		//System.out.println(account.toString()); 
		List<Account> query = queryRunner.query("select * from t_user", new BeanListHandler<Account>(Account.class));
		for (Account account : query) {
			System.out.println(account.toString());
		}
	}
}

ResultSetHandler常用的实现类:

BeanHandler,查询到的单个数据封装成一个对象

BeanListHandler,查询到的多个数据封装成一个List<对象>

ArrayHandler

ArrayListHandler

MapHandler

MapListHandler

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值