我们都知道在javaee实际开发中,分为3层结构来开发,controller,service和dao
那么为什么事物要存在于业务层中,事物是通过connection对象操作的,使用原始jdbc链接数据库的链接也是connection操作的,connection是在到是怎么传递到dao的呢?
这里讲解两种方式
第一种通过形式参数的方式
第二种通过ThreadLocal的方式
ThreadLocal的底层是个map,该map的key是固定的,当前线程。value可以让我们存入任意对象
public class JdbcUtils {
// 成员变量,创建了C3P0的连接池(连接池中已经存在连接了...)
private static final ComboPooledDataSource DATASOURCE = new ComboPooledDataSource();
// 把Connection绑定到当前的线程中
private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
public static DataSource getDataSource(){
return DATASOURCE;
}
public static Connection getConnection() throws SQLException{
Connection conn = null;
// 从tl中获取
conn = tl.get();
if(conn == null){
// 从连接池中获取连接
conn = DATASOURCE.getConnection();
// 非常关键,把连接存入到tl中
tl.set(conn);
}
return conn;
}
public static void beginTransaction() throws SQLException{
// 调用getConnection()
Connection conn = getConnection();
conn.setAutoCommit(false);
}
public static void commitTransaction() throws SQLException{
// 调用getConnection()
Connection conn = getConnection();
conn.commit();
}
public static void rollBackTransaction() throws SQLException{
// 调用getConnection()
Connection conn = getConnection();
conn.rollback();
}
public static void closeConn() throws SQLException{
// 调用getConnection()
Connection conn = getConnection();
conn.close();
tl.remove();
}
public static void release(Statement stmt,Connection conn){
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
// 已经变成了归还了...
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void release(ResultSet rs,Statement stmt,Connection conn){
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
// 把close()给修改了,原来是销毁连接,现在让方法变成归还连接。
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}