//C3P0 数据库连接池,方式一
@Test
public void test1() throws Exception{
ComboPooledDataSource ds = new ComboPooledDataSource();
ds.setDriverClass("com.mysql.jdbc.Driver");
ds.setJdbcUrl("jdbc:mysql://localhost:3306/test");
ds.setUser("root");
ds.setPassword("123456");
ds.setMaxPoolSize(10);
ds.setAcquireIncrement(3);
Connection conn = ds.getConnection();
System.out.println(conn);
conn.close();
}
//C3P0 数据库连接池,方式二
@Test
public void test2() throws Exception{
DataSource ds = new ComboPooledDataSource("helloc3p0");
Connection conn = ds.getConnection();
System.out.println(conn);
}
代码段二中采用c3p0数据库连接池的是加载配置文件的方式创建数据库连接池的,配置文件名字必须统一叫做c3p0-config.xml,还要加载.jar文件,方法如下:
c3p0-config.xml的内容:
//DBCP 数据库连接池,方式一:
@Test
public void test3() throws Exception{
BasicDataSource bds = new BasicDataSource();
bds.setDriverClassName("com.mysql.jdbc.Driver");
bds.setUrl("jdbc:mysql://localhost:3306/test");
bds.setUsername("root");
bds.setPassword("123456");
bds.setInitialSize(10);
bds.setMaxActive(10);
Connection conn = bds.getConnection();
System.out.println(conn);
}
//DBCP 数据库连接池,方式二:
@Test
public void test4() throws Exception{
Properties props = new Properties();
props.load(this.getClass().getClassLoader().getResourceAsStream("com/gome/day1/properties"));
DataSource ds = BasicDataSourceFactory.createDataSource(props);
Connection conn = ds.getConnection();
System.out.println(conn);
}
上边代码块二的方式是DBCP数据库连接池加载资源文件的方式,先加载两个.jar文件,在添加资源文件。properties详情如下:
需要注意的是,使用类加载器的方式加载资源文件,资源文件交放在包下与代码同一级别,并且资源文件中key的名字要严格按照方法中的名字取,不然无法成功。
下列程序在两次更新数据库表中数据的中间模拟故障,用来测试commit与rollback的作用:
public class TestTransaction {
// 模拟:
@Test
public void test1(){
Connection conn = null;
try {
conn = JDBCUtils.getConnection();
conn.setAutoCommit(false); //取消自动提交,事务开启
String sql1 = "update user_table set balance = balance - 100 where user = ?";
update(conn, sql1, "AA");
//模拟故障
// int num = 10 / 0;
String sql2 = "update user_table set balance = balance + 100 where user = ?";
update(conn, sql2, "BB");
conn.commit(); //提交
} catch (Exception e) {
e.printStackTrace();
//回滚
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
JDBCUtils.close(null, null, conn);
}
}
/*
* 考虑事务的通用查询
*/
public
T t = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
rs = ps.executeQuery();
// 获取当前结果集的元数据
ResultSetMetaData rsmd = rs.getMetaData();
// 获取结果集的列数
int columnCount = rsmd.getColumnCount();
if (rs.next()) {
t = clazz.newInstance();
for (int i = 0; i < columnCount; i++) {
// 获取列名
String columnName = rsmd.getColumnLabel(i + 1);
// 根据列名获取对应列的数据
Object columnValue = rs.getObject(columnName);
Field field = clazz.getDeclaredField(columnName);// 注意:必须保证结果集中列名(别名),与属性名称保持一致!!!!!
field.setAccessible(true);// 忽略访问权限
field.set(t, columnValue);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(rs, ps, null);
}
return t;
}
/*
* 考虑事务的,通用的增、删、改方法,适用于任何表
*/
public int update(Connection conn, String sql, Object... args) {
// 2. 获取 PreparedStatement , 用于发送 SQL
PreparedStatement ps = null;
// 4. 执行 SQL
int row = 0;
try {
ps = conn.prepareStatement(sql);
// 3. 填充占位符
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
row = ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 5. 关闭连接
JDBCUtils.close(ps, null);
}
return row;
}
}
public class TestDBUtils {
private QueryRunner qr = new QueryRunner();
//获取特殊某个值
@Test
public void test6(){
Connection conn = null;
try {
conn = JDBCUtils.getConnectionForC3P0();
String sql = "select count(*) from customers";
ResultSetHandler