`
kingxss
  • 浏览: 969260 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JDBC数据源连接池的配置和使用示例

阅读更多

个人学习参考所用,勿喷!


使用JDBC建立数据库连接的两种方式:

1.在代码中使用DriverManager获得数据库连接。这种方式效率低,并且其性能、可靠性和稳定性随着用户访问量得增加逐渐下降。

2.使用配置数据源的方式连接数据库,该方式其实质就是在上述方法的基础上增加了数据库连接池,这种方式效率高。


数据源连接池的方式连接数据库与在代码中使用DriverManager获得数据库连接存在如下差别:

1)数据源连接池的方式连接数据库是在程序中,通过向一个JNDI(Java Naming and  Directory Interface)服务器查询,即调用Context接口的lookup()方法,来得到DataSource对象,然后调用DataSource对象的getConnection()方法建立连接

2)为了能重复利用数据库连接对象,提高对请求的响应时间和服务器的性能,采用连接池技术.连接池技术预先建立多个数据库连接对象,然后将连接对象保存到连接池中,当客户请求到来时,从池中取出一个连接对象为客户服务,当请求完成时,客户程序调用close()方法,将连接对象放回池中.

3)在代码中使用DriverManager获得数据库连接的方式中,客户程序得到的连接对象是物理连接,调用连接对象的close()方法将关闭连接,而采用连接池技术,客户程序得到的连接对象是连接池中物理连接的一个句柄,调用连接对象的close()方法,物理连接并没有关闭,数据源的实现只是删除了客户程序中的连接对象和池中的连接对象之间的联系.


为了测试方便可以在数据库(这里以mysql 5为例)中建立一个USER表:

CREATE TABLE `user` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL,
  `password` varchar(50) DEFAULT NULL,
  `email` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`),
);
 

导入数据库的驱动的jar包到tomcat的lib目录下(这里以mysql5为例,所用到的jar包为:mysql-connector-java-5.0.8-bin.jar)。


1.在代码中使用DriverManager获得数据库连接。这种方式效率低,并且其性能、可靠性和稳定性随着用户访问量得增加逐渐下降。

   oracle数据库连接的Java代码如下:

import java.sql.Connection;
import java.sql.DriverManager;
/**
 * 获取数据库连接
 */
public class DBConnection {
    
    /** Oracle数据库连接URL*/
    private final static String DB_URL = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
    
    /** Oracle数据库连接驱动*/
    private final static String DB_DRIVER = "oracle.jdbc.driver.OracleDriver";
    
    /** 数据库用户名*/
    private final static String DB_USERNAME = "root";
    
    /** 数据库密码*/
    private final static String DB_PASSWORD = "admin";
    
    /**
     * 获取数据库连接
     * @return
     */
    public Connection getConnection(){
        /** 声明Connection连接对象*/
        Connection conn = null;
        try{
            /** 使用Class.forName()方法自动创建这个驱动程序的实例且自动调用DriverManager来注册它*/
            Class.forName(DB_DRIVER);
            /** 通过DriverManager的getConnection()方法获取数据库连接*/
            conn = DriverManager.getConnection(DB_URL,DB_USERNAME,DB_PASSWORD);
        }catch(Exception ex){
            ex.printStackTrace();
        }
        return conn;
    }
    
    /**
     * 关闭数据库连接
     * 
     * @param connect
     */
    public void closeConnection(Connection conn){
        try{
            if(conn!=null){
                /** 判断当前连接连接对象如果没有被关闭就调用关闭方法*/
                if(!conn.isClosed()){
                    conn.close();
                }
            }
        }catch(Exception ex){
            ex.printStackTrace();
        }
    }
    
}

 

 mysql数据库连接的JSP代码如下:

