`

(十) 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/ 目录下

分享到:
评论

相关推荐

    jsp 企业管理 web源码+SQL

    压缩包中的"企业管理"可能代表了整个项目目录,包含JSP页面、Java类文件、配置文件(如web.xml)、样式表(CSS)、脚本文件(JavaScript)、数据库连接文件(如db.properties)以及其他支持文件。开发者通过阅读...

    java web项目企业进销存管理系统

    《Java Web项目:企业进销存管理系统的深度解析》 在信息技术日新月异的今天,企业对于高效、精准的管理工具的需求日益增强。"Java Web项目企业进销存管理系统"便是这样一款针对企业管理核心流程——进、销、存进行...

    Web应用中,各种数据库连接方法总结

    在Web应用程序开发过程中,数据库的连接与操作是不可或缺的一部分。不同的数据库系统有着不同的连接方式。本文将总结在Web应用中常用的几种数据库(Oracle、DB2、SQL Server、MySQL等)通过ODBC和JDBC进行连接的方法...

    Java Web开发的连接池集

    在Java Web开发中,连接池是一种管理数据库连接的机制,旨在提高应用程序的性能和效率。连接池通过预先创建并维护一定数量的数据库连接,避免了每次需要与数据库交互时都进行连接建立和释放的开销。这个压缩包可能...

    用PB开发WEB应用

    PowerBuilder(PB)是一款强大的企业级应用程序开发工具,尤其适合构建数据库驱动的Web应用程序。它以其易用性、高效的数据库访问以及内置的数据窗口组件而受到开发者喜爱。在本主题中,我们将深入探讨如何利用Power...

    Java+Web项目企业事务管理系统源码 (1)Java源码

    3. **MVC设计模式**:在企业级Web应用中,Model-View-Controller(模型-视图-控制器)模式被广泛应用。模型负责数据处理,视图负责用户界面展示,控制器协调模型和视图之间的交互。 4. **Servlet与JSP**:Servlet是...

    企业中应用oracle的Web信息管理系统.pdf

    总结来说,Oracle数据库在企业Web信息管理系统中的应用涉及多方面的技术和策略,包括数据库设计、性能优化、系统集成和安全管理。Oracle的特性使其成为企业级信息管理的理想选择,但同时也要求企业在系统建设和运维...

    java web信息管理

    在这个“java web信息管理系统”项目中,我们可以深入理解Java Web的基础知识及其在实际开发中的应用。 首先,Java Web项目的核心是Servlet和JSP(JavaServer Pages)。Servlet是Java编写的服务器端程序,负责处理...

    基于WEB的企业人事管理系统

    2.2.2 社会可行性:企业越来越重视人力资源管理的效率与效果,采用Web技术构建的人事管理系统能够满足这一需求,具有良好的社会应用前景。 2.2.3 经济可行性:相比于传统的纸质管理方式,Web系统可以大幅降低管理和...

    数据库连接池技术及其在Web系统开发中的应用.pdf

    数据库连接池技术及其在Web系统开发中的应用 数据库连接池技术是指在Web...数据库连接池技术是Web系统开发中的一个重要技术,可以提高系统性能、可靠性和安全性,对于企业信息化进程中的数据库应用具有重要的意义。

    《精通NetBeans——Java桌面、Web与企业级程序开发详解》光盘

    《精通NetBeans——Java桌面、Web与企业级程序开发详解》是一本专为Java开发者设计的深入指南,它详尽地介绍了如何利用NetBeans IDE进行高效且高效的编程工作。NetBeans是一个开源的集成开发环境(IDE),广泛用于...

    AD域管理web版

    【AD域管理Web版】是一种基于微软Active Directory(AD)技术的网络管理工具,它利用了.NET框架进行开发,以Web界面的形式提供AD域的便捷管理。这种工具旨在简化IT管理员对AD域环境的日常维护工作,使得在任何地方...

    WEB版的SQL Server 企业管理器源码

    【压缩包子文件的文件名称列表】中,"SqlWebAdmin"可能是Web版SQL Server企业管理器的主要应用程序或库,包含实现Web界面和与SQL Server交互的代码。"SqlAdmin"可能是一个辅助或支持文件,可能包含了与数据库管理...

    基于WEB的MYSQL数据库管理系统

    基于Web的MySQL数据库管理系统则是将MySQL的功能与Web技术相结合,让用户可以通过Web浏览器进行数据库的管理和操作,无需在本地安装任何特定软件,极大地提高了远程协作和数据访问的便利性。 1. **Web界面**:基于...

    Java+Web项目企业事务管理系统源码源码整理

    Java+Web项目企业事务管理系统源码是一个典型的企业级应用开发实例,它涵盖了Java后端编程、Web前端交互以及数据库管理等多个技术领域。这个系统的源码分析将帮助我们深入理解如何构建一个完整的业务处理系统。 1. ...

    Java Web应用框架研究与应用.pdf

    在实际的Java Web应用开发中,Struts2常用于处理用户请求和展示视图,Hibernate负责数据的持久化,而Spring则作为一个整体的协调者,管理和连接其他两个框架,提供事务管理、安全控制等服务。这种组合使得开发团队能...

    Web版的数据库管理工具

    7. **部署与扩展**:由于是Web应用,可以轻松部署到各种Web服务器,如Tomcat、Jetty等,甚至云平台如AWS或Google Cloud。同时,利用微服务架构,可以实现服务的水平扩展,提高系统性能和可用性。 8. **用户界面**:...

    jdbc构建基于web的应用程序

    - **JNDI与DataSource**:在企业级应用中,通常使用JNDI(Java Naming and Directory Interface)查找DataSource,以实现数据库连接的管理,提高性能和可扩展性。 - **事务管理**:在Web应用中,JDBC可以配合...

    jsp-web开发技术与典型应用

    JSP广泛应用于电子商务网站、企业信息系统、内容管理系统等。实例代码可能涵盖了用户登录、购物车、订单处理、数据展示等功能,这些都是JSP开发中的常见应用场景。 **10. 学习与实践** 学习JSP不仅要掌握基本语法,...

Global site tag (gtag.js) - Google Analytics