Java - 如何处理DAO中的JDBC连接

时间:2014-08-19 23:17:53

标签: java jdbc object-pooling

我有一个DAO,我实现了一个连接池。我使用单例实例化连接池只有一个实例。我调用getConnection函数来获取我的DAO内部的连接。我为DAO中的每个方法执行此操作?这是处理与DAO连接的好方法吗?有没有更有效的方法来设置我的池并让它与我的DAO一起工作?特别是使用JDBC。

public class SQLUserDAO implements GenericDAO<User, String, Boolean>
{

    @Override
    public void update(User user, Boolean active) throws NotFoundException
        {
            // Create the ConnectionPool:
            JDBCConnectionPool pool = JDBCConnectionPool.getPoolInstance();




            // Get a connection:
            Connection con = pool.checkOut();

            // Return the connection:
            pool.checkIn(con);
        }

    @Override
    public void delete(User user, Boolean active) throws NotFoundException
        {
            // Create the ConnectionPool:
            JDBCConnectionPool pool = JDBCConnectionPool.getPoolInstance();

            // Get a connection:
            Connection con = pool.checkOut();

            // Return the connection:
            pool.checkIn(con);

        }

    @Override
    public User findByKey(String key, Boolean active) throws NotFoundException
        {
            // Create the ConnectionPool:
            JDBCConnectionPool pool = JDBCConnectionPool.getPoolInstance();

            // Get a connection:
            Connection con = pool.checkOut();

            // Return the connection:
            pool.checkIn(con);
            return null;
        }

    @Override
    public User findByValue(User object, Boolean active)
            throws NotFoundException
        {
            // Create the ConnectionPool:
            JDBCConnectionPool pool = JDBCConnectionPool.getPoolInstance();

            // Get a connection:
            Connection con = pool.checkOut();

            // Return the connection:
            pool.checkIn(con);
            return null;
        }

    @Override
    public void insert(User user, Boolean active) throws NotFoundException
        {
            // Create the ConnectionPool:
            JDBCConnectionPool pool = JDBCConnectionPool.getPoolInstance();

            // Get a connection:
            Connection conn = pool.checkOut();

            PreparedStatement preparedStatement;

            try
            {
                preparedStatement = conn
                        .prepareStatement("INSERT INTO users(user_id, user_name, user_password) VALUES (?,?,?)");

                preparedStatement.setString(1, user.getUserId().toString());
                preparedStatement.setString(2, user.getUserName());
                preparedStatement.setString(3, user.getClearTextPassword());

                // execute insert SQL stetement
                preparedStatement.executeUpdate();
            }
            catch (SQLException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            // Return the connection:
            pool.checkIn(conn);
        }
}

ObjectPool的

public abstract class ObjectPool<T>
{
    private long expirationTime;
    private Hashtable<T, Long> locked, unlocked;

    public ObjectPool()
    {
        expirationTime = 30000; // 30 seconds
        locked = new Hashtable<T, Long>();
        unlocked = new Hashtable<T, Long>();
    }

    protected abstract T create();

    public abstract boolean validate(T o);

    public abstract void expire(T o);

    public synchronized T checkOut()
        {
            long now = System.currentTimeMillis();
            T t;
            if (unlocked.size() > 0)
            {
                Enumeration<T> e = unlocked.keys();
                while (e.hasMoreElements())
                {
                    t = e.nextElement();
                    if ((now - unlocked.get(t)) > expirationTime)
                    {
                        // object has expired
                        unlocked.remove(t);
                        expire(t);
                        t = null;
                    }
                    else
                    {
                        if (validate(t))
                        {
                            unlocked.remove(t);
                            locked.put(t, now);
                            return (t);
                        }
                        else
                        {
                            // object failed validation
                            unlocked.remove(t);
                            expire(t);
                            t = null;
                        }
                    }
                }
            }
            // no objects available, create a new one
            t = create();
            locked.put(t, now);
            return (t);
        }

    public synchronized void checkIn(T t)
        {
            locked.remove(t);
            unlocked.put(t, System.currentTimeMillis());
        }
}

连接池

public class JDBCConnectionPool extends ObjectPool<Connection>
{
private String dsn, usr, pwd;

private JDBCConnectionPool()
{
    super();

    try
    {
        Properties p = new Properties();
        FileInputStream input = new FileInputStream(
                "src/dbproperties");
        p.load(input);
        String driver = p.getProperty("driver");
        this.dsn = p.getProperty("url");
        this.usr = p.getProperty("user");
        this.pwd = p.getProperty("password");

        DriverManager
                .registerDriver((oracle.jdbc.driver.OracleDriver) Class
                        .forName(driver).newInstance());

        input.close();

    }
    catch (FileNotFoundException e)
    {
        e.printStackTrace();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
    catch (InstantiationException e)
    {

        e.printStackTrace();
    }
    catch (IllegalAccessException e)
    {

        e.printStackTrace();
    }
    catch (SQLException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    catch (ClassNotFoundException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

private static class LazySingleton
{
    private static final JDBCConnectionPool SINGLETONINSTANCE = new JDBCConnectionPool();
}

public static JDBCConnectionPool getPoolInstance()
    {
        return LazySingleton.SINGLETONINSTANCE;
    }

@Override
protected Connection create()
    {
        try
        {
            return (DriverManager.getConnection(dsn, usr, pwd));
        }
        catch (SQLException e)
        {
            e.printStackTrace();
            return (null);
        }
    }

@Override
public void expire(Connection o)
    {
        try
        {
            ((Connection) o).close();
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
    }

@Override
public boolean validate(Connection o)
    {
        try
        {
            return (!((Connection) o).isClosed());
        }
        catch (SQLException e)
        {
            e.printStackTrace();
            return (false);
        }
    }

}

1 个答案:

答案 0 :(得分:2)

  1. 实现自己的连接池,如Not invented here反模式;有很多强大的库,例如DBCP。重塑这个的任何深刻理由?
  2. 为什么代码中的pool不是DAO类的实例字段,而是每个方法中的局部变量?
  3. 你编码的DAO,也没有任何状态;使它成为单身人士(除了连接池)。您可以将连接池传递给DAO的构造函数。
  4. 继续讨论最后一点:为什么不使用已建立的DataSource类型作为DAO构造函数的参数? DataSource可以轻松隐藏任何池化逻辑。
  5. 即使您不希望像IoC框架这样的完整解决方案来实例化和连接您的类,您也可以查看Spring的JdbcTemplate。它可以帮助您避免资源泄漏,并且设计得非常好。