<%@page import="java.sql.*, com.mysql.jdbc.Driver"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"	pageEncoding="UTF-8"%>
<html>
<body>	
	<%
	//com.mysql.jdbc.Driver
	Class.forName(Driver.class.getName()).newInstance();
	String url = "jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF8";
	String user = "root";
	String password = "123";
	
	Connection conn = DriverManager.getConnection(url, user, password);
	Statement stmt = conn.createStatement();
	
	String sql = "select * from user";
	ResultSet rs = stmt.executeQuery(sql);
	
	while(rs.next()) {
		out.print("<br />" + "====================" + "<br />");
		out.print(rs.getLong("id") + "   ");
		out.print(rs.getString("username") + "   ");
		out.print(rs.getString("password") + "   ");
		out.print(rs.getString("email") + "   ");
	}
	%>
</body>
</html>

 

2.使用配置数据源的方式连接数据库,该方式其实质就是在上述方法的基础上增加了数据库连接池,这种方式效率高。

1)mysql数据库数据源连接池的JSP代码如下:

<%@page import="java.sql.*, javax.naming.*, javax.sql.DataSource"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"	pageEncoding="UTF-8"%>
<html>
<body>
	<%
	Context initCtx = new InitialContext();
	DataSource ds = (DataSource)initCtx.lookup("java:comp/env/jdbc/demoDB");
	Connection conn = ds.getConnection();
	
	Statement stmt = conn.createStatement();
	
	String sql = "select * from user";
	ResultSet rs = stmt.executeQuery(sql);
	
	while(rs.next()) {
		out.print("<br />" + "====================" + "<br />");
		out.print(rs.getLong("id") + "   ");
		out.print(rs.getString("username") + "   ");
		out.print(rs.getString("password") + "   ");
		out.print(rs.getString("email") + "   ");
	}
	%>
</body>
</html>
 

2) 添加如下代码到tomcat的conf目录下的server.xml中:

<Context> 
	<Resource name="jdbc/demoDB" auth="Container" 
	type="javax.sql.DataSource"
	driverClassName="com.mysql.jdbc.Driver"
	url="jdbc:mysql://localhost:3306/demo"
	username="root"
	password="123"
	maxActive="50"
	maxIdle="30"
	maxWait="10000" />
</Context>

 

3)在web工程目录下的web.xml的根节点下配置如下内容:

<resource-ref>
	<description>mysqlDB Connection</description>
	<res-ref-name>jdbc/demoDB</res-ref-name>
	<res-type>javax.sql.DataSource</res-type>
	<res-auth>Container</res-auth>
</resource-ref>

 

 完成上述步骤数据源的连接池配置已经完成,但是为了提高项目的可移植性,最好将上述第二步的内容放入到工程的META-INF目录的context.xml中(这个文件需要自行建立):

<?xml version="1.0" encoding="UTF-8"?>
<Context>
      <Resource name="jdbc/demoDB" auth="Container" 
      type="javax.sql.DataSource"
      driverClassName="com.mysql.jdbc.Driver"
      url="jdbc:mysql://localhost:3306/demo"
      username="root"
      password="123"
      maxActive="50"
      maxIdle="30"
      maxWait="10000" />
</Context>


3.使用配置数据源的数据库连接池时的数据库操作工具类

代码如下:

package db.utils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.naming.InitialContext;
import javax.sql.DataSource;

//import org.apache.log4j.Logger;

/**
 * 数据库操作辅助类
 */
public class DbUtils {
	
	//private static Logger logger = Logger.getLogger("DbUtils");
	
	/**
	 * 该语句必须是一个 SQL INSERT、UPDATE 或 DELETE 语句
	 * @param sql
	 * @param paramList:参数,与SQL语句中的占位符一一对应
	 * @return
	 * @throws Exception
	 */
	public int execute(String sql, List<Object> paramList) throws Exception {
		if(sql == null || sql.trim().equals("")) {
			//logger.info("parameter is valid!");
		}

		Connection conn = null;
		PreparedStatement pstmt = null;
		int result = 0;
		try {
			conn = getConnection();
			pstmt = DbUtils.getPreparedStatement(conn, sql);
			setPreparedStatementParam(pstmt, paramList);
			if(pstmt == null) {
				return -1;
			}
			result = pstmt.executeUpdate();
		} catch (Exception e) {
			//logger.info(e.getMessage());
			throw new Exception(e);
		} finally {
			closeStatement(pstmt);
			closeConn(conn);
		}

		return result;
	}
	
