2
回答
请问这样使用C3P0,可行吗?
华为云实践训练营,热门技术免费实践!>>>   

这是数据库管理的类,模仿红薯老大的写法:

package mis2.db;

import java.sql.Connection;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.beanutils.BeanUtils;

import com.mchange.v2.c3p0.PooledDataSource;

public class DBManager {

	// ThreadLocal变量
	private final static ThreadLocal<Connection> conns = new ThreadLocal<Connection>();
	// 数据源
	private static DataSource dataSource;

       //  只调用一次 InitDataSource()方法
	static {
		InitDataSource(); // 初始化连接池
	}

        // 初始化连接池
	private final static void InitDataSource() {
		try {
			Properties dbProperties = new Properties();
			dbProperties.load(DBManager.class
					.getResourceAsStream("db.properties"));
			Properties cp_props = new Properties(); // c3p0的Properties
			for (Object key : dbProperties.keySet()) {
				String skey = (String) key; // 取得属性名
				if (skey.startsWith("jdbc.")) {
					String name = skey.substring(5);
					cp_props.put(name, dbProperties.getProperty(skey));
				}

			}
			dataSource = (DataSource) Class.forName(
					cp_props.getProperty("datasource")).newInstance();
			if (dataSource.getClass().getName().indexOf("c3p0") > 0) {
				// Disable JMX in C3P0
				System.setProperty("com.mchange.v2.c3p0.management.ManagementCoordinator",
								"com.mchange.v2.c3p0.management.NullManagementCoordinator");
			}

			BeanUtils.populate(dataSource, cp_props);

			System.out.println("初始化连接池完成.");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

        // 获取一个连接
	public final static Connection GetConnection() {
		Connection conn = conns.get();
		try {
			if (conn == null || conn.isClosed()) {
				conn = dataSource.getConnection();
				conns.set(conn);
				System.out.println("获取一个连接.");
				PooledDataSource pds = (PooledDataSource)dataSource;
				System.out.println("当前连接数量: " + pds.getNumConnections());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return conn;
	}

       // 关闭连接
	public final static void CloseConnection() {
		Connection conn = conns.get();
		try {
			if (conn != null && !conn.isClosed()) {
				conn.setAutoCommit(true);
				conn.close();
				System.out.println("关闭一个连接.");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		conns.set(null);
	}

      // 关闭连接池
	public final static void CloseDataSource() {
		try {
			dataSource.getClass().getMethod("close").invoke(dataSource);
			System.out.println("关闭连接池.");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
     

然后在程序里通过这样来获取连接:

DBManager.GetConnection();

现在的问题是,

(1)在使用语句DBManager.GetConnection();获取连接后,是不是不需要关闭数据库,只需要在某个地方调用一次DBManager.CloseConnection();就可以了?

(2)在哪里调用CloseDataSource()这个方法呢?

举报
坚持_执着
发帖于6年前 2回/703阅
共有2个答案 最后回答: 6年前

使用完 Connection 一定要调用  conn.close() 方法告诉连接池不再占有该连接,无需调用 CloseConnection() 方法

closeDataSource 方法是在整个应用停止时调用,可在过滤器的 destory 方法中调用

引用来自“鉴客”的答案

使用完 Connection 一定要调用  conn.close() 方法告诉连接池不再占有该连接,无需调用 CloseConnection() 方法

closeDataSource 方法是在整个应用停止时调用,可在过滤器的 destory 方法中调用

“使用完 Connection 一定要调用  conn.close() 方法告诉连接池不再占有该连接,无需调用 CloseConnection() 方法”,这句话的意思是说我必须像这样使用吗:

Connection conn = DBManager.GetConnection();
conn.close();

但是 CloseConnection()何时调用呢?还是说 CloseConnection()的功能就是conn.close();呢?

顶部