zoukankan      html  css  js  c++  java
  • JDBC 数据库连接池 小结

    原文:http://www.cnblogs.com/lihuiyy/archive/2012/02/14/2351768.html

    当对数据库的访问不是很频繁时,可以在每次访问数据库时建立一个连接,用完之后关闭。但是,对于一个复杂的数据库应用,频繁的建立、关闭连接,会极大的减低系统性能,造成瓶颈。所以可以使用数据库连接池来达到连接资源的共享,使得对于数据库的连接可以使高效、安全的复用。

    1.通过一个小测试来了解数据库连接池的原理

    (1)创建一个属性文件  dbpool.properties

    1 driverClassName=com.mysql.jdbc.Driver
    2 username=root
    3 password=iloveyou
    4 url=jdbc:mysql://localhost:3306/student
    5 poolSize=5

    (2)创建实现数据库连接池的类文件  ConnectionPool.java

    复制代码
      1 package dbpool;
    2
    3 import java.io.FileInputStream;
    4 import java.io.FileNotFoundException;
    5 import java.io.IOException;
    6 import java.sql.Connection;
    7 import java.sql.SQLException;
    8 import java.util.Properties;
    9 import java.util.Vector;
    10
    11 public class ConnectionPool {
    12 private Vector<Connection> pool;
    13 private String url;
    14 private String username;
    15 private String password;
    16 private String driverClassName;
    17 private int poolSize = 1;
    18 private static ConnectionPool instance = null;
    19
    20 //私有构造方法,禁止外部创建本类的对象,要想获得本类的对象,通过<code>getInstance</code>方法
    21 private ConnectionPool(){
    22 System.out.println("构造函数");
    23 init();
    24 }
    25
    26 //连接池初始化方法,读取属性文件的内容,建立连接池中的初始连接
    27 private void init(){
    28 readConfig();
    29 pool = new Vector<Connection>(poolSize);
    30 addConnection();
    31 }
    32
    33 //返回连接到连接池中
    34 public synchronized void release(Connection coon){
    35 pool.add(coon);
    36 }
    37
    38 //关闭连接池中的所有数据库连接
    39 public synchronized void closePool(){
    40 for (int i = 0; i < pool.size(); i++) {
    41 try {
    42 ((Connection)pool.get(i)).close();
    43 } catch (SQLException e) {
    44 // TODO Auto-generated catch block
    45 e.printStackTrace();
    46 }
    47 pool.remove(i);
    48 }
    49 }
    50
    51 //返回当前连接池的一个对象
    52 public static ConnectionPool getInstance(){
    53 if (instance == null) {
    54 instance = new ConnectionPool();
    55 }
    56 return instance;
    57 }
    58
    59 //返回连接池中的一个数据库连接
    60 public synchronized Connection getConnection(){
    61 if (pool.size() > 0) {
    62 Connection conn = pool.get(0);
    63 pool.remove(conn);
    64 return conn;
    65 }else {
    66 return null;
    67 }
    68 }
    69
    70 //在连接池中创建初始设置的数据库连接
    71 private void addConnection(){
    72 Connection coon = null;
    73 for (int i = 0; i < poolSize; i++) {
    74 try {
    75 Class.forName(driverClassName);
    76 coon = java.sql.DriverManager.getConnection(url, username, password);
    77 pool.add(coon);
    78 } catch (ClassNotFoundException e) {
    79 // TODO Auto-generated catch block
    80 e.printStackTrace();
    81 } catch (SQLException e) {
    82 // TODO Auto-generated catch block
    83 e.printStackTrace();
    84 }
    85 }
    86 }
    87
    88 //读取设置连接池的属性文件
    89 private void readConfig(){
    90 try {
    91 String path = System.getProperty("user.dir") + "\dbpool.properties";
    92 FileInputStream is = new FileInputStream(path);
    93 Properties props = new Properties();
    94 props.load(is);
    95 this.driverClassName = props.getProperty("driverClassName");
    96 this.username = props.getProperty("username");
    97 this.password = props.getProperty("password");
    98 this.url = props.getProperty("url");
    99 this.poolSize = Integer.parseInt(props.getProperty("poolSize"));
    100 } catch (FileNotFoundException e) {
    101 // TODO Auto-generated catch block
    102 e.printStackTrace();
    103 System.err.println("属性文件找不到");
    104 } catch (IOException e) {
    105 // TODO Auto-generated catch block
    106 e.printStackTrace();
    107 System.err.println("读取属性文件出错");
    108 }
    109 }
    110
    111 }
    复制代码

    (3)创建一个使用连接池访问数据库的类文件  ConnectionPoolTest.java

    复制代码
     1 package dbpool;
    2
    3 import java.sql.Connection;
    4 import java.sql.PreparedStatement;
    5 import java.sql.ResultSet;
    6 import java.sql.SQLException;
    7
    8 public class ConnectionPoolTest {
    9 public static void main(String[] args) throws SQLException{
    10 String sql = "select * from user";
    11 ConnectionPool pool = null;
    12
    13 for (int i = 0; i < 2; i++) {
    14 pool = ConnectionPool.getInstance();
    15 Connection conn = pool.getConnection();
    16 PreparedStatement stmt = conn.prepareStatement(sql);
    17 ResultSet rs = stmt.executeQuery(sql);
    18 while (rs.next()) {
    19 System.out.println(rs.getString(1) + " " + rs.getString(2) + " " + rs.getString(3));
    20 }
    21 rs.close();
    22 stmt.close();
    23 pool.release(conn);
    24 }
    25 pool.closePool();
    26 }
    27 }
    复制代码

    2.在开发具体项目时没有必要自己编写数据库连接池,现在已经有很多现成的组件。许多服务器已经内置了数据库连接池,如Tomcat服务器、Jboss服务器和WebLogic服务器等。我自己根据书上的例子,配置了一下Tomcat服务器。配置步骤如下:

    (1)配置Tomcat根目录下的 conf 中的文件 context.xml 如下:

    复制代码
    1 <!--Resource 设置数据库连接池的核心-->
    2 <!--属性 name 数据源的名字 属性 auth 表示验证方式 type 资源的类型 -->
    3 <Resource name="jdbc/DBWater" auth="Container" Type="javax.sql.DataSource"
    4 maxActive="100" maxIdle="30" maxWait="10000"
    5 username="root" password="*******"
    6 driverClassName="com.mysql.jdbc.Driver"
    7 url="jdbc:mysql://localhost:3306/student"/>
    复制代码

    将这段代码添加到<context></context>之间

    (2)修改项目工程目录下 WebRoot/WEB-INF/web.xml 文件:

    复制代码
     1 <resource-ref>
    2 <!-- 描述信息 -->
    3 <description>Connection Pool</description>
    4 <!-- 数据源名字 和上面配置中数据源的名字一致-->
    5 <res-ref-name>jdbc/DBWater</res-ref-name>
    6 <!-- 数据源类型 -->
    7 <res-type>javax.sql.DataSource</res-type>
    8 <res-auth>Container</res-auth>
    9 <res-sharing-scope>Shareable</res-sharing-scope>
    10 </resource-ref>
    复制代码

    下面就可以进行连接池使用了。比如,这里,创建一个DBWater.java文件:

    复制代码
     1 package com.lihui.dbwater;
    2
    3 import java.sql.Connection;
    4 import java.sql.ResultSet;
    5 import java.sql.Statement;
    6
    7 import javax.naming.Context;
    8 import javax.naming.InitialContext;
    9 import javax.naming.NamingException;
    10 import javax.sql.DataSource;
    11
    12 public class DBWater {
    13 String userId;
    14 String name;
    15 String password;
    16
    17 public String getUserId(){
    18 return userId;
    19 }
    20
    21 public String getName(){
    22 return name;
    23 }
    24
    25 public String getpassword(){
    26 return password;
    27 }
    28
    29 public void init(){
    30 try {
    31 InitialContext initC = new InitialContext();//创建InitialContext对象
    32 if (initC == null) {
    33 throw new Exception("No Context");
    34 }
    35 Context context = (Context)initC.lookup("java:comp/env");//不变
    36 DataSource ds = (DataSource)context.lookup("jdbc/DBWater");//tomcat服务器配置文件中数据源名称
    37 if (ds != null) {
    38 Connection conn = ds.getConnection();
    39 if (conn != null) {
    40 Statement statement = conn.createStatement();
    41 ResultSet resultSet = statement.executeQuery("select * from user");
    42 while (resultSet.next()) {
    43 userId = resultSet.getString(1);
    44 name = resultSet.getString(2);
    45 password = resultSet.getString(3);
    46 }
    47 conn.close();
    48 }
    49 }
    50 } catch (NamingException e) {
    51 // TODO Auto-generated catch block
    52 e.printStackTrace();
    53 } catch (Exception e) {
    54 // TODO Auto-generated catch block
    55 e.printStackTrace();
    56 }
    57 }
    58 }
    复制代码

    那么在jsp文件中调用该类:

    复制代码
     1 <%@ page language="java" import="java.util.*" pageEncoding="gb2312"%>
    2 <%@page import="com.lihui.dbwater.DBWater"%>
    3
    4 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    5 <html>
    6 <head>
    7 <title>连接池测试</title>
    8 </head>
    9
    10 <body>
    11 <%
    12 DBWater rs = new DBWater();
    13 rs.init();
    14 %>
    15 id:<%=rs.getUserId() %>
    16 name:<%=rs.getName() %>
    17 psd:<%=rs.getpassword() %>
    18 </body>
    19 </html>
  • 相关阅读:
    做好技术的量的累积,实现业绩的质的飞跃|专访宜信财富技术负责人刘宝剑
    深入理解MySQL索引
    程序的一生:从源程序到进程的辛苦历程
    Serializable详解(1):代码验证Java序列化与反序列化
    关于Java序列化的问题你真的会吗?
    Dubbo源码解析之SPI(一):扩展类的加载过程
    [C#] 命令总线模式
    C#构造函数在继承时必须要求与父类型构造函数入参相同怎么办?
    如何通过JavaScript构建Asp.net服务端控件
    Javascript iframe交互并兼容各种浏览器的解决方案
  • 原文地址:https://www.cnblogs.com/zhuawang/p/5574098.html
Copyright © 2011-2022 走看看