注:有些java类是JDK没有的,请到 http://www.findjar.com/index.x 中查找对应的jar包
1. 数据库配置文件 (放在工程的 classpath 下)
database.properties
## oracle ## #c3p0.driver=oracle.jdbc.driver.OracleDriver #c3p0.url=jdbc:oracle:thin:@192.168.1.49:1523:DB02 ## DB2 ## c3p0.driver=com.ibm.db2.jcc.DB2Driver c3p0.url=jdbc:db2://172.20.15.174:50000/test c3p0.user=admin c3p0.password=admin c3p0.initialPoolSize=15 #连接池中保留的最大连接数 c3p0.maxPoolSize=20 #连接池中保留的最小连接数 c3p0.minPoolSize=10 #最大空闲时间,n秒内未使用则连接被丢弃。若为0则永不丢弃 c3p0.maxIdleTime=60 #获得连接的最大等待毫秒数(两次连接中间隔时间) c3p0.acquireRetryDelay=1000 #当连接池中的连接耗尽的时候c3p0一次同时获取的连接数 c3p0.acquireIncrement=15 #定义在从数据库获取新连接失败后重复尝试的次数 c3p0.acquireRetryAttempts=30 #连接关闭时默认将所有未提交的操作回滚 c3p0.autoCommitOnClose=false #连接池内单个连接所拥有的最大缓存statements数 c3p0.maxStatementsPerConnection=100 #通过多线程实现多个操作同时被执行 c3p0.numHelperThreads=10 ### DPCP ### #最大等待秒数,单位为毫秒, 超过时间会报出错误信息 dpcp.maxwait=60000
2. 配置文件解析类
import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import org.apache.log4j.Logger; /** * @ClassName: ParsePropertiesFile * @Description: 解析属性文件(*.properties) * @author * @company * @date 2012-11-8 * @version V1.0 */ public final class ParsePropertiesFile { private static final Logger LOG = Logger .getLogger(ParsePropertiesFile.class); private static final ParsePropertiesFile instance = new ParsePropertiesFile(); private ParsePropertiesFile() { } public static ParsePropertiesFile getInstance() { return instance; } /** * @Title: getConfig * @Description: 解析并读取属性文件(*.properties) * @param propFile * 属性文件路径 * @return:Map * @author * @date 2012-11-8 */ public Map<String, String> getConfig(String propFile) { InputStream is = null; try { is = this.getClass().getClassLoader().getResourceAsStream(propFile); Properties prop = new Properties(); prop.load(is); Set<Entry<Object, Object>> set = prop.entrySet(); Iterator<Entry<Object, Object>> it = set.iterator(); String key = null, value = null; Entry<Object, Object> entry = null; while (it.hasNext()) { entry = it.next(); key = String.valueOf(entry.getKey()).trim(); value = String.valueOf(entry.getValue()).trim(); CommonConstants.propMap.put(key, value); } } catch (IOException e) { LOG.error("parse properties file '"+propFile+"' fail!", e); } catch (Exception e) { LOG.error("parse properties file '"+propFile+"' fail!", e); } IOUtil.closeStream(is, null); return CommonConstants.propMap; } }
3. IOUtil
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import org.apache.log4j.Logger; public final class IOUtil { private static final Logger LOG = Logger.getLogger(IOUtil.class); private IOUtil() { } public static void closeReader(Reader reader) { if (null != reader) { try { reader.close(); reader = null; } catch (IOException e) { LOG.error("close reader faile!", e); } } } public static void closeStream(InputStream is, OutputStream os) { if (null != is) { try { is.close(); is = null; } catch (IOException e) { LOG.error("close InputStream fail!", e); } } if (null != os) { try { os.close(); os = null; } catch (IOException e) { LOG.error("close OutputStream fail!", e); } } } }
4. CommonConstants
import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @ClassName: CommonConstants * @Description: 公共常量类 * @author wenjianhai * @company 广州市道一信息技术有限公司 * @date 2012-11-8 * @version V1.0 */ public final class CommonConstants { private CommonConstants() { } /** 存放属性配置文件(*.properties)中的key-value */ public static Map<String, String> propMap = new ConcurrentHashMap<String, String>(16); }
5. 初始化配置文件
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import org.apache.log4j.Logger; /** * @ClassName: InitServlet * @Description: 服务启动时需要初始化 * @author * @company * @date 2012-11-8 * @version V1.0 */ public class InitServlet extends HttpServlet { /** * @Fields serialVersionUID : 序列化id */ private static final long serialVersionUID = -283273527502774557L; private static final Logger log = Logger.getLogger(InitServlet.class); @Override public void init() throws ServletException { log.info("Start to init InitServlet."); // 必须要调用父类的初始化方法 super.init(); // 解析并读取属性文件 ParsePropertiesFile.getInstance().getConfig("database.properties"); log.info("End to init InitServlet."); } }
6. 在 web.xml 中配置servlet
<!-- 初始化 --> <servlet> <servlet-name>initServlet</servlet-name> <servlet-class>cn.com.do1.component.init.InitServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>initServlet</servlet-name> <url-pattern>/initServlet</url-pattern> </servlet-mapping>
7. 数据库连接池
import java.sql.Connection; import java.sql.SQLException; import java.util.Vector; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.lang.time.StopWatch; import org.apache.log4j.Logger; import com.mchange.v2.c3p0.ComboPooledDataSource; /** * @ClassName: ConnectionPool * @Description: 数据库连接池,用于获取第三方数据库的连接 * @author * @company * @date 2012-11-15 * @version V1.0 */ public final class ConnectionPool { private Vector<Connection> pool; private int poolSize;// 连接池大小 private static final Logger log = Logger.getLogger(ConnectionPool.class); // 线程局部变量 protected static ThreadLocal<Connection> threadLocalCon = new ThreadLocal<Connection>(); private static final ConnectionPool instance = new ConnectionPool(); private static DataSource dataSource; /* * 私有构造方法,禁止在外部创建本类的对象,要想获得本类的对象,统一通过getInstance()方法。 * 在构造方法中,完成数据池配置文件的加载以及数据池的创建。 */ private ConnectionPool() { try { this.poolSize = Integer.parseInt(CommonConstants.propMap .get("c3p0.maxPoolSize")); if (dataSource == null) { initDataSource(); } if (null == pool) { // 根据配置信息创建连接池 pool = new Vector<Connection>(poolSize); pool = addConnection(poolSize); } } catch (Exception e) { log.error("Init Connection Pool fail!", e); } } /* * 获取本类的对象 */ public static ConnectionPool getInstance() { return instance; } /* * 释放一条连接到连接池中。 */ public synchronized void release(Connection conn) { // 重新设置成自动提交(使用事务时,会设置为不自动提交,所以释放连接时,重置成事务自动提交) try { conn.setAutoCommit(true); } catch (SQLException e) { log.error("set auto commit fail!", e); } catch (Exception e) { log.error("set auto commit fail!", e); } // 重新放入连接池中 pool.add(conn); // 从线程变量中移除 threadLocalCon.set(null); } /* * 从连接池中获取一个连接 */ public Connection getConnection() { Connection con = threadLocalCon.get(); try { if (con == null || con.isClosed()) { while (pool.size() == 0) { try { Thread.sleep(500); } catch (InterruptedException e) { log.error(e); } } synchronized (this) { con = pool.get(0); threadLocalCon.set(con); } } } catch (Exception e1) { log.error("Get Connection fail!", e1); } return con; } /* * 根据传入的参数,在连接池中新建num个连接。 */ private Vector<Connection> addConnection(int num) { StopWatch sw = new StopWatch(); sw.start(); Connection conn = null; try { // Class.forName(driverClassName); for (int i = 0; i < num; i++) { // conn = DriverManager.getConnection(url, username, password); conn = dataSource.getConnection(); pool.add(conn); } } catch (Exception e) { log.error("add Connection fail!", e); } sw.stop(); log.info("end add connection,the time-consuming is:" + sw.getTime()); return pool; } /* * 清空连接池中所有连接。 */ public synchronized void closePool() { for (int i = 0; i < pool.size(); i++) { try { pool.get(i).close(); } catch (SQLException e) { log.error("close Connection Pool fail!", e); } catch (Exception e) { log.error("close Connection Pool fail!", e); } pool.remove(i); } } /* * 获取当前连接池中可用连接数 */ public int getAvailableConnectNumber() { return pool.size(); } /** * @Title: initDataSource * @Description:初始化数据源,使用 DPCP * @author * @date 2012-11-16 */ public static void initDataSourceDpcp() { // DPCP 连接池 BasicDataSource ds = new BasicDataSource(); ds.setDriverClassName(CommonConstants.propMap.get("c3p0.driver")); ds.setUrl(CommonConstants.propMap.get("c3p0.url")); ds.setUsername(CommonConstants.propMap.get("c3p0.user")); ds.setPassword(CommonConstants.propMap.get("c3p0.password")); // 设置从数据源中返回的连接是否采用自动提交机制 ds.setDefaultAutoCommit(Boolean.parseBoolean(CommonConstants.propMap .get("c3p0.autoCommitOnClose"))); // 最大连接数据库连接数,设置为0时,表示没有限制 ds.setInitialSize(Integer.parseInt(CommonConstants.propMap .get("c3p0.initialPoolSize"))); // 最大连接数 ds.setMaxActive(Integer.parseInt(CommonConstants.propMap .get("c3p0.maxPoolSize"))); // 在不新建连接的条件下,池中保持空闲的最少连接数 ds.setMinIdle(Integer.parseInt(CommonConstants.propMap .get("c3p0.minPoolSize"))); // 最大等待秒数,单位为毫秒, 超过时间会报出错误信息 ds.setMaxWait(Integer.parseInt(CommonConstants.propMap .get("dpcp.maxwait"))); dataSource = ds; } /** * @Title: initDataSource * @Description:初始化数据源,使用C3P0 * @author * @date 2012-11-16 */ public static void initDataSource() { // C3P0 连接池 ComboPooledDataSource cpds = new ComboPooledDataSource(); try { cpds.setDriverClass(CommonConstants.propMap.get("c3p0.driver")); } catch (Exception e) { log.error("load driver class fail!", e); } cpds.setUser(CommonConstants.propMap.get("c3p0.user")); cpds.setPassword(CommonConstants.propMap.get("c3p0.password")); cpds.setJdbcUrl(CommonConstants.propMap.get("c3p0.url")); // 初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 initialPoolSize cpds.setInitialPoolSize(Integer.parseInt(CommonConstants.propMap .get("c3p0.initialPoolSize"))); // 连接池中保留的最大连接数。Default: 15 maxPoolSize cpds.setMaxPoolSize(Integer.parseInt(CommonConstants.propMap .get("c3p0.maxPoolSize"))); // 连接池中保留的最小连接数。 cpds.setMinPoolSize(Integer.parseInt(CommonConstants.propMap .get("c3p0.minPoolSize"))); // 获得连接的最大等待毫秒数。Default: 1000 acquireRetryDelay cpds.setAcquireRetryDelay(Integer.parseInt(CommonConstants.propMap .get("c3p0.acquireRetryDelay"))); // 最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 maxIdleTime cpds.setMaxIdleTime(Integer.parseInt(CommonConstants.propMap .get("c3p0.maxIdleTime"))); // 当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 acquireIncrement cpds.setAcquireIncrement(Integer.parseInt(CommonConstants.propMap .get("c3p0.acquireIncrement"))); // 每60秒检查所有连接池中的空闲连接。Default: 0 idleConnectionTestPeriod // cpds.setIdleConnectionTestPeriod(60); // 连接关闭时默认将所有未提交的操作回滚。Default: false autoCommitOnClose cpds.setAutoCommitOnClose(Boolean.parseBoolean(CommonConstants.propMap .get("c3p0.autoCommitOnClose"))); // maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数 cpds.setMaxStatementsPerConnection(Integer .parseInt(CommonConstants.propMap .get("c3p0.maxStatementsPerConnection"))); // c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成,扩展这些操作可以有效的提升性能 .通过多线程实现多个操作同时被执行 cpds.setNumHelperThreads(Integer.parseInt(CommonConstants.propMap .get("c3p0.numHelperThreads"))); // 定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 acquireRetryAttempts cpds.setAcquireRetryAttempts(Integer.parseInt(CommonConstants.propMap .get("c3p0.acquireRetryAttempts"))); // 定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个一显著提高测试速度。注意:测试的表必须在初始数据源的时候就存在。Default: // null preferredTestQuery // cpds.setPreferredTestQuery("select sysdate from dual"); // 因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的 // 时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable // 等方法来提升连接测试的性能。Default: false testConnectionOnCheckout // cpds.setTestConnectionOnCheckout(true); // 如果设为true那么在取得连接的同时将校验连接的有效性。Default: false testConnectionOnCheckin // cpds.setTestConnectionOnCheckin(true); // JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: // 0 // cpds.setMaxStatements(1); // 获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 // 保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试 // 获取连接失败后该数据源将申明已断开并永久关闭。Default: false breakAfterAcquireFailure // cpds.setBreakAfterAcquireFailure(false); dataSource = cpds; } /** * @Title: beginTransaction * @Description: 开始事务 * @param conn * :数据库连接 * @author * @date 2012-11-16 */ public static void beginTransaction(Connection conn) { try { if (conn != null) { if (conn.getAutoCommit()) { // 手动提交 conn.setAutoCommit(false); } } } catch (SQLException e) { log.error("set auto commit to false fail!", e); } catch (Exception e) { log.error("begin Transaction fail!", e); } } /** * @Title: commitTransaction * @Description: 提交事务 * @param conn * :数据库连接 * @author * @date 2012-11-16 */ public static void commitTransaction(Connection conn) { try { if (conn != null) { if (!conn.getAutoCommit()) { conn.commit(); } } } catch (SQLException e) { log.error("commit transaction fail!", e); } catch (Exception e) { log.error("commit transaction fail!", e); } } /** * @Title: rollbackTransaction * @Description: 事务回滚 * @param conn * :数据库连接 * @author * @date 2012-11-16 */ public static void rollbackTransaction(Connection conn) { try { if (conn != null) { if (!conn.getAutoCommit()) { conn.rollback(); } } } catch (SQLException e) { log.error("rollback transaction fail!", e); } catch (Exception e) { log.error("rollback transaction fail!", e); } } /** * @Title: resetConnection * @Description: 事务重置 * @param conn * :数据库连接 * @author * @date 2012-11-16 */ public static void resetConnection(Connection conn) { try { if (conn != null) { if (conn.getAutoCommit()) { conn.setAutoCommit(false); } else { conn.setAutoCommit(true); } } } catch (SQLException e) { log.error("reset transaction fail!", e); } catch (Exception e) { log.error("reset transaction fail!", e); } } /** * @Title: setAutoCommit * @Description: 设置是否自动提交事务 * @param conn * 数据库连接 * @param autoCommit * :是否自动提交 * @author * @date 2012-11-16 */ public static void setAutoCommit(Connection conn, boolean autoCommit) { if (conn != null) { try { conn.setAutoCommit(autoCommit); } catch (SQLException e) { log.error("set Auto Commit fail!", e); } catch (Exception e) { log.error("set Auto Commit fail!", e); } } } }
8. 调用 (DAO层)
/** * @Title: findExpireNotice * @Description: 查找2个月后到期的许可证、工商执照 * @param isAll * 0:查找所有已到期的,1:查找2个月后到期的 * @return List * @throws Exception * @see cn.com.do1.component.business.licencenotice.dao.ILicencenoticeDAO#findExpireNotice(int) * @author */ @Override public List<RmLicense> findExpireNotice(YcBusinessMessagePO bm, int isAll) throws Exception { // 获取中间库连接 Connection conn = null; try { conn = ConnectionPool.getInstance().getConnection(); } catch (Exception e) { logger.error("连接中间库失败!", e); throw new Exception("连接中间库失败!"); } List<RmLicense> list = new ArrayList<RmLicense>(); String sql = null; if (0 == isAll) { // 查找所有已到期的 sql = "select b.license_code,a.CUST_NAME,a.CORPORATION_NAME," + "a.MANAGER,a.MANAGER_TEL " + "from rm_cust a,rm_license b where a.cust_id=b.cust_id " + " and status='1' and INVALIDATION_DATE<=current date"; } else if (1 == isAll) { // 查找bm.getWarningLimit()天后到期的 sql = "select b.license_code,a.CUST_NAME,a.CORPORATION_NAME," + "a.MANAGER,a.MANAGER_TEL " + "from rm_cust a,rm_license b where a.cust_id=b.cust_id " + " and status='1' " + " and INVALIDATION_DATE=(current date + " + bm.getWarningLimit() + " days)"; } logger.info("查找2个月后到期的许可证、工商执照,the sql is:\r\n" + sql); PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(); RmLicense license = null; while (rs.next()) { license = new RmLicense(); license.setLicenseCode(rs.getString("license_code")); license.setCustName(rs.getString("CUST_NAME")); license.setCorporationName(rs.getString("CORPORATION_NAME")); license.setManager(rs.getString("MANAGER")); license.setManagerTel(rs.getString("MANAGER_TEL")); list.add(license); } ps.close(); ConnectionPool.getInstance().release(conn); return list; }
相关推荐
Java JDBC 数据库连接池总结 Java 语言中,JDBC(Java DataBase Connection)是应用程序与数据库沟通的桥梁。在 Web 应用开发的早期,主要使用的技术是 CGIASPPHP 等。之后,Sun 公司推出了基于 Java 语言的 ...
总的来说,Java JDBC数据库连接池是提升Web应用性能的重要技术,通过有效的连接管理和复用,它降低了数据库操作的开销,提升了系统的稳定性和响应速度。在开发过程中,选择合适的连接池实现,并对其进行合理配置,是...
** JDBC数据库连接池详解 ** 在Java开发中,JDBC(Java Database Connectivity)是用于与数据库交互的标准API。然而,直接使用JDBC进行数据库操作可能会导致资源管理的问题,因为每次数据库连接的创建和关闭都会...
本资源集合了常用的JDBC数据库连接jar包,以及一些知名的数据库连接池实现,如dbcp和c3p0,这对于开发人员来说是非常宝贵的资源。 首先,让我们了解一下JDBC。JDBC提供了一套标准的API,包括接口和类,使得开发者...
**JDBC数据库连接池工程文件详解** 在Java开发中,JDBC(Java Database Connectivity)是用于与各种数据库交互的标准API。然而,频繁地创建和关闭数据库连接会消耗大量的系统资源,影响应用程序性能。为了解决这个...
实现JDBC数据库连接池的基本步骤如下: 1. **选择连接池实现**:首先,我们需要选择一个合适的数据库连接池实现,如Apache的DBCP、C3P0、HikariCP或Tomcat JDBC连接池等。这些连接池库提供了管理和维护数据库连接的...
本教程将深入讲解JDBC数据库连接池的简单实现。 首先,我们需要理解JDBC(Java Database Connectivity)的基本概念。JDBC是Java API,它允许Java程序与各种类型的数据库进行交互。然而,每次应用程序需要访问数据库...
Java JDBC数据库连接池是Java应用程序与数据库交互的重要优化手段,旨在提高数据库访问效率和资源利用率。在传统的JDBC操作中,每次请求都需要建立和关闭数据库连接,这不仅耗时,还可能导致系统资源的过度消耗,...
jdbc数据库连接池R2的源代码。R2通过代理connection对象和工厂模式实现了不改变原jdbc调用方式的前提下的jdbc数据库连接池。结构简单,功能完善,高可配置,充分应用了jdk1.6的同步包特性,提高了并发效率,并能够...
本资源名为“最新版加注释通用JDBC数据库连接池”,显然它提供了一个带有详细注释的通用JDBC数据库连接池实现,这将有助于开发者理解和使用。这里我们将详细讲解数据库连接池的概念、工作原理以及如何使用。 **...
Java JDBC数据库连接池总结 Java JDBC(Java Database Connectivity)是Java语言访问数据库的标准接口,它允许应用程序通过编写Java代码来与各种数据库进行交互。在Web应用程序中,由于B/S架构的普及,Java JDBC...
**JDBC数据库连接池技术详解** 在Java编程中,数据库操作是常见的任务,而有效管理数据库连接对于提高应用性能和资源利用率至关重要。这就是数据库连接池技术的出现原因。本篇将深入探讨`JDBC(Java Database ...
实现一个简单的JDBC数据库连接池,我们通常需要以下组件: 1. 连接池初始化:配置连接池的大小,预创建指定数量的数据库连接,并将它们存入池中。 2. 获取连接:提供一个方法供应用获取数据库连接,当连接池中有...
JDBC数据库连接池总结 一、JDBC数据库连接池概述 在基于B/S架构的三层开发模式中,Java应用程序访问数据库的基本原理是通过JDBC(Java DataBase Connection)技术。JDBC是一种“开放”的方案,为数据库应用开发...
J2EE 程序员一般都有现成的应用服务器所带的JDBC 数据库连接池,不过对于开发一般的 Java Application 、 Applet 或者 JSP、velocity 时,我们可用的JDBC 数据库连接池并不多,并且一般性能都不好。我们可以自己写一...
【JDBC数据库连接池总结】 在Java开发中,JDBC(Java Database Connectivity)是用于连接应用程序和数据库的关键技术。JDBC提供了一套API,使得开发者能够以标准的方式编写数据库交互代码。然而,直接使用JDBC在高...