	/**
	 * 将查询数据库获得的结果集转换为Map对象
	 * @param sql:查询语句
	 * @param paramList:参数
	 * @return
	 */
	public List<Map<String, Object>> getQueryList(String sql, List<Object> paramList) throws Exception {
		if(sql == null || sql.trim().equals("")) {
			//logger.info("parameter is valid!");
			return null;
		}

		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		List<Map<String, Object>> queryList = null;
		try {
			conn = getConnection();
			pstmt = DbUtils.getPreparedStatement(conn, sql);
			setPreparedStatementParam(pstmt, paramList);
			if(pstmt == null) {
				return null;
			}
			rs = getResultSet(pstmt);
			queryList = getQueryList(rs);
		} catch (RuntimeException e) {
			//logger.info(e.getMessage());
			System.out.println("parameter is valid!");
			throw new Exception(e);
		} finally {
			closeResultSet(rs);
			closeStatement(pstmt);
			closeConn(conn);
		}
		return queryList;
	}
	
	private void setPreparedStatementParam(PreparedStatement pstmt, List<Object> paramList) throws Exception {
		if(pstmt == null || paramList == null || paramList.isEmpty()) {
			return;
		}
		DateFormat df = DateFormat.getDateTimeInstance();
		for (int i = 0; i < paramList.size(); i++) {
			if(paramList.get(i) instanceof Integer) {
				int paramValue = ((Integer)paramList.get(i)).intValue();
				pstmt.setInt(i+1, paramValue);
			} else if(paramList.get(i) instanceof Float) {
				float paramValue = ((Float)paramList.get(i)).floatValue();
				pstmt.setFloat(i+1, paramValue);
			} else if(paramList.get(i) instanceof Double) {
				double paramValue = ((Double)paramList.get(i)).doubleValue();
				pstmt.setDouble(i+1, paramValue);
			} else if(paramList.get(i) instanceof Date) {
				pstmt.setString(i+1, df.format((Date)paramList.get(i)));
			} else if(paramList.get(i) instanceof Long) {
				long paramValue = ((Long)paramList.get(i)).longValue();
				pstmt.setLong(i+1, paramValue);
			} else if(paramList.get(i) instanceof String) {
				pstmt.setString(i+1, (String)paramList.get(i));
			}
		}
		return;
	}
	
	/**
	 * 获得数据库连接
	 * @return
	 * @throws Exception
	 */
	private Connection getConnection() throws Exception {
		InitialContext cxt = new InitialContext();
		DataSource ds = (DataSource) cxt.lookup(jndiName);
		if ( ds == null ) {
		   throw new Exception("Data source not found!");
		}
		
		return ds.getConnection();
	}
	
	private static PreparedStatement getPreparedStatement(Connection conn, String sql) throws Exception {
		if(conn == null || sql == null || sql.trim().equals("")) {
			return null;
		}
		PreparedStatement pstmt = conn.prepareStatement(sql.trim());
		return pstmt;
	}
	
	/**
	 * 获得数据库查询结果集
	 * @param pstmt
	 * @return
	 * @throws Exception
	 */
	private ResultSet getResultSet(PreparedStatement pstmt) throws Exception {
		if(pstmt == null) {
			return null;
		}
		ResultSet rs = pstmt.executeQuery();
		return rs;
	}
	
