Tomcat 6 JNDI數據源詳解

數據庫鏈接池這個概念應該都不陌生,在Java中鏈接池也就是數據庫的鏈接池,它是一種採用鏈接複用的思想避免屢次鏈接形成資源的浪費機制。html

最多見的鏈接池就是DBCP和C30P了,在tomcat中默認使用的DBCP的鏈接池,在Hibernate中則默認使用的是C3P0。他們的區別對於使用者來講最明顯的就是,默認狀況下DBCP不提供空閒鏈接的釋放,須要手動開啓。java

下面介紹下Tomcat中數據鏈接池的配置及使用。mysql

 

介紹

  本篇依賴一個概念——JNDI,能夠參考前面的博客:JNDI資源詳解web

  對於JNDI,能夠簡單理解成Tomcat中的資源池,經過一些特有的名字與特定的資源相對應,相似一個map,能夠簡單的經過名字獲取到該資源。sql

  那麼本篇中JNDI數據源就是經過配置一個數據源的資源,在應用中經過該名稱獲取到數據庫鏈接,進行操做。這樣就省去了每次鏈接數據庫的步驟。數據庫

鏈接池原理

  鏈接池的概念,應該都不陌生了。部份內容能夠參考:幾個主流的鏈接池apache

  這裏簡單說明下,若是單獨在應用使用鏈接池,可能只是在應用運行時建立鏈接池。而tomcat配置數據源能夠在tomcat容器啓動時就初始化鏈接池,中止tomcat時才釋放資源,其部署的應用能夠根據JNDI的聲明,在應用中共享使用該資源。tomcat

  所以一個是應用中的鏈接池(即一個應用中不一樣的業務使用該鏈接池,好比註冊新用戶與購買商品),一個能夠擴大到多應用的鏈接池,具體使用的還要看業務需求。oracle

 

  另外,tomcat中默認使用的DBCP鏈接池,其jar包位於CATALINA_HOME/lib下,tomcat-dbcp.jarpost

  須要注意的是,默認狀況下dbcp不會去釋放空閒的鏈接。好比,咱們在編碼時,拿到一個鏈接執行業務操做,可是沒有進行釋放。此時,DBCP鏈接池不會放回到空閒隊列中。若是再有新的鏈接,會分配其餘的鏈接。當鏈接數目過大時,就會形成鏈接的阻塞。

  能夠經過配置某些屬性來自動回收鏈接,首先設置removeAbandoned="true"開啓回收,而後設置removeAbandonedTimeout="300"設置鏈接的時間,超過該時間就會自動收回。

  具體內容能夠參考:DBCP文檔

Mysql案例

  按照下面幾個步驟:

  1 放置mysql驅動:能夠到這裏下載

  2 建立數據庫插入數據

  3 配置JNDI資源(context.xml以及web.xml)

  4 建立JSP驗證結果

  

  1 放置驅動

  在tomcat根目錄下的Lib中放置mysql驅動。

  2 建立數據庫表並添加數據

  能夠參考下面的SQL腳本:

/*
SQLyog v4.05
Host - 4.1.11-nt : Database - test
*********************************************************************
Server version : 4.1.11-nt
*/


create database if not exists `test`;

USE `test`;

/*Table structure for table `test`.`stu` */

drop table if exists `test`.`stu`;

CREATE TABLE `stu` (
  `id` int(11) NOT NULL default '0',
  `name` char(1) default NULL,
  `age` int(11) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

/*Data for the table `test`.`stu` */

insert into `test`.`stu` values (0,'x',26),(1,'z',27),(2,'w',25);

  3 配置JNDI資源

  首先在context.xml中添加<resource>

<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
               maxActive="100" maxIdle="30" maxWait="10000"
               username="root" password="123456" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost:3306/test"/>

  其中username爲你的用戶名,password是密碼。

  maxActive指定最大的鏈接數,maxIdle指定最大的空閒鏈接數(即沒有鏈接時,保存多少鏈接),maxWait指定最大的等待鏈接數。

  而後在web.xml中配置指定的資源名稱(不是必須的)

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

  4 建立JSP頁面,輸出信息

  按照下面的代碼建立,並釋放鏈接:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    import="javax.naming.*,java.sql.*,javax.sql.*"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h2>Results</h2>
    <%
    Context initContext = new InitialContext();
    Context envContext  = (Context)initContext.lookup("java:/comp/env");
    DataSource ds = (DataSource)envContext.lookup("jdbc/TestDB");
    Connection conn = ds.getConnection();
    String sql = "select * from stu";
    PreparedStatement st = conn.prepareStatement(sql);
    ResultSet rs = st.executeQuery();
    while(rs.next()){
        out.println("name:"+rs.getString(2)+" age:"+rs.getInt(3)+"<br>");
    }
    if(rs!=null){
        try{
            rs.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
        rs = null;
    }
    if(st!=null){
        try{
            st.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    if(conn!=null){
        try{
            conn.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
    %>
</body>
</html>

  最後的執行結果:

其餘的配置

  其餘的配置如Oracle和PostgreSQL僅僅是須要的數據庫驅動和建立的JNDI名稱不一樣:

  例如,在oracle中,context.xml中配置以下:

<Resource name="jdbc/myoracle" auth="Container"
              type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
              url="jdbc:oracle:thin:@127.0.0.1:1521:mysid"
              username="scott" password="tiger" maxActive="20" maxIdle="10"
              maxWait="-1"/> 

  在PostgreSQL中配置以下:

<Resource name="jdbc/postgres" auth="Container"
          type="javax.sql.DataSource" driverClassName="org.postgresql.Driver"
          url="jdbc:postgresql://127.0.0.1:5432/mydb"
          username="myuser" password="mypasswd" maxActive="20" maxIdle="10"
maxWait="-1"/>

  使用方式都是差很少的。

參考

【1】幾種主流的鏈接池:http://developer.51cto.com/art/201006/207768.htm

【2】DBCP官方文檔:http://commons.apache.org/proper/commons-dbcp/configuration.html

【3】Tomcat JNDI Database:http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html

相關文章
相關標籤/搜索