JDBC数据源连接池配置及应用

 更新时间:2016年06月14日 10:04:25   作者:kingxss  
这篇文章主要介绍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的语法,大家可以关注:《Thinking in Java 中文手册》、《JDK 1.7 参考手册官方英文版》、《JDK 1.6 API java 中文参考手册》、《JDK 1.5 API java 中文参考手册》,也希望大家多多支持脚本之家。

相关文章

  • Mybatis-Plus查询中如何排除标识字段

    Mybatis-Plus查询中如何排除标识字段

    这篇文章主要介绍了Mybatis-Plus查询中排除标识字段的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • MyBatis-Plus 如何单元测试的实现

    MyBatis-Plus 如何单元测试的实现

    这篇文章主要介绍了MyBatis-Plus 如何单元测试的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • java使用httpclient 发送请求的示例

    java使用httpclient 发送请求的示例

    HttpClient 是Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议,这篇文章主要介绍了java使用httpclient 发送请求的示例,需要的朋友可以参考下
    2023-10-10
  • 基于Spring-AOP实现自定义分片工具详解

    基于Spring-AOP实现自定义分片工具详解

    随着数据量的增长,在与其他系统交互时,批量接口会出现超时现象,发现原批量接口在实现时,没有做分片处理。由于与其他系统交互比较多,一个一个接口去做分片优化,改动量较大,所以考虑通过AOP解决此问题,感兴趣的可以了解一下
    2022-11-11
  • mybatis-plus实现打印完整sql语句

    mybatis-plus实现打印完整sql语句

    这篇文章主要介绍了mybatis-plus实现打印完整sql语句方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • 详解AOP与Filter拦截请求打印日志实用例子

    详解AOP与Filter拦截请求打印日志实用例子

    这篇文章主要介绍了详解AOP与Filter拦截请求打印日志实用例子,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • Java中DecimalFormat用法及符号含义

    Java中DecimalFormat用法及符号含义

    DecimalFormat是NumberFormat的一个具体子类,用于格式化十进制数字。这篇文章介绍了DecimalFormat的用法及符号含义,需要的朋友可以收藏下,方便下次浏览观看
    2021-12-12
  • ssm框架下web项目,web.xml配置文件的作用(详解)

    ssm框架下web项目,web.xml配置文件的作用(详解)

    下面小编就为大家带来一篇ssm框架下web项目,web.xml配置文件的作用(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • 一文详解SpringMVC中的@RequestMapping注解

    一文详解SpringMVC中的@RequestMapping注解

    @RequestMapping是一个用于映射HTTP请求到处理方法的注解,在Spring框架中使用,它可以用于控制器类和处理方法上,用来指定处理不同URL路径的请求,并定义请求的方法等,本文小编将给大家详细的介绍一下SpringMVC中的@RequestMapping注解,需要的朋友可以参考下
    2023-08-08
  • 详解spring cloud config实现datasource的热部署

    详解spring cloud config实现datasource的热部署

    这篇文章主要介绍了详解spring cloud config实现datasource的热部署,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01

最新评论