日期:2014-05-20  浏览次数:20699 次

【学习&讨论】一个类设计的问题,不看的一定后悔,大家一起学习!
请问下面两种方式有何区别,各自的优点和缺点是什么?

//第一种,为每个方法创建一个Connection
public   class   TestA
{
private   Connection   getConnection()
{
Class.forName( "... ");
Connection   conn   =   DriverManager.getConnection( "... ");
return   conn;
}

public   void   methodA()
{
Connection   conn   =   getConnection();
...
conn.close();
}

                  public   void   methodB()
{
Connection   conn   =   getConnection();
...
conn.close();
}
}

//第二种,创建一个Connection实例变量,供所有的方法调用
public   class   TestB
{
private   Connection   conn;

public   Test()
{
Class.forName( "... ");
this.conn   =   DriverManager.getConnection( "... ");
}

public   void   methodA()
{
...
Statement   st   =   this.conn.createStatement();
...
this.conn.close();
}

                  public   void   methodB()
{
...
Statement   st   =   this.conn.createStatement();
...
this.conn.close();
}
}

------解决方案--------------------
第一种,方法之间使用独立的数据库连接,
第二种,设计上存在问题,methodA和methodB应该是共享一个连接,但是又在调用各自方法之后把连接给关闭了,下一个方法调用的时候连接已经关闭,数据库操作明显会出错,数据库连接的关闭操作应该独立出来,也不是由methodA和methodB来调用(既然他们也没有创建连接),有点数据库连接池的味道,只不过只有一个连接
------解决方案--------------------
第一种方法每次调用都要建立连接,比较消耗时间,所以一般都是建立一个连接后重复使用,就是你的第二种方法. 不过this.conn.close();应该去掉,放到finally块中关闭连接
------解决方案--------------------
第二种方法完全错误,同一个连接建立一次关闭多次,
第一种是对的,但是有性能问题,建议使用连接池
------解决方案--------------------
001 import java.io.*;
002 import java.sql.*;
003 import java.util.*;
004 import java.util.Date;
005
006 /**
007 * 管理类DBConnectionManager支持对一个或多个由属性文件定义的数据库连接
008 * 池的访问.客户程序可以调用getInstance()方法访问本类的唯一实例.
009 */
010 public class DBConnectionManager {
011 static private DBConnectionManager instance; // 唯一实例
012 static private int clients;
013
014 private Vector drivers = new Vector();
015 private PrintWriter log;
016 private Hashtable pools = new Hashtable();
017
018 /**
019 * 返回唯一实例.如果是第一次调用此方法,则创建实例
020 *
021 * @return DBConnectionManager 唯一实例
022 */
023 static synchronized public DBConnectionManager getInstance() {
024 if (instance == null) {
025 instance = new DBConnectionManager();
026 }
027 clients++;
028 return instance;
029 }
030
031 /**
032 * 建构函数私有以防止其它对象创建本类实例
033 */
034 private DBConnectionManager() {
035 init();
036 }
037
038 /**
039 * 将连接对象返回给由名字指定的连接池
040 *
041 * @param name 在属性文件中定义的连接池名字
042 * @param con 连接对象
043 */
044 public void freeConnection(String name, Connection con) {
045 DBConnectionPool pool = (DBConnectionPool) pools.get(name);
046 if (pool != null) {
047 pool.freeConnection(con);
048 }
049 }
050
051 /**
052 * 获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数
053 * 限制,则创建并返回新连接
054 *
055 * @param name 在属性文件中定义的连接池名字
056 * @return Connection 可用连接或null
057 */
058 public Connection getConnection(String name) {