事务 与 数据库连接池【c3p0】 与 DBUtiles学习笔记

1.事务

开启事务:start transaction;
回滚事务:rollback;
提交事务: commit;
关闭自动提交事务:setAutoCommit(false);
1.1事务的特性ACID【面试】
1.原子性【A】:事务包含的逻辑不可分割
一致性【C】:事务执行前后,数据完整性
隔离性【I】 :事务执行期间不受其他事务影响
持久性【D】:事务执行成功,则数据永久保存到磁盘上;
1.1.2.事务的安全隐患:
不考虑隔离级别设置:
【读】:
1.脏读:>>>一个事务读到另外一个事务还未提交的数据;
2.不可重复读:>>>一个事务读到了另外一个事务提交的数据,造成两次查询结果不一致;>>>解决:重复读:repeatable read;【默认】
3.幻读:一个事务读到另外一个事务已提交插入的数据,导致多次查询结果不一致。>>>>解决:Serializable【可串行化】最高级别
四个隔离级别的效率从高到低排列:
读未提交>读已提交>可重复读>可串行化
拦截程度相反

【写】:丢失更新
>>>解决:1.悲观锁;
======== 2.乐观锁

【mysql默认隔离级别:可重复读】
【oracle默认隔离级别:读已提交】
1.1.3在代码中使用事务的步骤

Connection conn = JDBCUtil.getConn();
conn.setAutoCommit(false);//关闭事务的自动提交
.....
conn.commit();//提交
conn.roolback();//回滚

2.数据库连接池

2.1DBCP连接池【了解】
dbcp创建dataSource方式:

BasicDataSource dataSource = new BasicDataSource();

2.1.1使用代码方式连接【了解】
将数据插入到bank下的account表中

public class demo1 {
	@Test
	public void dbcp(){
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			//1.构建数据源对象
			BasicDataSource dataSource = new BasicDataSource();
			dataSource.setDriverClassName("com.mysql.jdbc.Driver");
			dataSource.setUrl("jdbc:mysql://localhost/bank");
			dataSource.setUsername("root");
			dataSource.setPassword("123456");
			//2.获得连接对象
			conn = dataSource.getConnection();
			String sql = "insert into account values(null,?,?)";
			ps = conn.prepareStatement(sql);
			ps.setString(1, "admin");
			ps.setInt(2, 20000);
			ps.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			JDBCUtil.release(conn, ps);
		}
	}
}

2.1.2使用配置文件方式

2.2 c3p0连接池【掌握】
c3p0创建dataSource连接方式:

ComboPooledDataSource dataSource = new ComboPooledDataSource();

2.2.1代码连接【了解】

public class demo1 {
	@Test
	public void c3p0() throws PropertyVetoException{
		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/bank");
			dataSource.setUser("root");
			dataSource.setPassword("123456");
			
			
			conn = dataSource.getConnection();
			String sql = "insert into account values(null,?,?)";
			ps = conn.prepareStatement(sql);
			ps.setString(1, "aaa");
			ps.setInt(2, 12000);
			ps.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			JDBCUtil.release(conn, ps);
		}
	}
}

2.2.2c3p0配置文件连接方式【★掌握】
c3p0-config.xml的源文件

<c3p0-config>
  <default-config>
    <property name="automaticTestTable">con_test</property>
    <property name="checkoutTimeout">30000</property>
    <property name="idleConnectionTestPeriod">30</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>

    <user-overrides user="test-user">
      <property name="maxPoolSize">10</property>
      <property name="minPoolSize">1</property>
      <property name="maxStatements">0</property>
    </user-overrides>

  </default-config>

  <!-- This app is massive! -->
  <named-config name="intergalactoApp"> 
    <property name="acquireIncrement">50</property>
    <property name="initialPoolSize">100</property>
    <property name="minPoolSize">50</property>
    <property name="maxPoolSize">1000</property>

    <!-- intergalactoApp adopts a different approach to configuring statement caching -->
    <property name="maxStatements">0</property> 
    <property name="maxStatementsPerConnection">5</property>

    <!-- he's important, but there's only one of him -->
    <user-overrides user="master-of-the-universe"> 
      <property name="acquireIncrement">1</property>
      <property name="initialPoolSize">1</property>
      <property name="minPoolSize">1</property>
      <property name="maxPoolSize">5</property>
      <property name="maxStatementsPerConnection">50</property>
    </user-overrides>
  </named-config>