	/**
	 * @param rs
	 * @return
	 * @throws Exception
	 */
	private List<Map<String, Object>> getQueryList(ResultSet rs) throws Exception {
		if(rs == null) {
			return null;
		}
		ResultSetMetaData rsMetaData = rs.getMetaData();
		int columnCount = rsMetaData.getColumnCount();
		List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>();
		while (rs.next()) {
			Map<String, Object> dataMap = new HashMap<String, Object>();
			for (int i = 0; i < columnCount; i++) {
				dataMap.put(rsMetaData.getColumnName(i+1), rs.getObject(i+1));
			}
			dataList.add(dataMap);
		}
		return dataList;
	}
	
	/**
	 * 关闭数据库连接
	 * @param conn
	 */
	private void closeConn(Connection conn) {
		if(conn == null) {
			return;
		}
		try {
			conn.close();
		} catch (SQLException e) {
			//logger.info(e.getMessage());
		}
	}
	
	/**
	 * 关闭
	 * @param stmt
	 */
	private void closeStatement(Statement stmt) {
		if(stmt == null) {
			return;
		}
		try {
			stmt.close();
		} catch (SQLException e) {
			//logger.info(e.getMessage());
		}
	}
	
	/**
	 * 关闭
	 * @param rs
	 */
	private void closeResultSet(ResultSet rs) {
		if(rs == null) {
			return;
		}
		try {
			rs.close();
		} catch (SQLException e) {
			//logger.info(e.getMessage());
		}
	}
	
	
	private String jndiName = "java:/comp/env/jdbc/demoDB";

	public void setJndiName(String jndiName) {
		this.jndiName = jndiName;
	}
}
 

 

分享到:
评论

