`

(十) Web与企业应用中的连接管理

阅读更多

 

1.JNDI

在企业环境中部署JDBC应用时,数据库连接管理与JNDI(Java名字和目录接口)是集成在一起的。

e.g.  Context jndiContext = new InitialContext();

      DataSource source = (DataSource)jndiContext.lookup("java:comp/env/jdbc/corejava");

      Connection conn = source.getConnection();

注意:不再使用DriverManager,而是使用JNDI服务来定位数据源。一个数据源就是一个能够提供简单的JDBC连接和更高级服务的接口。javax.sql标准扩展包定义了DataSource接口。

 

在JavaEE 5的容器中,甚至可以不必编程进行JNDI查找,只需要在DataSource域上使用Resource注解,当加载应用时,这个数据源引用将被设置。

e.g.  @Resource("jdbc/corejava")

      private DataSource source;

 

2.连接池

因为数据库连接是有限的资源,如果用户在某个时刻离开应用,那么他占用的连接就不应该保持开发状态;另一方面每次查询都要获取连接并在随后关闭它的代价也是相当高的。

解决这个问题的办法是建立数据库连接池,这意味着数据库连接在物理上并未被关闭,而是保留在一个队列中并被反复重用。

连接池可以通过获取数据源并调用getConnection方法得到连接池中的连接。使用完连接后,调用close方法,使用该方法并不在物理上关闭连接,而只是告诉连接池已经使用完该连接。连接池通常还会将池机制用于预备语句上。


C3P0 DEMO

import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.Properties;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class DBUtil {
	
	private static ComboPooledDataSource dataSource = null;
	private static Properties param = null;
	private static String prefix = null;
	static{
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(System.getProperty("user.dir") + "/bin/database.properties");
			param = new Properties();
			param.load(fis);
			fis.close();
			
			if("MySQL".equalsIgnoreCase(param.getProperty("DatabaseType"))){
				prefix = "mysql.";
			}else if("Derby".equalsIgnoreCase(param.getProperty("DatabaseType"))){
				prefix = "derby.";
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public static Connection getConnection(){
		try{
			String drivers = param.getProperty(prefix + "jdbc.drivers");
			if (drivers != null && !"".equals(drivers)) {
				System.setProperty("jdbc.drivers", drivers);
			}
			String url = param.getProperty(prefix + "jdbc.url");
			String username = param.getProperty(prefix + "jdbc.username");
			String password = param.getProperty(prefix + "jdbc.password");
			return DriverManager.getConnection(url,username,password);
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
		
	}
	
	public static Connection getConnectionByC3P0(){
		try{
			if(dataSource == null){
				DBUtil.C3P0Init();
			}
			return dataSource.getConnection();
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
		
	}
	
    public static void C3P0Init(){   
    	try{
    		dataSource = new ComboPooledDataSource();
    		String drivers = param.getProperty(prefix+"jdbc.drivers");
    		if (drivers != null && !"".equals(drivers)) {
    			dataSource.setDriverClass(drivers);
    		}
    		dataSource.setJdbcUrl(param.getProperty(prefix + "jdbc.url"));
    		dataSource.setUser(param.getProperty(prefix + "jdbc.username"));
    		dataSource.setPassword(param.getProperty(prefix + "jdbc.password"));
    		//连接池中保留的最大连接数
    		dataSource.setMaxPoolSize(20);
    		//连接池中保留的最小连接数
    		dataSource.setMinPoolSize(3);
    		//初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 
    		dataSource.setInitialPoolSize(3);
    		//最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0
    		dataSource.setMaxIdleTime(0);
    		//当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3
    		dataSource.setAcquireIncrement(3);
    		//定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 
    		dataSource.setAcquireRetryAttempts(30);
    		//两次连接中间隔时间,单位毫秒。Default: 1000 
    		dataSource.setAcquireRetryDelay(1000);
    		//如果设为true那么在取得连接的同时将校验连接的有效性。Default: false 
    		dataSource.setTestConnectionOnCheckin(false);
    		//c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么
    		//属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试
    		//使用。Default: null
    		dataSource.setAutomaticTestTable(null);
    		//当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出
    		//SQLException,如设为0则无限期等待。单位毫秒。Default: 0
    		dataSource.setCheckoutTimeout(0);
    		//JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。
    		dataSource.setMaxStatements(0);


    	}catch(Exception e){
    		e.printStackTrace();
    	}
    } 
	
	public static boolean createTable(Connection conn){
		try{
			Statement stmt = conn.createStatement();
			String createTable = "CREATE TABLE test_table(" +
								 " id INT," +
								 " str VARCHAR(20)," +
								 " ds TIMESTAMP," +
								 " PRIMARY KEY (`id`))";
			stmt.executeUpdate(createTable);
			stmt.close();
			return true;
		}catch(Exception e){
			e.printStackTrace();
		}
		return false;
	}
	
	public static boolean destroyTable(Connection conn){
		try{
			Statement stmt = conn.createStatement();
			stmt.execute("DROP TABLE test_table");
			stmt.close();
			return true;
		}catch(Exception e){
			e.printStackTrace();
		}
		return false;
	}
} 


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.Date;

import com.shaogq.jdbc.util.DBUtil;

public class TestC3P0 {
	public static void main(String[] args) {
		Connection conn = null;
		try {
			try{
				//JDBC
//				conn = DBUtil.getConnection();
				//连接池
				conn = DBUtil.getConnectionByC3P0();
//				DBUtil.createTable(conn);
				TestC3P0 t = new TestC3P0();
//				t.init(conn);
//				t.insertTimestamp(conn);
//				t.moreResultSelect(conn);
				t.insertGeneratedKeys(conn);
			}finally{
//				DBUtil.destroyTable(conn);
				conn.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	
	/**
	 * 初始化数据库表中数据
	 */
	public void init(Connection conn){
		try{
			PreparedStatement prepStmt = null;
			try{
				String insertDate = "INSERT INTO test_table values(?,?,?)";
				prepStmt = conn.prepareStatement(insertDate);
				int[] ch = new int[]{1,2,3,4,5,6,7,8};
				String[] str = new String[]{"a","b","c","d","e","f","g","h"};
				for(int i=0;i<ch.length&&i<str.length;i++){
					prepStmt.setInt(1, ch[i]);
					prepStmt.setString(2, str[i]);
					prepStmt.setTimestamp(3, new Timestamp(new Date().getTime()));
					prepStmt.executeUpdate();
				}
				prepStmt.close();
			}finally{
				prepStmt.close();
			}
		}catch(SQLException e){
			for(Throwable t : e){
				t.printStackTrace();
			}
		}
	}
	
	/**
	 * 通过转义插入时间
	 */
	public void insertTimestamp(Connection conn){
		try{
			Statement stmt = null;
			try{
				stmt = conn.createStatement();
				String sql = "INSERT INTO test_table VALUES(100,'abc',{ts '2011-11-11 23:59:59'})";
				stmt.executeUpdate(sql);
			}finally{
				stmt.close();
			}
		}catch(SQLException e){
			for(Throwable t : e){
				t.printStackTrace();
			}
		}
	}
	
	/**
	 * 查询更多结果集
	 */
	public void moreResultSelect(Connection conn){
		try{
			PreparedStatement prepStmt = null;
			try{
				String sql = "SELECT * FROM test_table where str=? ";
				prepStmt = conn.prepareStatement(sql);
				prepStmt.setString(1, "abc");
				boolean hasResult = prepStmt.execute();
				if(hasResult){
					do{
						ResultSet result = prepStmt.getResultSet();
						while(result.next()){
							System.out.println(result.getString("str") + "," + result.getInt("id") + "," + result.getTimestamp("ds"));
						}
					}while(prepStmt.getMoreResults());
				}
			}finally{
				prepStmt.close();
			}
		}catch(SQLException e){
			for(Throwable t : e){
				t.printStackTrace();
			}
		}
	}
	
	/**
	 * 测试自动插入主键
	 */
	private void insertGeneratedKeys(Connection conn) {
		try{
			Statement stmt = null;
			try{
				stmt = conn.createStatement();
				String sql = "INSERT INTO test_table VALUES('a',{ts '2011-11-11 23:59:59'})";
				stmt.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
			}finally{
				
			}
		}catch(SQLException e){
			for(Throwable t : e){
				t.printStackTrace();
			}
		}
	}
}
 

JNDI+C3P0

tomcat/conf/context.xml

	<!-- 一种实现方式 不用写web.xml
	<Resource name="TestJNDI" auth="Container" type="javax.sql.DataSource"
               maxActive="100" maxIdle="30" maxWait="10000"
      testOnBorrow="true" testOnReturn="true" testWhileIdle="true"
      validationQuery=" select 1 "
               username="root" password="12345678" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost:3306/corejava"/>
	-->

	<!--下面注释部分为使用jndi+tomcat自带的连接池 需要写web.xml

	<Resource name="TestJNDI" type= "javax.sql.DataSource"
	username="root" password= "12345678" driverClassName= "com.mysql.jdbc.Driver" url= "jdbc:mysql://localhost:3306/corejava"
	maxIdle="30" maxWait= "5000" maxActive= "100" />
	-->
	<!--下面注释部分为使用jndi+c3p0-->
	
	<Resource name="TestJNDI"
	type="com.mchange.v2.c3p0.ComboPooledDataSource"
	maxPoolSize="50" minPoolSize="2" acquireIncrement="2"
	factory="org.apache.naming.factory.BeanFactory"
	user="root" password="12345678"
	driverClass="com.mysql.jdbc.Driver"
	jdbcUrl="jdbc:mysql://localhost:3306/corejava"/>
 
project/WEB-INF/web.xml
<resource-ref>
<description>DBConnection</description>
<res-ref-name>TestJNDI</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
 

    private static Connection conn = null;
    static Context context = null;
    static DataSource dataSource = null;
    
    public static Connection getConnection() throws NamingException, SQLException{
    	context = new InitialContext();
    	dataSource = (DataSource) context.lookup("java:/comp/env/TestJNDI");
    	if(dataSource!=null){
    		conn = dataSource.getConnection();
    	}
         return conn;
     }
 
注意:要通过TOMCAT DBCP来实现JNDI,连接数据库,需要将驱动JAR包拷贝到 apache-tomcat/lib/ 目录下

分享到:
评论

相关推荐

    cpweb企业网站管理系统 v1.1.rar

    CPWEB企业网站管理系统(以下称CPWEB)是一个基于PHP Mysql架构的企业网站管理系统。CPWEB 采用模块化方式开发,功能强大灵活易于扩展,并且完全开放源代码,面向大中型站点提供重量级企业网站建设解决方案。 ...

    cpweb企业网站管理系统 v1.1 PHP.rar

    CPWEB企业网站管理系统(以下称CPWEB)是一个基于PHP Mysql架构的企业网站管理系统。CPWEB 采用模块化方式开发,功能强大灵活易于扩展,并且完全开放源代码,面向大中型站点提供重量级企业网站建设解决方案。主要...

    WEB工资管理系统模板

    该程序通过asp.net的ADO数据对象来实现前台与后台Access数据库的连接,并具有典型的数据库应用系统的特征,完成了系统结构与现实生活的紧密结合。 工资管理系统的开发不仅是一个应用程序编写的过程,更重要的是在系统的...

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    中文名: 经典Java EE企业应用实战--基于WebLogic/JBoss的JSF+EJB 3+JPA整合开发 原名: 经典Java EE企业应用实战--基于WebLogic/JBoss的JSF+EJB 3+JPA整合开发 作者: 李刚 资源格式: PDF 版本: 第一版 出版社: 电子...

    Java Web编程宝典-十年典藏版.pdf.part2(共2个)

    《Java Web编程宝典(十年典藏版)》是一本集技能、范例、项目和应用为一体的学习手册,书中介绍了应用Java Web进行程序开发的各种技术、技巧。全书分4篇,共24章,其中,第1篇为技能学习篇,主要包括Java Web开发环境...

    J2EE应用与BEA.WebLogic.Server第2版.pdf

    第十一章 使用 WebLogic Server JavaMail 连接 Internet 邮件 第十二章 管理 WebLogic Server 8.1 第十三章 WebLogic Server 8.1 应用程序安全 第十四章 设计产品部署 第十五章 Web 拍卖设计目标 第十六章 WebLogic ...

    基础 Step - Web Application及企业计算

    理解Web应用及开发的基本概念 掌握Servlet、会话管理、Filter及Java 掌握JSP 、JSP EL及JSTL 编写基于MVC模式的Java Web应用

    Spring3.x企业应用开发实战(完整版) part1

     《Spring3.x企业应用开发实战》是在《精通Spring2.x——企业应用开发详解》的基础上,经过历时一年的重大调整改版而成的,本书延续了上一版本追求深度,注重原理,不停留在技术表面的写作风格,力求使读者在熟练...

    Spring.3.x企业应用开发实战(完整版).part2

     《Spring3.x企业应用开发实战》是在《精通Spring2.x——企业应用开发详解》的基础上,经过历时一年的重大调整改版而成的,本书延续了上一版本追求深度,注重原理,不停留在技术表面的写作风格,力求使读者在熟练...

    整合Mybatis和Spring框架进行注解开发SSM框架的学习与应用-Java EE企业级应用开发学习记录(第十天)

    本资源记录了在Java EE企业级应用开发学习过程中的第十天内容,重点关注了整合Spring、Spring MVC和MyBatis(SSM框架)进行注解开发的学习和应用。通过这一天的学习,您将掌握如何构建强大的Web应用程序,同时提供了...

    数据挖掘在各行业的应用论文

    数据挖掘中知识管理与表达系统的设计与实现.caj 数据挖掘及其在通信侦察信号处理中的应用.caj 基于智能化数据挖掘的高新技术监测分析技术研究.caj 数据挖掘及在营销中的应用.caj 数据挖掘中信息颗粒及其构造.caj ...

    auth0-multitenant-website:演示一个简单的多租户 Web 应用程序的示例,该应用程序使用授权扩展来管理具有组的租户

    因此,如果您愿意,您可以将所有用户(跨所有租户)存储在一个数据库连接中(如示例所示)或跨多个连接(例如,数据库连接中的一些用户和企业连接中的一些用户,如 AD) 多租户应用程序表示为 Auth0 中的单个应用...

    基于Spring Boot + Vue 前后端分离的人力资源管理项目源码+数据库+需求规格说明书,可做常规企业级应用脚手架

    基于Spring Boot + Vue 前后端分离的人力资源管理项目源码+数据库+需求规格说明书,可做常规企业级应用脚手架 安装部署 提前准备 准备三样东西: 空的 vhr 数据库 redis rabbitmq 项目导入 项目的使用 Maven导入 ...

    《精通Spring2.X企业应用开发详解》20-23

    展现层应用 第19章 Spring MVC之一 第20章 Spring MVC之二 第21章 集成其他Web框架 第6篇 其他 第22章 Spring应用的测试 第23章 Spring工具类盘点 附录A 各种数据库连接配置及驱动 附录B ...

    J2EE中文版指南 CHM格式 带全文检索

    应用程序部署者和系统管理员 19 五.本书所用的软件 20 数据库访问 20 J2EE API 20 简化系统集成 20 工具 20 第2章 动手做一个EJB 22 一.准备工作 23 二.创建J2EE应用程序 24 三.创建企业Bean 24 编写企业Bean...

    weblogic 服务器管理(中文版)

    第19章,“管理WebLogic J2EE连接器架构”描述了提供对其它企业信息系统连接的WebLogic J2EE平台扩展是如何被管理的。 第20章,“管理WebLogic服务器许可证”描述了如何更新BEA许可证 附录A,“使用WebLogic Java...

    数据挖掘论文合集-242篇(part2)

    数据挖掘中知识管理与表达系统的设计与实现.caj 数据挖掘中聚类算法比较研究.caj 数据挖掘分类问题的贪婪粗糙集约简算法.caj 数据挖掘原理、方法及其应用.caj 数据挖掘及其在 SXWG_EIS 中的应用.caj 数据挖掘及其在...

    Sail!企业网站管理系统简体中文版 v1.2.rar

    2年来,凭借Silence长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得Sail得到了很多公司和网站的认可,并且越来越多地被应用到大中型商业网站 主要功能: 单页、文章、产品、公告、留言、...

    Sail!企业网站管理系统简体中文版 v1.2

    凭借Silence长期积累的丰富的Web开发及数据库经验和勇于创新追求完美的设计理念,使得Sail得到了很多公司和网站的认可,并且越来越多地被应用到大中型商业网站主要功能:单页、文章、产品、公告、留言、招聘、友情...

    serviceMix

    企业服务总线(EnterpriseServiceBus,ESB)从面向服务体系架构(Service-OrientedArchitecture,SOA)发展而来,是传统中间件技术与XML、Web服务等技术结合的产物。 ESB提供了网络中最基本的连接中枢,是构筑企业...

Global site tag (gtag.js) - Google Analytics