</c3p0-config>

所以我们在定义c3p0配置文件时必须也使用c3p0-config.xml这个名字
在这里插入图片描述
c3p0-config.xml

<?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/bank</property>
    <property name="user">root</property>
    <property name="password">123456</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>

c3p0_demo2.java

public class c3p0_demo2 {
	@Test
	public void test(){
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			ComboPooledDataSource dataSource = new ComboPooledDataSource();
			//获得连接对象
			conn = dataSource.getConnection();
			String sql = "insert into account values(null,?,?)";
			ps = conn.prepareStatement(sql);
			ps.setString(1, "c3p0");
			ps.setInt(2, 18000);
			ps.executeUpdate();//执行
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			JDBCUtil.release(conn, ps);//释放
		}
	}
}

运行后数据库情况
在这里插入图片描述
这里就把数据插进来了。
【特别注意】xml文件的命名一定是:c3p0-config.xml,否则就会执行失败

3.DBUtiles

QueryRunner

//1.c3p0创建连接
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//2.dbUtil只是简化CRUD的代码,但是不可以创建连接
QueryRunner run = new QueryRunner(dataSource);

两个常用的方法:
1.queryRunner.update();//增删改
2.queryRunner.query();//查询
3.1DBUtiles里的增删改
dbUtil只是简化CRUD的代码,但是不可以创建连接

public class Tset {
	@Test
	public void testInsert() throws SQLException{
		//1.c3p0创建连接
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		//2.dbUtil只是简化CRUD的代码,但是不可以创建连接
		QueryRunner run = new QueryRunner(dataSource);
		String sql = "insert into account values(null,?,?)";
		//3.增加
		run.update(sql, "dbutil",230000);
		//4.删除
		run.update("delete from account where id = ?", 8);
		//5.更新
		run.update("update account set money=? where id=?", 20000,4);
	}
}

3.2DBUtiles通用的增删改方法
通过元数据获取有几个?(即占位符)

	ParameterMetaData metaData = ps.getParameterMetaData();
	int count = metaData.getParameterCount();
public void test(){
		update("insert into account values(null,?,?)", "common",100000);
	}
	
public class CommonUtil {
	public void update(String sql,Object...args){
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			conn = JDBCUtil.getConn();
			ps = conn.prepareStatement(sql);
			ParameterMetaData metaData = ps.getParameterMetaData();//获取元数据
			int count = metaData.getParameterCount();//获取个数,这里获取?的个数
			
			for (int i = 0; i < count; i++) {
				ps.setObject(i+1, args[i]);
			}
			ps.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			JDBCUtil.release(conn, ps);
		}
	}
}

3.3DBUtiles里的查询
这里用到泛型,现在Domain层建立一个Account类:
生成set,get方法,重写String

private String name;
private int money;

(一)代码实现
在这里插入图片描述
1.查询单条数据
new BeanHandler<‘T’>(class文件);

public class Select {
	@Test
	public void selectDemo() throws SQLException{
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		QueryRunner runner = new QueryRunner(dataSource);
		//查询单条数据
		Account account = runner.query("select * from account where id=?",
					new BeanHandler<Account>(Account.class), 9);
		System.out.println(account);
	}
}
Account [name=dbutil, money=230000]

2.查询多条数据
new BeanListHandler<‘T’>(class);

public class Select {
	@Test
	public void selectDemo() throws SQLException{
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		QueryRunner runner = new QueryRunner(dataSource);
		//查询单条数据
	List<Account> list= runner.query("select * from account",
					new BeanListHandler<Account>(Account.class));
		System.out.println(list);
	}
}
[Account [name=张三, money=23000], Account [name=李四, money=25000], Account [name=admin, money=20000], Account [name=aaa, money=20000], Account [name=c3p0, money=18000], Account [name=dbutil, money=230000], Account [name=dbutil, money=230000], Account [name=dbutil, money=230000], Account [name=dbutil, money=230000]]

猜你喜欢

转载自blog.csdn.net/stack_xman/article/details/83782153