相关推荐

    完美的java jdbc连接池实例

    java jdbc 连接池实例 项目只要配数据源就可以直接启用, 也可以整合到你个项目里面, 可oracle、mysql、sqlserver自由切换方言。

    TOMCAT6.0配置数据库连接池

    Tomcat5的配置需要在server.xml文件当中配置或者在conf/Catalina/localhost下面相应的上下文配置文件做配置Tomcat标准数据源资源工厂配置项如下: * driverClassName - 所使用的JDBC驱动类全称。 * maxActive - 同一...

    JDBC 3.0数据库开发与设计

    4.6.1 JDBC数据源 4.6.2 实例 4.7 连接池 4.7.1 连接池数据源(Connection PoolDataSource) 4.7.2 连接池处理事件 4.7.3 三层环境下的连接池操作 4.7.4 连接池和DataSource实现 4.7.5 包含连接池的数据源...

    JDBC工具包MidaoJDBC.zip

    Midao JDBC 简化了 JDBC 的开发,特点是灵活、可定制、简单直观,提供大量的功能,包括事务处理、元数据操作、类型处理、检视、输入输出处理和转化,带连接池的数据源支持;缓存和懒查询执行;命名参数;多供应商...

    vertx-jdbc:顶点 3.0 JDBC

    JDBC Executor 为通过 Vertx 3.0 事件总线访问任何符合 JDBC 的数据源提供了一种快速有效的方法。 与 Executor 的所有交互都应该是原子的,并且尽可能“简短而甜蜜”,以尽量减少对共享(JDBC 连接)资源的争用; ...

    《Java Web开发与实战--Eclipse+Tomcat+Servlet+JSP整合应用》.(刘伟,张利国).[PDF].zip

    主要内容包括web应用程序运行原理、主流集成开发工具(eclipse/myeclipse)和运行环境(tomcat)的配置和使用、servlet、jsp、jdbc、jsp表达式语言(el)、servlet监听器和过滤器、定制标记库、jstl、mvc模式、dao...

    面试葵花宝典

    14.说出数据连接池的工作机制是什么? 15同步和异步有和异同,在什么情况下分别使用他们?举例说明。 16应用服务器有那些? 17你所知道的集合类都有哪些?主要方法? 18给你一个:驱动程序A,数据源名称为B,用户名称为...

    Java Web开发与实战:Eclipse+Tomcat+Servlet+JSP整合应用(含光盘源代码)

    主要内容包括web应用程序运行原理、主流集成开发工具(eclipse/myeclipse)和运行环境(tomcat)的配置和使用、servlet、jsp、jdbc、jsp表达式语言(el)、servlet监听器和过滤器、定制标记库、jstl、mvc模式、dao...

    Dbutils项目实例

    3 可以使用数据源 使用JNDI 数据库连接池等技术来优化性能 重用已经构建好的数据库连接对象 而不像php asp那样 费时费力的不断重复的构建和析构这样的对象 DBUtils包括3个包: org apache commons dbutils org ...

    Java范例开发大全 (源程序)

     实例200 数据格式转换符的使用 349  11.5 System类的使用 351  实例201 记录程序执行的时间 351  实例202 程序的退出 352  实例203 获取程序运行环境的信息 353  第4篇 Java高级开发技术  第12章 集合...

    Java数据库编程宝典2

    12.3 创建和配置Lo9in servlet 12.3.1 实现会员Web站点 12.3.2 创建Login页面 12.3.3 创建servlet 12.3.4 部署 12.4 使用JSP 12.4.1 在JSP中使用JavaBean 12.4.2 自动类型转换 12.4.3 创建和部署JDBC ...

    Java数据库编程宝典4

    12.3 创建和配置Lo9in servlet 12.3.1 实现会员Web站点 12.3.2 创建Login页面 12.3.3 创建servlet 12.3.4 部署 12.4 使用JSP 12.4.1 在JSP中使用JavaBean 12.4.2 自动类型转换 12.4.3 创建和部署JDBC ...

    Java数据库编程宝典1

    12.3 创建和配置Lo9in servlet 12.3.1 实现会员Web站点 12.3.2 创建Login页面 12.3.3 创建servlet 12.3.4 部署 12.4 使用JSP 12.4.1 在JSP中使用JavaBean 12.4.2 自动类型转换 12.4.3 创建和部署JDBC ...

    Java数据库编程宝典3

    12.3 创建和配置Lo9in servlet 12.3.1 实现会员Web站点 12.3.2 创建Login页面 12.3.3 创建servlet 12.3.4 部署 12.4 使用JSP 12.4.1 在JSP中使用JavaBean 12.4.2 自动类型转换 12.4.3 创建和部署JDBC ...

    java范例开发大全源代码

     实例200 数据格式转换符的使用 349  11.5 System类的使用 351  实例201 记录程序执行的时间 351  实例202 程序的退出 352  实例203 获取程序运行环境的信息 353  第4篇 Java高级开发技术  第12...

    JAVA上百实例源码以及开源项目源代码

    2个目标文件,FTP的目标是:(1)提高文件的共享性(计算机程序和/或数据),(2)鼓励间接地(通过程序)使用远程计算机,(3)保护用户因主机之间的文件存储系统导致的变化,(4)为了可靠和高效地传输,虽然用户...

    java范例开发大全

    实例243 模拟人工服务台(线程连接池) 466 13.6 线程应用实例 471 实例244 下雪的村庄 472 实例245 小飞侠 474 实例246 飞流直下 477 实例247 多线程断点续传 479 实例248 滚动的珠子 485 实例249 余额查询 489 ...

    轻开平台(轻松互联网开发平台,原WebEasy)开发手册 20150915更新

    ODBC数据源的配置文件实例 &lt;Database DbUrl="jdbc:odbc:RealData" DriverName="sun.jdbc.odbc.JdbcOdbcDriver" Name="RealData" age="120" frequency="60" max="3" min="0" pause="5" timesUsed="3" trace="false" ...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part2

    8.4 jdbc数据源和连接池 299 8.5 mysql对中文的处理 302 8.6 小结 302 第9章 会话跟踪 303 9.1 用于会话跟踪的技术 303 9.1.1 ssl会话 304 9.1.2 cookies 304 9.1.3 url重写 305 9.2 java servlet api的会话...

Global site tag (gtag.js) - Google Analytics