数据库连接池技术

目录

  • 目录
    • JDBC 操作数据库
      • JDBC-ODBC 桥
      • JDBC 连接数据库
    • DBCP 连接池
    • TOMCAT 连接池
    • C3P0 连接池
    • Druid连接池

JDBC 操作数据库

<提示:JDBC -ODBC 桥连接已经不再广泛使用. 淘汰的技术>

JDBC-ODBC 桥

JDBC-ODBC桥是一个JDBC驱动程序。完成了从JDBC操作带ODBC操作之间的转换工作。允许JDBC驱动程序被用作ODBC的驱动程序。使用JDBC-ODBC桥连接数据库的步骤是:

(1) 首先加载JDBC-ODBC桥的驱动程序。代码如下:
Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);
Class类是java.lang包中的一个类,通过该类的静态方法forName()可加载sun.jdbc.odbc包中的JdbcOdbcDriver类来建立JDBC-ODBC桥连接器。

(2)使用java.sql包中的Connection接口,并通过DriverManager类的静态方法getConnection()创建连接对象。格式如下:
Connection conn = DriverManager.getConnection(“jdbc:odbc:数据源名字” , “user name” , “password”);
数据源必须给出一个简短的描述名。假设没有设置user name和password,要与数据源tom交换数据,建立Connection对象的代码如下:
Connection conn = DriverManager.getConnection(“jdbc.odbc:tom”,”“,”“);

(3)向数据库发送SQL语句。使用Statement接口声明一个SQL语句对象,并通过刚才创建的连接数据库对象conn的createStatement()方法创建这个SQL对象。代码如下:
Statement sql = conn.createStatement();
JDBC-ODBC桥作为连接数据库的过渡性技术,现在已经不被Java技术广泛应用,现在广泛应用的是JDBC技术。但并不表示JDBC-ODBC桥技术已经被淘汰。由于ODBC技术被广泛地使用,使得Java可以利用JDBC-ODBC桥可以访问几乎所有的数据库。JDBC-ODBC桥作为sun.jdbc.odbc包与JDK一起自动安装,不需要特殊配置。

1.通过JDBC-ODBC 桥连接SQL Server 数据库
建立数据库连接,需要指定数据库的驱动和路径。
指定驱动:
String driverClass=”sun.jdbc.odbc.JdbcOdbcDriver”;

采用JDBC-ODBC方式连接数据库,该参数指定的是连接方式,并不需要引入驱动包。
指定路径:
String url=”jdbc:odbc:db_database05”;

以下是win10操作系统中的ODBC 配置

1.打开控制面板-管理工具-找到ODBC数据源-系统DSN-添加
如下图:

数据库连接池技术_第1张图片

数据库连接池技术_第2张图片

由于基本上用不到所以只是做个简介.

JDBC 连接数据库

JDBC是Java连接数据库的一种非常快速和有效的方法。但是JDBC不能直接使用,必须配合数据库提供商所提供的数据库连接驱动才能实现数据库的连接。

使用JDBC连接数据库主要分为3个步骤:获取数据库连接驱动、指定数据库连接字符串和通过驱动管理器管理驱动。
获取数据库连接的驱动,在Java中主要使用Class.forName来实现。Class 类的实例表示正在运行的Java应用程序中的类和接口。其自身并没有公共构造方法,Class 类是在加载时由 Java 虚拟机及通过调用类加载器中的defineClass方法自动构造的。
数据库连接字符串主要由连接数据库所使用驱动器、服务器的IP地址、数据库名称以及连接用户名和密码几部分组成。
通过驱动管理器管理驱动是使用DriverManager类来实现的,该类的主要功能是将数据库连接字符串转换成与其对应的数据库连接接口,以实现数据库的连接。

连接数据库

import java.sql.*; //导入java.sql包
public class Conn { // 创建类Conn
      Connection con; // 声明Connection对象
      public Connection getConnection(){                    //建立返回值为Connection的方法
                  try {
                        // 加载驱动
                        Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
                        System.out.println("数据库驱动加载成功");                                       (1)
                  } catch (ClassNotFoundException e) {
                         e.printStackTrace();
                  }
                  try {
                        // 连接数据库
                        con=DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433;" +
                                    "DatabaseName=db_jdbc","sa","");                                                                            (2)
                        System.out.println("数据库连接成功");
                  } catch (SQLException e) {
                        e.printStackTrace();
                  } 
                  return con;                                                 //按方法要求返回个Connection对象
            }
       // 主方法
      public static void main(String[] args) {
            Conn c = new Conn(); // 创建本类对象
            c.getConnection(); // 调用连接数据库方法
      }
}

* 向数据库发送SQL 语句 *
实例getConnection()方法,只是获取与数据库的连接。要执行SQL语句首先要获得Statement类对象。通过创建的连接数据库对象con的createStatement()方法可获得Statement对象。

try {
   Statement sql = con.createStatement();
} catch (SQLException e) {
   e.printStackTrace();
}

* 处理查询结果集

有了Statement对象以后,可调用相应的方法实现对数据库的查询和修改。并将查询的结果集存放在ResultSet类的对象中。例如如下语句可返回一个ResultSet对象

