JdbcUtils最终版(使用common-dbutil、编写TxQueryRunner、处理多线程)
我自己都很懵逼,不知道自己干了啥。
好像主要是为了分离service层和dao层的工作,还得让他们使用同一个connection。然后编写了一个TxqueryRunner进一步封装整合,最后还处理了多线程并发访问的问题。
我要疯了。
先把代码贴上,留着慢慢消化。
JDBCUtils:
package com.veeja.jdbc;
//import java.io.InputStream;
import java.sql.Connection;
//import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
//import java.util.Properties;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class JDBCUtils {
// static String driverClass = null;
// static String url = null;
// static String user = null;
// static String passwd = null;
//
// static {
// try {
// // 1. 创建一个属性配置对象
// Properties properties = new Properties();
//
// // 2. 把properties文件转化为inputstream流
//
// // 方法一:如果把properties文件放在工程的根目录下,可以使用下面的语句读取这个文件
// // InputStream is = new FileInputStream("jdbc.properties");
//
// // 方法二:使用类加载器,去读取src目录下的资源文件
// InputStream is = JDBCUtils.class.getClassLoader()
// .getResourceAsStream("jdbc.properties");
//
// // 3. 导入输入流。
// properties.load(is);
//
// // 4. 读取属性
// driverClass = properties.getProperty("driverClass");
// url = properties.getProperty("url");
// user = properties.getProperty("user");
// passwd = properties.getProperty("passwd");
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
// /**
// * 注册驱动
// */
// private static void registerDriver() {
// // DriverManager.registerDriver(new com.mysql.jdbc.Driver());
// try {
// Class.forName(driverClass);
// } catch (ClassNotFoundException e) {
// e.printStackTrace();
// }
// }
public static ComboPooledDataSource dataSource = new ComboPooledDataSource();
/** * 返回连接处建立的数据库连接 * * @return * @throws SQLException */
public static Connection getConnection() throws SQLException {
Connection connection = tl.get();
// 当connection不为null的时候表示事务已经开始了。
if (connection != null)
return connection;
return dataSource.getConnection();
// Connection conn = null;
// try {
// // 2. 建立连接 参数1:协议+访问数据库 参数2:用户名 参数3:密码
// conn = DriverManager.getConnection(url, user, passwd);
// } catch (Exception e) {
// e.printStackTrace();
// }
// System.out.println("获取数据库连接connection");
// return conn;
}
/** * 返回连接池对象 */
public DataSource getDataSource() {
return dataSource;
}
/** * 释放资源 * * @param conn * @param st * @param rs */
public static void release(Connection connection, Statement statement,
ResultSet resultSet) {
closeRs(resultSet);
closeSt(statement);
closeConn(connection);
}
// 释放ResultSet对象
private static void closeRs(ResultSet resultSet) {
System.out.println("释放ResultSet对象");
try {
if (resultSet != null) {
resultSet.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
resultSet = null;
}
}
// 释放Statement对象
private static void closeSt(Statement statement) {
System.out.println("释放Statement对象。");
try {
if (statement != null) {
statement.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
statement = null;
}
}
// 释放数据库连接。
private static void closeConn(Connection connection) {
System.out.println("释放数据库连接。");
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
connection = null;
}
}
// 事务专用连接!
private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
/** * 开启事务,获取一个connection,设置它的setAutoCommit(false)。 还要保证DAO中使用的连接使我们刚刚创建的。 * * @throws SQLException */
public static void beginTransaction() throws SQLException {
Connection connection = tl.get();
if (connection != null) {
throw new SQLException("事务已经开启了,请不要重复开启事务!");
}
// 创建一个connection,设置为手动提交
// 把这个connection给dao用
// 还要让commitTransaction或者rollbackTransaction可以获取到。
connection = getConnection();
connection.setAutoCommit(false);
tl.set(connection);// 把当前线程的连接保存起来
}
/** * 提交事务,获取beginTransaction提供的Connection,然后调用commit方法 * * @throws SQLException */
public static void commitTransaction() throws SQLException {
Connection connection = tl.get();// 获取当前线程的连接
if (connection == null) {
throw new SQLException("事务还没有开启,无法提交事务!");
}
connection.commit();
connection.close();
// 把它设置为null,表示事务已经结束了。再次调用getConnection()返回的就不是connection了
// connection = null;
tl.remove();// 从tl中移除了
}
/** * 回滚事务,获取beginTransaction提供的Connection,然后调用rollback方法 * * @throws SQLException */
public static void roolbackTransaction() throws SQLException {
Connection connection = tl.get();// 获取当前线程的连接
if (connection == null) {
throw new SQLException("事务还没有开启,无法回滚事务!");
}
connection.rollback();
connection.close();
// 把它设置为null,表示事务已经结束了。再次调用getConnection()返回的就不是connection了
// connection = null;
tl.remove();
}
/** * 释放连接 * * @param connection * @throws SQLException */
public static void releaseConnection(Connection connection)
throws SQLException {
Connection connection1 = tl.get();
/** * 判断是否为事务专用连接,如果是,就不关闭。 如果是事务专用连接,那么就要关闭连接。 */
// 如果connection=null,说明现在没有事务,那么connection一定不是事务专用连接
if (connection1 == null) {
connection1.close();
}
// 如果connection!=null ,说明事务开启了,那么需要判断是否为事务专用连接.
// 如果参数连接与connection是否相等,如果不相等,说明不是事务专用连接
if (connection1 != null) {
connection1.close();
}
}
}
TxQueryRunner
覆写父类中所有没有使用connection的方法。
package com.veeja.jdbc;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
/** * * 这个类中的方法,自己来处理连接的问题 . 无需外界传递! * 通过JdbcUtils.getConnection()得到连接! * 有可能是事务连接,也可能是普通的连接! * JdbcUtils.releaseConnection()完成对连接的释放! 如果是普通连接,关闭之! * * @author Veeja.Liu * @emial veejaliu@gmail.com * */
public class TxQueryRunner extends QueryRunner {
public int[] batch(String sql, Object[][] params) throws SQLException {
// 1.得到连接
// 2.执行父类方法,传递连接对象
// 3. 释放连接
// 4. 返回值
Connection connection = JDBCUtils.getConnection();
int[] result = super.batch(connection, sql, params);
JDBCUtils.releaseConnection(connection);
return result;
}
public Object query(String sql, Object param, ResultSetHandler rsh)
throws SQLException {
// 1.得到连接
// 2.执行父类方法,传递连接对象
// 3. 释放连接
// 4. 返回值
Connection connection = JDBCUtils.getConnection();
Object result = super.query(connection, sql, param, rsh);
JDBCUtils.releaseConnection(connection);
return result;
}
public Object query(String sql, Object[] params, ResultSetHandler rsh)
throws SQLException {
// 1.得到连接
// 2.执行父类方法,传递连接对象
// 3. 释放连接
// 4. 返回值
Connection connection = JDBCUtils.getConnection();
Object result = super.query(connection, sql, params, rsh);
JDBCUtils.releaseConnection(connection);
return result;
}
public Object query(String sql, ResultSetHandler rsh, Object[] params)
throws SQLException {
// 1.得到连接
// 2.执行父类方法,传递连接对象
// 3. 释放连接
// 4. 返回值
Connection connection = JDBCUtils.getConnection();
Object result = super.query(connection, sql, rsh, params);
JDBCUtils.releaseConnection(connection);
return result;
}
public Object query(String sql, ResultSetHandler rsh) throws SQLException {
// 1.得到连接
// 2.执行父类方法,传递连接对象
// 3. 释放连接
// 4. 返回值
Connection connection = JDBCUtils.getConnection();
Object result = super.query(connection, sql, rsh);
JDBCUtils.releaseConnection(connection);
return result;
}
public int update(String sql) throws SQLException {
// 1.得到连接
// 2.执行父类方法,传递连接对象
// 3. 释放连接
// 4. 返回值
Connection connection = JDBCUtils.getConnection();
int result = super.update(connection, sql);
JDBCUtils.releaseConnection(connection);
return result;
}
public int update(String sql, Object param) throws SQLException {
// 1.得到连接
// 2.执行父类方法,传递连接对象
// 3. 释放连接
// 4. 返回值
Connection connection = JDBCUtils.getConnection();
int result = super.update(connection, sql, param);
JDBCUtils.releaseConnection(connection);
return result;
}
public int update(String sql, Object[] params) throws SQLException {
// 1.得到连接
// 2.执行父类方法,传递连接对象
// 3. 释放连接
// 4. 返回值
Connection connection = JDBCUtils.getConnection();
int result = super.update(connection, sql, params);
JDBCUtils.releaseConnection(connection);
return result;
}
}
Dao
这里的测试并不规范。
package com.veeja.jdbc;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
public class UserDao {
public static void main(String[] args) throws SQLException {
Integer id = new Integer(1);
String name = "aaaa";
update(name, id);
}
public static void update(String name, Integer id) throws SQLException {
QueryRunner qRunner = new TxQueryRunner();
String sql = "update student set name = ? where id = ?";
Object[] params = { name, id };
qRunner.update(sql, params);
}
}
还没有评论,来说两句吧...