前提条件: 1 使用连接池 2 使用了spring的ioc,即DAO是单例的 提出这个问题是由于我们系统中的实际出现的状况 由于开发人员众多,素质参差不齐,开发时间紧迫, 出现了大量的不符合规范的代码以及错误代码. 常见的就是 在关闭链接的时候没有关闭链接的创建的所有的Statement (关闭了部分,但不是所有) 所以想和 大家探讨一下该如何在代码层次实现关闭数据库链接时,自动关闭由该链接创建的所有的Statement. 我的思路是这样的 将"当前线程+当前链接"创建的所有Statement 放入一个ThreadLocal 对象内. 当关闭链接时, 从ThreadLocal 对象取出 所有的 Statement ,逐个关闭. 不知道这样的思路是否可行. 下面附上代码: 为了阅读方便没有写出全部的创建Statement的方法
代码
-
- public class ConnectionUtils {
- public static final ThreadLocal statementMap = new ThreadLocal();
-
- public static void initStatementMap(Connection conn){
- String key=String.valueOf(conn);
- Map map=(Map)statementMap.get();
- if (map==null){
- map=Collections.synchronizedMap(new HashMap());
- statementMap.set(map);
- }
- if (map.get(key)==null) {
- map.put(key, new ArrayList());
- }
- }
-
- public static void putStatement(Connection conn,Statement statement){
- Map map=(Map)statementMap.get();
- List list=(List)map.get(conn.toString());
- list.add(statement);
- }
-
- public static void closeAllStatement(Connection conn){
- Map map=(Map)statementMap.get();
- List list=(List)map.get(conn.toString());
- for (Iterator itor=list.iterator();itor.hasNext();){
- Statement stm=(Statement)itor.next();
- try {
- stm.close();
- } catch (SQLException e) {
- }
- }
- }
-
- public static Statement createStatement(Connection conn) throws SQLException{
- Statement statement=conn.createStatement();
- putStatement(conn,statement);
- return statement;
- }
-
-
- public static CallableStatement prepareCall(Connection conn, String sql) throws SQLException {
- CallableStatement statement=conn.prepareCall(sql);
- putStatement(conn,statement);
- return statement;
- }
-
- public static PreparedStatement prepareStatement(Connection conn, String sql) throws SQLException{
- PreparedStatement statement= conn.prepareStatement(sql);
- putStatement(conn,statement);
- return statement;
- }
-
- }
<script type="text/javascript">render_code();</script> 在dao内的getConnection时 可以这么写
代码
- protected final Connection getConnection(){
- Connection conn=DataSourceUtils.getConnection(getDataSource());
- ConnectionUtils.initStatementMap(conn);
- return conn;
- }
<script type="text/javascript">render_code();</script> 关闭Connection时 可以这么写
代码
- protected final void closeConnection(Connection conn) {
- ConnectionUtils.closeAllStatement(conn);
- DataSourceUtils.releaseConnection(conn, getDataSource());
- }
<script type="text/javascript">render_code();</script> 要创建Statement时可以这么写
代码
- pstmt = ConnectionUtils.prepareStatement(conn,bufSql.toString());
<script type="text/javascript">render_code();</script> |