zoukankan      html  css  js  c++  java
  • 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表:

    Sql代码  收藏代码
    1. <span style="font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: x-small;">CREATE TABLE `user` (  
    2.   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
    3.   `username` varchar(50) DEFAULT NULL,  
    4.   `password` varchar(50) DEFAULT NULL,  
    5.   `email` varchar(50) DEFAULT NULL,  
    6.   PRIMARY KEY (`id`),  
    7. );</span>  

     

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

     

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

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

    Java代码  收藏代码
    1. import java.sql.Connection;  
    2. import java.sql.DriverManager;  
    3. /** 
    4.  * 获取数据库连接 
    5.  */  
    6. public class DBConnection {  
    7.       
    8.     /** Oracle数据库连接URL*/  
    9.     private final static String DB_URL = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";  
    10.       
    11.     /** Oracle数据库连接驱动*/  
    12.     private final static String DB_DRIVER = "oracle.jdbc.driver.OracleDriver";  
    13.       
    14.     /** 数据库用户名*/  
    15.     private final static String DB_USERNAME = "root";  
    16.       
    17.     /** 数据库密码*/  
    18.     private final static String DB_PASSWORD = "admin";  
    19.       
    20.     /** 
    21.      * 获取数据库连接 
    22.      * @return 
    23.      */  
    24.     public Connection getConnection(){  
    25.         /** 声明Connection连接对象*/  
    26.         Connection conn = null;  
    27.         try{  
    28.             /** 使用Class.forName()方法自动创建这个驱动程序的实例且自动调用DriverManager来注册它*/  
    29.             Class.forName(DB_DRIVER);  
    30.             /** 通过DriverManager的getConnection()方法获取数据库连接*/  
    31.             conn = DriverManager.getConnection(DB_URL,DB_USERNAME,DB_PASSWORD);  
    32.         }catch(Exception ex){  
    33.             ex.printStackTrace();  
    34.         }  
    35.         return conn;  
    36.     }  
    37.       
    38.     /** 
    39.      * 关闭数据库连接 
    40.      *  
    41.      * @param connect 
    42.      */  
    43.     public void closeConnection(Connection conn){  
    44.         try{  
    45.             if(conn!=null){  
    46.                 /** 判断当前连接连接对象如果没有被关闭就调用关闭方法*/  
    47.                 if(!conn.isClosed()){  
    48.                     conn.close();  
    49.                 }  
    50.             }  
    51.         }catch(Exception ex){  
    52.             ex.printStackTrace();  
    53.         }  
    54.     }  
    55.       
    56. }  

     

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

    Jsp代码  收藏代码
    1. <%@page import="java.sql.*, com.mysql.jdbc.Driver"%>  
    2. <%@ page language="java" contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8"%>  
    3. <html>  
    4. <body>      
    5.     <%  
    6.     //com.mysql.jdbc.Driver  
    7.     Class.forName(Driver.class.getName()).newInstance();  
    8.     String url = "jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF8";  
    9.     String user = "root";  
    10.     String password = "123";  
    11.       
    12.     Connection conn = DriverManager.getConnection(url, user, password);  
    13.     Statement stmt = conn.createStatement();  
    14.       
    15.     String sql = "select * from user";  
    16.     ResultSet rs = stmt.executeQuery(sql);  
    17.       
    18.     while(rs.next()) {  
    19.         out.print("<br />" + "====================" + "<br />");  
    20.         out.print(rs.getLong("id") + "   ");  
    21.         out.print(rs.getString("username") + "   ");  
    22.         out.print(rs.getString("password") + "   ");  
    23.         out.print(rs.getString("email") + "   ");  
    24.     }  
    25.     %>  
    26. </body>  
    27. </html>  

     

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

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

    Jsp代码  收藏代码
    1. <%@page import="java.sql.*, javax.naming.*, javax.sql.DataSource"%>  
    2. <%@ page language="java" contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8"%>  
    3. <html>  
    4. <body>  
    5.     <%  
    6.     Context initCtx = new InitialContext();  
    7.     DataSource ds = (DataSource)initCtx.lookup("java:comp/env/jdbc/demoDB");  
    8.     Connection conn = ds.getConnection();  
    9.       
    10.     Statement stmt = conn.createStatement();  
    11.       
    12.     String sql = "select * from user";  
    13.     ResultSet rs = stmt.executeQuery(sql);  
    14.       
    15.     while(rs.next()) {  
    16.         out.print("<br />" + "====================" + "<br />");  
    17.         out.print(rs.getLong("id") + "   ");  
    18.         out.print(rs.getString("username") + "   ");  
    19.         out.print(rs.getString("password") + "   ");  
    20.         out.print(rs.getString("email") + "   ");  
    21.     }  
    22.     %>  
    23. </body>  
    24. </html>  

     

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

    Xml代码  收藏代码
    1. <Context>   
    2.     <Resource name="jdbc/demoDB" auth="Container"   
    3.     type="javax.sql.DataSource"  
    4.     driverClassName="com.mysql.jdbc.Driver"  
    5.     url="jdbc:mysql://localhost:3306/demo"  
    6.     username="root"  
    7.     password="123"  
    8.     maxActive="50"  
    9.     maxIdle="30"  
    10.     maxWait="10000" />  
    11. </Context>  

     

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

    Xml代码  收藏代码
    1. <resource-ref>  
    2.     <description>mysqlDB Connection</description>  
    3.     <res-ref-name>jdbc/demoDB</res-ref-name>  
    4.     <res-type>javax.sql.DataSource</res-type>  
    5.     <res-auth>Container</res-auth>  
    6. </resource-ref>  

     

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

    Xml代码  收藏代码
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <Context>  
    3.       <Resource name="jdbc/demoDB" auth="Container"   
    4.       type="javax.sql.DataSource"  
    5.       driverClassName="com.mysql.jdbc.Driver"  
    6.       url="jdbc:mysql://localhost:3306/demo"  
    7.       username="root"  
    8.       password="123"  
    9.       maxActive="50"  
    10.       maxIdle="30"  
    11.       maxWait="10000" />  
    12. </Context>  

     

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

    代码如下:

    Java代码  收藏代码
    1. package db.utils;  
    2.   
    3. import java.sql.Connection;  
    4. import java.sql.PreparedStatement;  
    5. import java.sql.ResultSet;  
    6. import java.sql.ResultSetMetaData;  
    7. import java.sql.SQLException;  
    8. import java.sql.Statement;  
    9. import java.text.DateFormat;  
    10. import java.util.ArrayList;  
    11. import java.util.Date;  
    12. import java.util.HashMap;  
    13. import java.util.List;  
    14. import java.util.Map;  
    15.   
    16. import javax.naming.InitialContext;  
    17. import javax.sql.DataSource;  
    18.   
    19. //import org.apache.log4j.Logger;  
    20.   
    21. /** 
    22.  * 数据库操作辅助类 
    23.  */  
    24. public class DbUtils {  
    25.       
    26.     //private static Logger logger = Logger.getLogger("DbUtils");  
    27.       
    28.     /** 
    29.      * 该语句必须是一个 SQL INSERT、UPDATE 或 DELETE 语句 
    30.      * @param sql 
    31.      * @param paramList:参数,与SQL语句中的占位符一一对应 
    32.      * @return 
    33.      * @throws Exception 
    34.      */  
    35.     public int execute(String sql, List<Object> paramList) throws Exception {  
    36.         if(sql == null || sql.trim().equals("")) {  
    37.             //logger.info("parameter is valid!");  
    38.         }  
    39.   
    40.         Connection conn = null;  
    41.         PreparedStatement pstmt = null;  
    42.         int result = 0;  
    43.         try {  
    44.             conn = getConnection();  
    45.             pstmt = DbUtils.getPreparedStatement(conn, sql);  
    46.             setPreparedStatementParam(pstmt, paramList);  
    47.             if(pstmt == null) {  
    48.                 return -1;  
    49.             }  
    50.             result = pstmt.executeUpdate();  
    51.         } catch (Exception e) {  
    52.             //logger.info(e.getMessage());  
    53.             throw new Exception(e);  
    54.         } finally {  
    55.             closeStatement(pstmt);  
    56.             closeConn(conn);  
    57.         }  
    58.   
    59.         return result;  
    60.     }  
    61.       
    62.     /** 
    63.      * 将查询数据库获得的结果集转换为Map对象 
    64.      * @param sql:查询语句 
    65.      * @param paramList:参数 
    66.      * @return 
    67.      */  
    68.     public List<Map<String, Object>> getQueryList(String sql, List<Object> paramList) throws Exception {  
    69.         if(sql == null || sql.trim().equals("")) {  
    70.             //logger.info("parameter is valid!");  
    71.             return null;  
    72.         }  
    73.   
    74.         Connection conn = null;  
    75.         PreparedStatement pstmt = null;  
    76.         ResultSet rs = null;  
    77.         List<Map<String, Object>> queryList = null;  
    78.         try {  
    79.             conn = getConnection();  
    80.             pstmt = DbUtils.getPreparedStatement(conn, sql);  
    81.             setPreparedStatementParam(pstmt, paramList);  
    82.             if(pstmt == null) {  
    83.                 return null;  
    84.             }  
    85.             rs = getResultSet(pstmt);  
    86.             queryList = getQueryList(rs);  
    87.         } catch (RuntimeException e) {  
    88.             //logger.info(e.getMessage());  
    89.             System.out.println("parameter is valid!");  
    90.             throw new Exception(e);  
    91.         } finally {  
    92.             closeResultSet(rs);  
    93.             closeStatement(pstmt);  
    94.             closeConn(conn);  
    95.         }  
    96.         return queryList;  
    97.     }  
    98.       
    99.     private void setPreparedStatementParam(PreparedStatement pstmt, List<Object> paramList) throws Exception {  
    100.         if(pstmt == null || paramList == null || paramList.isEmpty()) {  
    101.             return;  
    102.         }  
    103.         DateFormat df = DateFormat.getDateTimeInstance();  
    104.         for (int i = 0; i < paramList.size(); i++) {  
    105.             if(paramList.get(i) instanceof Integer) {  
    106.                 int paramValue = ((Integer)paramList.get(i)).intValue();  
    107.                 pstmt.setInt(i+1, paramValue);  
    108.             } else if(paramList.get(i) instanceof Float) {  
    109.                 float paramValue = ((Float)paramList.get(i)).floatValue();  
    110.                 pstmt.setFloat(i+1, paramValue);  
    111.             } else if(paramList.get(i) instanceof Double) {  
    112.                 double paramValue = ((Double)paramList.get(i)).doubleValue();  
    113.                 pstmt.setDouble(i+1, paramValue);  
    114.             } else if(paramList.get(i) instanceof Date) {  
    115.                 pstmt.setString(i+1, df.format((Date)paramList.get(i)));  
    116.             } else if(paramList.get(i) instanceof Long) {  
    117.                 long paramValue = ((Long)paramList.get(i)).longValue();  
    118.                 pstmt.setLong(i+1, paramValue);  
    119.             } else if(paramList.get(i) instanceof String) {  
    120.                 pstmt.setString(i+1, (String)paramList.get(i));  
    121.             }  
    122.         }  
    123.         return;  
    124.     }  
    125.       
    126.     /** 
    127.      * 获得数据库连接 
    128.      * @return 
    129.      * @throws Exception 
    130.      */  
    131.     private Connection getConnection() throws Exception {  
    132.         InitialContext cxt = new InitialContext();  
    133.         DataSource ds = (DataSource) cxt.lookup(jndiName);  
    134.         if ( ds == null ) {  
    135.            throw new Exception("Data source not found!");  
    136.         }  
    137.           
    138.         return ds.getConnection();  
    139.     }  
    140.       
    141.     private static PreparedStatement getPreparedStatement(Connection conn, String sql) throws Exception {  
    142.         if(conn == null || sql == null || sql.trim().equals("")) {  
    143.             return null;  
    144.         }  
    145.         PreparedStatement pstmt = conn.prepareStatement(sql.trim());  
    146.         return pstmt;  
    147.     }  
    148.       
    149.     /** 
    150.      * 获得数据库查询结果集 
    151.      * @param pstmt 
    152.      * @return 
    153.      * @throws Exception 
    154.      */  
    155.     private ResultSet getResultSet(PreparedStatement pstmt) throws Exception {  
    156.         if(pstmt == null) {  
    157.             return null;  
    158.         }  
    159.         ResultSet rs = pstmt.executeQuery();  
    160.         return rs;  
    161.     }  
    162.       
    163.     /** 
    164.      * @param rs 
    165.      * @return 
    166.      * @throws Exception 
    167.      */  
    168.     private List<Map<String, Object>> getQueryList(ResultSet rs) throws Exception {  
    169.         if(rs == null) {  
    170.             return null;  
    171.         }  
    172.         ResultSetMetaData rsMetaData = rs.getMetaData();  
    173.         int columnCount = rsMetaData.getColumnCount();  
    174.         List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>();  
    175.         while (rs.next()) {  
    176.             Map<String, Object> dataMap = new HashMap<String, Object>();  
    177.             for (int i = 0; i < columnCount; i++) {  
    178.                 dataMap.put(rsMetaData.getColumnName(i+1), rs.getObject(i+1));  
    179.             }  
    180.             dataList.add(dataMap);  
    181.         }  
    182.         return dataList;  
    183.     }  
    184.       
    185.     /** 
    186.      * 关闭数据库连接 
    187.      * @param conn 
    188.      */  
    189.     private void closeConn(Connection conn) {  
    190.         if(conn == null) {  
    191.             return;  
    192.         }  
    193.         try {  
    194.             conn.close();  
    195.         } catch (SQLException e) {  
    196.             //logger.info(e.getMessage());  
    197.         }  
    198.     }  
    199.       
    200.     /** 
    201.      * 关闭 
    202.      * @param stmt 
    203.      */  
    204.     private void closeStatement(Statement stmt) {  
    205.         if(stmt == null) {  
    206.             return;  
    207.         }  
    208.         try {  
    209.             stmt.close();  
    210.         } catch (SQLException e) {  
    211.             //logger.info(e.getMessage());  
    212.         }  
    213.     }  
    214.       
    215.     /** 
    216.      * 关闭 
    217.      * @param rs 
    218.      */  
    219.     private void closeResultSet(ResultSet rs) {  
    220.         if(rs == null) {  
    221.             return;  
    222.         }  
    223.         try {  
    224.             rs.close();  
    225.         } catch (SQLException e) {  
    226.             //logger.info(e.getMessage());  
    227.         }  
    228.     }  
    229.       
    230.       
    231.     private String jndiName = "java:/comp/env/jdbc/demoDB";  
    232.   
    233.     public void setJndiName(String jndiName) {  
    234.         this.jndiName = jndiName;  
    235.     }  

    原文:http://kingxss.iteye.com/blog/1479451

  • 相关阅读:
    【Azure Redis 缓存】Azure Redis 功能性讨论二
    【Azure Developer】如何用Microsoft Graph API管理AAD Application里面的Permissions
    【Azure 环境】通过Python SDK收集所有订阅简略信息,例如订阅id 名称, 资源组及组内资源信息等,如何给Python应用赋予相应的权限才能获取到信息呢?
    【Azure 应用服务】App Service与APIM同时集成到同一个虚拟网络后,如何通过内网访问内部VNET的APIM呢?
    【Azure 云服务】如何从Azure Cloud Service中获取项目的部署文件
    【Azure Redis 缓存】Azure Redis 异常
    【Azure 微服务】基于已经存在的虚拟网络(VNET)及子网创建新的Service Fabric并且为所有节点配置自定义DNS服务
    【Azure Redis 缓存】遇见Azure Redis不能创建成功的问题:至少一个资源部署操作失败,因为 Microsoft.Cache 资源提供程序未注册。
    【Azure Redis 缓存】如何得知Azure Redis服务有更新行为?
    【Azure API 管理】在 Azure API 管理中使用 OAuth 2.0 授权和 Azure AD 保护 Web API 后端,在请求中携带Token访问后报401的错误
  • 原文地址:https://www.cnblogs.com/bohanfu/p/5709994.html
Copyright © 2011-2022 走看看