try {
   Connection con = ....   // 省略部分代码
   // 获取 Statement
   Statement stmt = con.createStatement();
   // 获取结果集
   ResultSet res = stmt.executeQuery("select * from tb_emp");
   res.close();
   stmt.close();
   con.close();
} catch (Exception e) {
   e.printStackTrace();
}

运行结果为返回一个ResultSet对象,ResultSet对象一次只可以看到结果集中的一行数据,使用该类的next()方法可将光标从当前位置向后或下移一行。

* 顺序查询*
ResultSet类的next()方法的返回值是boolean类型的数据,当游标移动到最后一行之后会返回false。下面的实例就是将数据表tb_emp中的全部信息显示在控制台上。

import java.sql.*; //导入java.sql包

public class Gradation { // 创建类
   static Connection con; // 声明Connection对象
   static Statement sql; // 声明Statement对象
   static ResultSet res; // 声明ResultSet对象

   public Connection getConnection() { // 连接数据库方法
      try {
         // 加载驱动
         Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
         // 创建数据库连接
         con = DriverManager.getConnection(
               "jdbc:microsoft:sqlserver://localhost:1433;"
                     + "DatabaseName=db_jdbc", "sa", "111");
      } catch (Exception e) {
         e.printStackTrace();
      }
      return con;
   }
   public static void main(String[] args) { // 主方法
      Gradation c = new Gradation(); // 创建本类对象
      con = c.getConnection(); // 与数据库建立连接
      try {
         sql = con.createStatement(); // 实例化Statement对象
         res = sql.executeQuery("select * from tb_stu"); // 执行SQL语句,返回结果集
         while (res.next()) { // 如果当前语句不是最后一条则进入循环
            String id = res.getString("id"); // 获取列名是“id”的字段值
            String name = res.getString("name"); // 获取列名是“name”的字段值
            String sex = res.getString("sex"); // 获取列名是“sex”的字段值
            String brithday = res.getString("brithday"); // 获取列名是“brithday”的字段值
            System.out.print("编号:" + id); // 将列值输出
            System.out.print(" 姓名:" + name);
            System.out.print(" 性别:" + sex);
            System.out.println(" 生日:" + brithday);
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

* 模糊查询 *

SQL语句中提供了LIKE操作符进行模糊查询,可使用“%”来代替0个或多个字符,使用下划线“_”来代替一个字符。例如,查询姓张的同学信息,SQL语句如下。

import java.sql.*; //导入java.sql包

public class Train { // 创建类Train
   static Connection con; // 声明Connection对象
   static Statement sql; // 声明Statement对象
   static ResultSet res; // 声明ResultSet对象

   public Connection getConnection() { // 与数据库连接方法
      try {
         Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
         con = DriverManager.getConnection(
               "jdbc:microsoft:sqlserver://localhost:1433;"
                     + "DatabaseName=db_jdbc", "sa", "");
      } catch (Exception e) {
         e.printStackTrace();
      }
      return con;
   }

   public static void main(String[] args) { // 主方法
      Train c = new Train(); // 创建本类对象
      con = c.getConnection(); // 获取与数据库的连接
      try { // try语句捕捉异常
         sql = con.createStatement(); // 实例化Statement对象
         res = sql.executeQuery("select * from tb_stu where name like '张%'");// 执行SQL语句
         while (res.next()) { // 如果当前记录不是结果集中的最后一条,进入循环体
            String id = res.getString(1); // 获取id字段值
            String name = res.getString("name"); // 获取name字段值
            String sex = res.getString("sex"); // 获取sex字段值
            String brithday = res.getString("brithday"); // 获取brithday字段值
            System.out.print("编号:" + id); // 输出信息
            System.out.print(" 姓名:" + name);
            System.out.print(" 性别:" + sex);
            System.out.println(" 生日:" + brithday);
         }
      } catch (Exception e) { // 处理异常
         e.printStackTrace(); // 输出异常信息
      }
   }
}

* 预处理语句 *

向数据库发送一个SQL语句,数据库中的SQL解释器负责把SQL语句生成底层的内部命令,然后执行该命令。完成相关的数据操作。如果不断地向数据库提交SQL语句肯定会增加数据库中SQL解释器的负担。影响执行的速度。
对于JDBC,可以通过Connection对象的prepareStatement(String sql)方法对SQL语句进行编译预处理,生成数据库底层的内部命令,并将该命令封装在PreparedStatement对象中。通过调用该对象的相应方法执行底层数据库命令。这样应用程序能针对连接的数据库,实现将SQL语句解释为数据库底层的内部命令,然后让数据库执行这个命令,这样可以减轻数据库的负担,提供了访问数据库的速度。
对SQL进行预处理时可以通过使用通配符“?”来代替任何的字段值。例如:

sql = con.prepareStatement("select * from tb_stu where id = ?");

在执行预处理语句前,必须相应方法来设置通配符所表示的值。例如:
sql.setInt(1,2);
上述语句中的“1”表示从左向右的第几个通配符。“2”表示设置的通配符的值。将通配符的值设置为2后,功能等同于:

sql = con.prepareStatement("select * from tb_stu where id = 2”);

尽管书写两条语句,看似麻烦了一些,但使用预处理语句可使应用程序更容易动态的改变SQL语句中关于字段值条件的设定。
注意:通过setXXX()方法为SQL语句中的参数赋值时,建议利用与参数匹配的方法,也可以利用setObject()方法为各种类型的参数赋值。例如:
sql.setObject(2,’李丽’);
例 本实例预处理语句动态的获取制定编号的同学信息,本实例以查询编号为2的同学信息为例结果预处理语句的用法。

import java.io.*;
import java.sql.*;
public class Prep {                       //创建类Perp
   static Connection con;                 //声明Connection对象
   static PreparedStatement sql;          //声明预处理对象
   static ResultSet res;                  //声明结果集对象
   public Connection getConnection() {    //与数据库连接方法
      try {
         Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
         con = DriverManager.getConnection(
               "jdbc:microsoft:sqlserver://localhost:1433;"
                     + "DatabaseName=db_jdbc", "sa", "");
      } catch (Exception e) {
         e.printStackTrace();
      }
      return con;
   }
   public static void main(String[] args) {   //主方法
      Prep c = new Prep ();                   //创建本类对象
      con = c.getConnection();                //获取与数据库的连接
      try {          
         sql = con.prepareStatement("select * from tb_stu where id = ?"); //实例化预处理对象
         sql.setInt(1, 2);                        //设置参数
         res = sql.executeQuery();               //执行预处理语句
         while (res.next()) {                    //如果当前记录不是结果集中最后一行,则进入循环体
            String id = res.getString(1);        //获取结果集中的第一列的值
            String name = res.getString("name"); //获取name列的列值
            String sex = res.getString("sex");   //获取sex列的列值
            String brithday = res.getString("brithday");    //获取brithday列的列值
            System.out.print("编号:" + id);          //输出信息
            System.out.print(" 姓名:" + name);
            System.out.print(" 性别:" + sex);
            System.out.println(" 生日:" + brithday);
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

* 添加 修改 删除记录 *
可以通过SQL语句对数据进行添加、修改和删除操作。可通过PreparedStatement类的指定参数动态的对数据表中原有数据进行修改操作。并通过executeUpdate()方法执行更新语句。

import java.sql.*; //导入java.sql包
public class Renewal { // 创建类
   static Connection con; // 声明Connection对象
   static PreparedStatement sql; // 声明PreparedStatement对象
   static ResultSet res; // 声明ResultSet对象

   // 建立返回值为Connection的方法
   public Connection getConnection() {
      try {
         // 加载数据库驱动
         Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
         // 创建数据库连接
         con = DriverManager.getConnection(
               "jdbc:microsoft:sqlserver://localhost:1433;"
                     + "DatabaseName=db_jdbc", "sa", "111");
      } catch (Exception e) {
         e.printStackTrace();
      }
      // 按方法要求返回个Connection对象
      return con;
   }
   // 主方法
   public static void main(String[] args) {
      Renewal c = new Renewal(); // 创建本类对象
      con = c.getConnection(); // 调用连接数据库方法
      try {
         sql = con.prepareStatement("select * from tb_stu"); // 查询数据库
         res = sql.executeQuery(); // 执行SQL语句
         System.out.println("执行增加、修改、删除前数据:");
         // 遍历查询结果集
         while (res.next()) {
            String id = res.getString(1);
            String name = res.getString("name");
            String sex = res.getString("sex");
            String brithday = res.getString("brithday");
            System.out.print("编号:" + id);
            System.out.print(" 姓名:" + name);
            System.out.print(" 性别:" + sex);
            System.out.println(" 生日:" + brithday);
         }
         // 创建PrepareStatement对象
         sql = con.prepareStatement("insert into tb_stu values(?,?,?,?)");
         sql.setInt(1, 10);
         sql.setString(2, "张宏"); // 预处理添加数据
         sql.setString(3, "女");
         sql.setString(4, "1993-10-20");
         sql.executeUpdate();
         // 创建PrepareStatement对象
         sql = con
               .prepareStatement("update tb_stu set brithday = ? where id = ?");
         sql.setString(1, "1994-11-02"); // 更新数据
         sql.setInt(2, 2);
         sql.executeUpdate();
         // 创建PrepareStatement对象
         sql = con.prepareStatement("delete from tb_stu where id = ?");
         sql.setInt(1, 1); // 删除数据
         sql.executeUpdate();
         // 查询修改数据后的tb_stu表中数据
         sql = con.prepareStatement("select * from tb_stu");
         res = sql.executeQuery(); // 执行SQL语句
         System.out.println("执行增加、修改、删除后的数据:");
         // 遍历查询结果集
         while (res.next()) {
            String id = res.getString(1);
            String name = res.getString("name");
            String sex = res.getString("sex");
            String brithday = res.getString("brithday");
            System.out.print("编号:" + id);
            System.out.print(" 姓名:" + name);
            System.out.print(" 性别:" + sex);
            System.out.println(" 生日:" + brithday);
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

* Connection 接口 *

数据库连接池技术_第3张图片

* Statement 接口 *

数据库连接池技术_第4张图片

* PreparedStatement *

数据库连接池技术_第5张图片

* DriverManager 类*
数据库连接池技术_第6张图片

ResultSet

数据库连接池技术_第7张图片

数据库连接池技术_第8张图片

开发步骤

(1)数据库连接类的实现,代码如下:

<%! 
    Connection Con;
    public boolean Con() throws SQLException{
        try
        { 
             Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
             String URL = "jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=db_database05";
             String user="sa"; 
             String password="";  
             Con = DriverManager.getConnection(URL,user,password);
             return true;
        }
        catch(ClassNotFoundException e)
        {
             return false; 
        }
    }
%>

(2)连接数据库并显示连接成功与失败的提示,代码如下:

<%
if (Con()){
   out.println("数据库连接成功!");
}
else{
   out.println("数据库连接失败!");
}
%>

程序完整代码:

<%@ page language="java" import="java.sql.*" import="java.util.*" pageEncoding="GB2312"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%! 
      Connection Con;
      public boolean Con() throws SQLException{
            try
            { 
                  Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
                  String URL = "jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=db_database05";
                  String user="sa"; 
                  String password="";  
                  Con = DriverManager.getConnection(URL,user,password);
                  return true;
            }
            catch(ClassNotFoundException e)
            {
                  return false; 
            }
      }
%>

<html>
  <head>
    <base href="<%=basePath%>">

    <title>通过JDBC连接SQL Server数据库title>

      <meta http-equiv="pragma" content="no-cache">
      <meta http-equiv="cache-control" content="no-cache">
      <meta http-equiv="expires" content="0">    
      <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
      <meta http-equiv="description" content="This is my page">
      

  <meta http-equiv="Content-Type" content="text/html; charset=gb2312"><style type="text/css">
--
body {
      background-image: url();
}
.style1 {
      color: #FFFFFF;
      font-weight: bold;
}
-->
  style>head>

  <body>
            <div align="center">
                  <table width="546" height="196" border="0" cellpadding="0"
                        cellspacing="0" background="1.gif">
                        <tr>
                              <td valign="middle">
                                    <div align="center">
                                          <div align="center">
                                                <p>
                                                      <%
                                                               if (Con()) {
                                                               out.println("数据库连接成功!");
                                                        } else {
                                                               out.println("数据库连接失败!");
                                                        }
                                                      %>
                                                      <br> 
                                              <% 
                                          String SQL = "Select * From ClassList_Tab";
                                          Statement Smt; 
                                 ResultSet Rs;
                                 Smt = Con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
                                 Rs = Smt.executeQuery(SQL);
                                          %> 
                                            p>
                                                <table width="413" border="0" cellspacing="0" cellpadding="0">
                                  <tr>
                                    <td width="86"><div align="left">课程列表div>td>
                                    <td width="80"><div align="left">课程名称div>td>
                                    <td width="82"><div align="left">开课时间div>td>
                                    <td width="78"><div align="left">学时div>td>
                                    <td width="87"><div align="left">课程类别div>td>
                                  tr>
                                  <% 
                                  for (int i=0 ;i<2 ;i++){
                                  Rs.next();
                                  %>
                                  <tr>
                                    <td><div align="left"><%=Rs.getString("CID")%>div>td>
                                    <td><div align="left"><%=Rs.getString("CName")%>div>td>
                                    <td><div align="left"><%=Rs.getString("CStartDate")%>div>td>
                                    <td><div align="left"><%=Rs.getString("CPeriod")%>div>td>
                                    <td><div align="left"><%=Rs.getString("CType")%>div>td>
                                  tr>
                                  <% 
                                  }
                                  %>
                                table>
                                                <p> 

                                            p>
                                                <p>

                                                p>
                                          div>
                                    div>
                              td>
                        tr>
              table>
                  <p> 

              p>
            div>
  body>
html>

DBCP 连接池

本实例在使用数据库连接池连接数据库的时候主要用到了BasicDataSource类,BasicDataSource类位于org.apache.tomcat.dbcp.dbcp包中,声明语法如下所示:

public class BasicDataSource extends Object implements DataSource
BasicDataSource类主要通过JavaBeans的形式来配置数据库连接池参数。

(1)setDriverClassName()方法,用于设置数据库驱动类,声明语法如下所示:

public void setDriverClassName(String driverClassName)

driverClassName:数据库驱动类名称。
在本实例中设置数据库驱动类的关键代码如下所示:

……//省略部分代码
bds = new BasicDataSource();
bds.setDriverClassName("com.mysql.jdbc.Driver");

(2)setUrl()方法,用于设置数据库连接字符串,声明语法如下所示:
public void setUrl(String url)
url:连接数据库字符串。
在本实例中设置数据库连接字符串的关键代码如下所示:

……//省略部分代码
bds = new BasicDataSource();
bds.setUrl("jdbc:mysql://localhost:3306/db_database02");

(3)setUsername()方法用于设置连接数据库的用户名,声明语法如下所示:
public void setUsername(String username)
username:数据库用户名。
在本实例中设置连接数据库用户名的关键代码如下所示:

……//省略部分代码
bds = new BasicDataSource();
bds.setUsername("mr");

(4)setPassword()方法用于设置连接数据库的密码,声明语法如下所示:

public void setPassword(String password)

password:数据库密码。
在本实例中设置连接数据库密码的关键代码如下所示:

……//省略部分代码
bds = new BasicDataSource();
bds.setPassword("mrsoft");

(5)setInitialSize()方法用于设置数据库连接池初始化的时候创建的连接数量,声明语法如下所示:

public void setInitialSize(int initialSize)

initialSize:连接池初始连接数量。
在本实例中将连接池初始化时的连接数量设置为5,关键代码如下所示:

……//省略部分代码
bds = new BasicDataSource();
dbs.setInitialSize(5);

(6)setMinIdle()方法用于设置连接池内空闲连接的最小数量,声明语法如下所示:

public void setMaxIdle(int maxIdle)

maxIdle:最小空闲连接数。
在本实例中将最小空闲连接数量设置为2,关键代码如下所示:

……//省略部分代码
bds = new BasicDataSource();
bds.setMinIdle(2);

(7)setMaxActive()方法用于设置连接池内最大活动连接的数量。

public void setMaxActive(int maxActive)

maxActive:最大活动连接数。
在本实例中将最大活动连接数量设置5,关键代码如下所示:

……//省略部分代码
bds = new BasicDataSource();
bds.setMaxActive(5);

(8)setMaxWait()方法用于设置当池内没有可用连接时,等待的最大时间,声明语法如下所示:

public void setMaxWait(long maxWait)

maxWait:最大等待时间。
在本实例中将等待的最大时间设置为10000毫秒,关键代码如下所示:

……//省略部分代码
bds = new BasicDataSource();
bds.setMaxWait(10000);

(9)setMaxIdle()方法用于设置连接池内最大空闲连接的数量。

public void setMinIdle(int minIdle)

minIdle:最大空闲连接数。
在本实例中将连接池内允许的最大空闲连接数量设置为4,关键代码如下所示:

……//省略部分代码
bds = new BasicDataSource();
bds.setMaxIdle(4);

(10)getConnection()方法用于从连接池中获取连接,声明语法如下所示:

public Connection getConnection() throws SQLException

在本实例中获取数据库连接,关键代码如下所示:

……//省略部分代码
bds = new BasicDataSource();
Connection con = bds.getConnection();

(1)编写DBPool类,用于初始化一个数据库连接池,关键代码如下所示:

public class DBPool {
    public static BasicDataSource bds;                     //声明静态的BasicDataSource
    private static DBPool dbPool;                      //声明静态的DBPool
    private static String driver = "com.mysql.jdbc.Driver";              //数据库驱动类
    private static String url = "jdbc:mysql://localhost:3306/db_database02";            //数据库连接字符串
    private static String name = "mr";         //数据库用户名
    private static String password = "mrsoft";    //数据库密码
    static {
        dbPool = new DBPool();              //实例化一个DBPool对象
    }
    //构造方法
    public DBPool() {
        bds = new BasicDataSource();             //创建BasicDataSource对象
        //配置数据库连接参数
        bds.setDriverClassName(driver);   //数据库驱动
        bds.setUrl(url);                   //数据库连接字符串
        bds.setUsername(name);              //数据库名称
        bds.setPassword(password);        //数据库密码
        bds.setInitialSize(5);             //初始化时连接数量
        bds.setMinIdle(2);                //最小空闲连接数
        bds.setMaxActive(5);            //最大活动连接数
        bds.setMaxWait(10000);              //最大等待时间,单位毫秒
        bds.setMaxIdle(4);               //最大空闲连接数
    }
}

(2)在DBPool类中编写getInstance()方法和getConnection()方法,用于从连接池中获取连接,关键代码如下所示:

public final Connection getConnection() {
    try {
        return bds.getConnection(); //返回一个数据库连接
    } catch (SQLException ex) {
        ex.printStackTrace();
        return null;                   //如果出现异常返回null
    }
}
public final static DBPool getInstance() {
    return dbPool;
}

(3)在DBPool类中编写freeConnection()方法,用于将使用完的数据库连接释放,关键代码如下所示:

public final static void freeConnection(Connection conn) {
    if (conn != null) {
        try {
            conn.close();              //关闭连接
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

使用DBCP连接池需要commons.dbcp.jar,同时DBCP连接池还依赖Apache的另外2个开源项目commons.collections.jar和commons.pool.jar,这些jar包都可以在http://www.apache.org上下载到,下载这三个jar包并将其添加到项目中就可以使用了。在Tomcat服务器中已经内置了DBCP连接池所需要的包,所以在使用Tomcat服务器时不需要另外下载jar文件了。

(4)新建demo.jsp页面,用于显示在不同情况下,连接池内连接数量的变化情况,关键代码如下所示:

<html>
    <body>
        
        --------------------连接池初始化---------------------- <br>
        初始化连接数:<%= DBPool.bds.getInitialSize()%><br>
        最小空闲连接数:<%= DBPool.bds.getMinIdle()%><br>
        最大空闲连接数:<%= DBPool.bds.getMaxIdle()%><br>
        最大等待时间(毫秒):<%= DBPool.bds.getMaxWait()%><br>
        最大活动连接数:<%= DBPool.bds.getMaxActive()%><br>
        当前活动的连接数:<%= DBPool.bds.getNumActive()%><br>
        当前空闲的连接数:<%= DBPool.bds.getNumIdle()%><br>
        <table width="700px" align="center" border="1">
            <tr align="center">
                <td width="80px">员工编号td>
                <td width="90px">员工姓名td>
                <td width="80px">员工姓别td>
                <td width="80px">员工年龄td>
                <td width="200px">所在部门td>
                <td>职务td>
            tr>
            
        <%
        Connection con = DBPool.getInstance().getConnection();
        Statement st = con.createStatement();
        ResultSet rs = st.executeQuery("SELECT * FROM tb_employee");
        while(rs.next()){
        %>
            <tr align="center">
                <td><%= rs.getInt("id") %>td>
                <td><%= rs.getString("name") %>td>
                <td><%= rs.getString("sex") %>td>
                <td><%= rs.getString("age") %>td>
                <td><%= rs.getString("dept") %>td>
                <td><%= rs.getString("duty") %>td>
            tr>
        <%
        }
        rs.close();
        st.close();
        %>
        table>
        --------------------调用获得连接方法之后---------------------- <br>
        当前活动的连接数:<%= DBPool.bds.getNumActive()%><br>
        当前空闲的连接数:<%= DBPool.bds.getNumIdle()%><br>
        
        --------------------调用释放连接方法之后---------------------- <br>
        <%
        DBPool.freeConnection(con);
        %>
        当前活动的连接数:<%= DBPool.bds.getNumActive()%><br>
        当前空闲的连接数:<%= DBPool.bds.getNumIdle()%><br>
    body>
html>

TOMCAT 连接池

数据库连接池是当今Java程序控制开发中常用的技术,其主要用于解决高负载数据库访问造成的性能问题,提高数据库的使用效率。本实例将介绍如何通过Tomcat连接池访问数据库。

连接池技术原理如图2所示。连接的建立、断开都由连接池自身来管理,当程序需要建立数据库连接时,只需从内存中取一个来用而不用新建。同样,使用完毕后,将其放回内存即可。另外,连接池还可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。
数据源是在JDBC 2.0中引入的一个概念。在JDBC 2.0扩展包中定义了javax.sql.DataSource接口来描述数据源。如果希望通过Tomcat连接池建立一个数据库连接,通过查询在JNDI服务(Java名称和目录接口服务)中的数据源,可以从数据源中获取相应的数据库连接。这样就只能提供一个逻辑名称,而不是数据库登录的具体细节。

(1)把数据库驱动包(mssqlserver.jar、msutil.jar、msbase.jar)复制到%Tomcat_HOME%\ common\lib文件夹下。
(2)配置%Tomcat_HOME %\conf\server.xml文件。笔者使用的是Tomcat 5.5服务器,打开Tomcat 5.5\conf\server.xml文件,在该文件中的之间加入如下代码:

<Context path="/ connectionPool"  docBase=" connectionPool" debug="5" reloadable="true" corssContext="true">
<Resource name="jdbc/ConnectionPool"
auth="Container"
type="javax.sql.DataSource"
maxActive="20"
maxIdle="30"
maxWait="10000"
username="sa"
password=""
driverClassName="com.microsoft.jdbc.sqlserver.SQLServerDriver"
url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=db_database05"/>
Context>

参数说明:

l path:指定访问Web应用程序的URL入口。

l docBase:指定Web应用程序的文件路径,可以是绝对路径,也可以是相对于Host的appBase属性的相对路径。

l maxActive:连接池处于活动状态的数据库连接的最大数目,取0表示不受限制。

l maxIdle:连接池处于空闲状态的数据库连接的最大数目,取0表示不受限制。

l maxWait:连接池中数据库连接处于空闲状态的最长时间(以毫秒为单位),取0表示无限期等待时间。

l username:数据库登录名。

l password:数据库登录密码。

l driverClassName:指定数据库的JDBC驱动程序。

l url:指定连接数据库URL,db_database05是数据库名称。

(3)创建index.jsp页面文件,显示数据库是否已经连接,关键代码如下:

<%@ page import="java.sql.*"%>
<%@ page import="javax.sql.*"%>
<%@ page import="javax.naming.*"%>
<div align='center'>
<%
DataSource ds = null;
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
try{
InitialContext ctx=new InitialContext();
ds=(DataSource)ctx.lookup("java:comp/env/jdbc/ConnectionPool");
conn = ds.getConnection();
}
catch(Exception e){
e.printStackTrace();
}
%>
<%if(conn!=null){
try{
stmt=conn.createStatement();
rs=stmt.executeQuery("select * from tb_userOperation");
%>
取得数据库连接成功!!!span>
<table width="220" border="1">
  <tr align="center">
    <td>姓名td>
    <td>年龄td>
    <td>职业td>
  tr>
  <%while(rs.next()){
%>
  <tr align="center">
    <td><%=rs.getString("name")%>td>
    <td><%=rs.getString("sex")%>td>
    <td><%=rs.getString("profession")%>td>
  tr>
  <%}%>
table>
<%
}catch(Exception e){
out.print("32131");
}%>
<%}%>
(4)在web.xml文件引用连接池,关键代码如下:
<resource-ref>
    <description>SQL server text appdescription>
    <res-ref-name>jdbc/ConnectionPoolres-ref-name>
    <res-type>javax.sql.DataSourceres-type>
     <res-auth>Containerres-auth>
resource-ref>

(4)在web.xml文件引用连接池,关键代码如下:

<resource-ref>
    <description>SQL server text appdescription>
    <res-ref-name>jdbc/ConnectionPoolres-ref-name>
    <res-type>javax.sql.DataSourceres-type>
     <res-auth>Containerres-auth>
resource-ref>

(5)程序完整代码如下:

<%@ page contentType="text/html; charset=gb2312" language="java"  errorPage="" %>
<%@ page import="java.sql.*"%>
<%@ page import="javax.sql.*"%>
<%@ page import="javax.naming.*"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>通过Tomcat连接池连接SQL Server数据库title>
<style type="text/css">
--
.style1 {color: #0000FF}
-->
style>
head>

<body>
<div align='center'>
<span class="style1">
<%
DataSource ds = null;
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;

try{
InitialContext ctx=new InitialContext();
ds=(DataSource)ctx.lookup("java:comp/env/jdbc/ConnectionPool");
conn = ds.getConnection();
}
catch(Exception e){
e.printStackTrace();
}
%>
<%if(conn!=null){
try{
stmt=conn.createStatement();
rs=stmt.executeQuery("select * from tb_userOperation");
%>
取得数据库连接成功!!!span>
<table width="220" border="1">
  <tr align="center">
    <td><span class="style1">姓名span>td>
    <td><span class="style1">年龄span>td>
    <td><span class="style1">职业span>td>
  tr>
  <%while(rs.next()){
%>
  <tr align="center">
    <td><%=rs.getString("name")%>td>
    <td><%=rs.getString("sex")%>td>
    <td><%=rs.getString("profession")%>td>
  tr>
  <%}%>
table>
<%
}catch(Exception e){

}%>
<%}%>
body>
html>

★★★★★WEB-INF\web.xml★★★★★


<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
  <display-name>webdisplay-name>
  <resource-ref>
  <description>SQL server text appdescription>
  <res-ref-name>jdbc/ConnectionPoolres-ref-name>
    <res-type>javax.sql.DataSourceres-type>
       <res-auth>Containerres-auth>
resource-ref>
web-app>

利用WebLogic连接池访问数据库不但可以提高网站的访问速度,而且可以保证数据库的安全。下面将介绍如何通过WebLogic连接池连接SQL Server 2000数据库。

通过WebLogic连接池连接数据库时,首先需要获得一个引用本地服务器上JNDI服务的Context对象,然后再通过Context对象的lookup()方法,得到JNDI名字服务中的DataSource对象的引用,最后通过DataSource对象的getConnection()方法获得一个Connection对象的实例。关键代码如下:

Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("database05JNDI");
conn = ds.getConnection();
其中,DataSource对象代表了数据源,一般由数据库驱动程序厂商实现,其主要方法如下。
l     getConnection():获取一个Connection对象。
l     getConnection(String username,String password):获取一个Connection对象。
l     getLogWriter():从DataSource获得LogWriter对象,该对象是PrinterWriter对象的实例。
l     setLogWriter(PrintWriter out):设置DataSource的LogWriter对象。
l     getLoginTimeout():获得DataSource尝试连接数据库的最大时间。
l    setLoginTimeout():设置DataSource尝试连接数据库的最大时间。

(1)在SQL Server企业管理器中,创建一个名称为mr的登录用户,该用户的登录密码为mrsoft,并指定该用户可以访问本实例所用的数据库db_database05。
(2)首先在WebLogic服务控制台中配置名称为database05Pool的数据库连接池,然后配置名称为database05DS的Data Sources数据源,其JNDI名字为database05JNDI。具体方法可参见实例014。
(3)编写连接SQL Server数据库的JavaBean“ConnDB”,将其保存到com.core包中,并定义相应的全局变量,关键代码如下:

package com.core;
import java.sql.*;
import javax.sql.*;
import javax.naming.Context;
public class ConnDB{
    public Connection conn = null;
    public Statement stmt = null;
    public ResultSet rs = null;
    public Context context = null;
}

(4)编写执行查询操作的方法executeQuery(),在该方法中将通过WebLogic服务的JNDI名字访问指定数据源,获取数据库配置信息,并连接数据库。具体代码如下:

public ResultSet executeQuery(String sql) {
    try {
       Context ctx = new InitialContext();
       DataSource ds = (DataSource) ctx.lookup("database05JNDI");
       conn = ds.getConnection();
       stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
                          ResultSet.CONCUR_READ_ONLY);
       rs = stmt.executeQuery(sql);
    } catch (Exception ex) {
       System.err.println(ex.getMessage());
    } finally {}
    return rs;
}

(5)在JSP页面中调用executeQuery()方法查询公告信息,关键代码如下:

<jsp:useBean id="conn" scope="page" class="com.core.ConnDB"/>
<%ResultSet rs= conn.executeQuery("select * from tb_BBS");%>

(6)程序完整代码如下:

package com.core;

import java.sql.*;
import javax.sql.*;
import javax.naming.Context;

import javax.naming.*;

public class ConnDB {
    public Connection conn = null;
    public Statement stmt = null;
    public ResultSet rs = null;
    public Context context = null;

    public ConnDB() {}

    /***************************************************
     *method name:      executeQuery()
     *功能:执行查询操作
     *return value: ResultSet
     ****************************************************/
    public ResultSet executeQuery(String sql) {
        try {
            Context ctx = new InitialContext();
            DataSource ds = (DataSource) ctx.lookup("database05JNDI");
            conn = ds.getConnection();
            stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
                                        ResultSet.CONCUR_READ_ONLY);
            rs = stmt.executeQuery(sql);
        } catch (Exception ex) {
            System.err.println(ex.getMessage());
        } finally {}
        return rs;
    }

    /***************************************************
     *method name:      close()
     *功能:关闭数据库链接
     *return value:       void
     ****************************************************/
    public void close() {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (Exception e) {
            e.printStackTrace(System.err);
        } finally {}
        try {
            if (stmt != null) {
                stmt.close();
            }
        } catch (Exception e) {
            e.printStackTrace(System.err);
        } finally {}
        try {
            if (conn != null) {
                conn.close();
            }
        } catch (Exception e) {
            e.printStackTrace(System.err);
        } finally {}
    }
}

index.jsp

<%@ page contentType="text/html; charset=GBK" import="java.sql.*"%>
<jsp:useBean id="conn" scope="page" class="com.core.ConnDB"/>
<html>
<head>
<title>
通过WebLogic连接池连接SQL Server数据库
title>
head>
<body bgcolor="#ffffff">
<link href="CSS/style.css" rel="stylesheet">
<%ResultSet rs= conn.executeQuery("select * from tb_BBS");%>
  <table width="182" height="155"  border="0" align="center" cellpadding="0" cellspacing="0">
      <tr>
        <td><img src="images/shop_22.gif" width="182" height="58">td>
      tr>
      <tr>
        <td height="97" align="center" valign="top" class="tableBorder_l"><table width="88%"  border="0" cellspacing="0" cellpadding="0">
            <%
            int ID_bbs=0;
            String title="";
                try{
            while(rs.next()){
              ID_bbs=rs.getInt(1);
              title=rs.getString(2);
%>
            <tr>
              <td height="24" class="tableBorder_T_dashed"><a href="#"><%=title%>a>td>
            tr>
<%             }
                }catch(Exception e){
                System.out.println(e.getMessage());
                }%>
        table>td>
      tr>
table>
body>
html>

CSS\style.css

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
  
  < bean id = "dataSource" class = "com.alibaba.druid.pool.DruidDataSource"destroy-method = "close" >    
         
       < property name = "url" value = "${url}" />    
       < property name = "username" value = "${username}" />    
       < property name = "password" value = "${password}" />    
       < property name = "driverClassName" value = "${driverClassName}" />    
       < property name = "filters" value = "${filters}" />    
          
       < property name = "maxActive" value = "${maxActive}" />  
         
       < property name = "initialSize" value = "${initialSize}" />  
         
       < property name = "maxWait" value = "${maxWait}" />  
         
       < property name = "minIdle" value = "${minIdle}" />    
         
       < property name = "timeBetweenEvictionRunsMillis" value ="${timeBetweenEvictionRunsMillis}" />  
         
       < property name = "minEvictableIdleTimeMillis" value ="${minEvictableIdleTimeMillis}" />    
       < property name = "validationQuery" value = "${validationQuery}" />    
       < property name = "testWhileIdle" value = "${testWhileIdle}" />    
       < property name = "testOnBorrow" value = "${testOnBorrow}" />    
       < property name = "testOnReturn" value = "${testOnReturn}" />    
       < property name = "maxOpenPreparedStatements" value ="${maxOpenPreparedStatements}" />  
         
       < property name = "removeAbandoned" value = "${removeAbandoned}" />  
         
       < property name = "removeAbandonedTimeout" value ="${removeAbandonedTimeout}" />  
            
       < property name = "logAbandoned" value = "${logAbandoned}" />  
  bean >  

dbconfig.properties

[html] view plain copy 在CODE上查看代码片派生到我的代码片
url: jdbc:mysql:// localhost :3306/ newm  
driverClassName: com.mysql.jdbc.Driver  
username: root  
password: root  
filters: stat  
maxActive: 20  
initialSize: 1  
maxWait: 60000  
minIdle: 10  
maxIdle: 15  
timeBetweenEvictionRunsMillis: 60000  
minEvictableIdleTimeMillis: 300000  
validationQuery: SELECT 'x'  
testWhileIdle: true  
testOnBorrow: false  
testOnReturn: false  
maxOpenPreparedStatements: 20  
removeAbandoned: true  
removeAbandonedTimeout: 1800  
logAbandoned: true  

web.xml

[html] view plain copy 在CODE上查看代码片派生到我的代码片
  
  < filter >  
     < filter-name > DruidWebStatFilter filter-name >  
     < filter-class > com.alibaba.druid.support.http.WebStatFilter filter-class >  
     < init-param >  
         < param-name > exclusions param-name >  
         < param-value > *. js ,*. gif ,*. jpg ,*. png ,*. css ,*. ico ,/ druid /* param-value >  
     init-param >  
  filter >  
  < filter-mapping >  
     < filter-name > DruidWebStatFilter filter-name >  
     < url-pattern > /* url-pattern >  
  filter-mapping >  
  < servlet >  
     < servlet-name > DruidStatView servlet-name >  
     < servlet-class > com.alibaba.druid.support.http.StatViewServlet servlet-class >  
  servlet >  
  < servlet-mapping >  
     < servlet-name > DruidStatView servlet-name >  
     < url-pattern > / druid /* url-pattern >  
  servlet-mapping >  
    

访问监控页面: http://ip:port/projectName/druid/index.html

你可能感兴趣的:(hibernate,学习笔记)