使用连接池的数据库工具类

 

照书上抄了一个封装JDBC的数据库工具类,没想到用的时候出了很多问题,

它当初使用的环境是JDBC直连的方式,现在我稍加修改换成了数据库连接池,

结果错误百出,查找这些错误耗费了我几天的时间,刚开始报错说:

Statement 对象已关闭,我很奇怪为什么会自动关闭,后来发现是在代码中调用了

下面的stop()方法手动关闭的,于是就将其注释掉了,但是同样的错误依旧,

 

最后才发现原因:原来开在一个业务逻辑类中我忘了注释stop(),代码执行到此

仍然关闭了Connection和Statement的引用,这个。。这个纯属个人疏忽所致。。。汗!

 

不过让我不解的是,将代码中所有的stop()方法都注释掉之后,就再也没问题了,可转念一想,这些连接难道都不需要关闭吗?那这个stop()方法岂不是没用处了啊,那还写它干吗?

跟踪调试过程中发现,一旦执行stop(),就会使conn==null,然后第二次调用DataStore ds=DataStore.getInstance();时只是判断static DataStore db 是否为 null;若为空再新建一个Connection,但事实上db并不为空,于是在以后的代码中调用conn就会报NullPointEsception,调用stmt就会报 已经关闭的Exception.

我知道问题一定出在这个private static DataStore db  上,可又不知道怎么修改,总不能在stop()中吧db也=null了吧?但是如果不使用stop()释放数据库资源,那么我的连接池又有什么用那?在并发处理时如何解决,总不能靠那一个Connection连接吧??

 

package org.database;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.naming.InitialContext;
import javax.sql.DataSource;

/* 封装JDBC的主要数据库操作:CRUD与事务操作,实现数据库访问层与业务逻辑层的分离 */
/* 使用举例:
 * 1.插入,删除,更新
 * String sql="delete from uesr";
 *   先获取数据库访问实例
 * DataStore ds=DataStore.getInstance();
 * try{
 *     ds.execute(sql);
 *   }catch(Exception e){
 *    ....}
 * 2.读取操作
 * String sql="select * from user";
 *   获取实例
 * DataStore ds=DataStore.getInstance();
 * try{
 *     ResultSet rs=ds.read(sql);
 *     ...   
 *    }catch(Exception e){
 *     ....}   
 * 3.事务操作
 *  DataStore ds=DataStore.getInstance();
 *  ds.beginTransaction();
 *  String sql_1="delete * from user";
 *  String sql_2="insert into user values('username','password')";
 *  try{
 *       ds.execute(sql_1);
 *       ds.execute(sql_2);
 *      }catch(Exception e){
 *         ds.ErrorOccur();
 *      }    
 *  ds.commitTransaction();
 */

public class DataStore
{
 // 静态工厂模式
 private static DataStore db   = null;
 // 数据库连接对象
 private static Connection conn  = null;
 private Statement   stmt  = null;
 private boolean    haddErrors = false;

 // 构造函数
 private DataStore() throws Exception
 {
  if (conn == null)
  {
   // 从数据源获得连接
   InitialContext ctx = new InitialContext();
   DataSource ds = (DataSource) ctx
     .lookup("java:comp/env/jdbc/webmail");
   conn = ds.getConnection();
   stmt = conn.createStatement();
  }
 }

 // 取得DataStore实例, 工厂方法
 public static DataStore getInstance()
 {
  if (db == null)
  {
   try
   {
    db = new DataStore();
   }
   catch (Exception e)
   {
    conn = null;
    // 日志处理
    System.out.println("----取得DataStore实例出错---");
    e.printStackTrace();
   }
  }
  return db;
 }

 // 发起事务
 public void beginTransaction() throws SQLException
 {
  //System.out.println(conn.isClosed());
  if (conn != null) // 不是必需的,非问题关键所在
  conn.setAutoCommit(false);// 应用JDBC事务,设置为非自动提交
 }

 // 执行事务
 public void commitTransaction() throws SQLException
 {
  if (!haddErrors)
  {
   conn.commit();
  }
  else
  {
   conn.rollback();
   haddErrors = false;
  }
  haddErrors = false;
  conn.setAutoCommit(true);
 }

 // 标记出错
 public void ErrorOccur()
 {
  haddErrors = true;
 }

 // 执行插入,删除和修改操作
 synchronized public void execute(String sql) throws SQLException
 {
  // if (conn!= null) stmt = conn.createStatement();
  if (stmt != null) stmt.executeUpdate(sql);
  else
  {
   // 日志处理
   System.out.println("数据库插入出错!");
  }
 }

 // 查询操作
 synchronized public ResultSet read(String sql) throws SQLException
 {
  if (stmt != null)
  {
   ResultSet tmp = null;
   tmp = stmt.executeQuery(sql);
   return tmp;
  }
  else
  {
   return null;
  }
 }

 // 查询个数操作
 synchronized public int readCount(String sql) throws SQLException
 {
  int nCount = 0;
  try
  {
   if (stmt != null)
   {
    ResultSet tmp = null;
    tmp = stmt.executeQuery(sql);
    if (tmp != null && tmp.next()) nCount = tmp.getInt(1);
    else
     nCount = 0;
   }
   else
    nCount = 0;

  }
  catch (SQLException e)
  {
   return nCount;
  }
  return nCount;
 }

 // 终止数据库连接
 synchronized public void stop()
 {
  try
  {

   if (stmt != null)
   {
    stmt.close();
   }
   if (conn != null)
   {
    conn.close();
   }
  }
  catch (Exception e)
  {
   // 记录日志
   System.out.println("数据库关闭出错!");
   e.printStackTrace();
  }
  finally
  {
   conn = null;
  }
 }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值