JNDI学习总结(三)——Tomcat下使用Druid配置JNDI数据源

  com.alibaba.druid.pool.DruidDataSourceFactory实现了javax.naming.spi.ObjectFactory,可以作为JNDI数据源来配置。

一、下载Druid的jar包

  下载地址:http://mvnrepository.com/artifact/com.alibaba/druid/1.0.9,如下图所示:

  

  druid.jar依赖log4j的jar包,所以还需要下载log4j的jar包。

  log4j的下载地址如下:http://mvnrepository.com/artifact/log4j/log4j/1.2.17,如下图所示:

  

二、使用Druid配置JNDI数据源

2.1、前期准备工作

  创建一个Web测试项目Druid_JNDI_Config,将下载下来druid-1.0.9.jar和log4j-1.2.17.jar添加到项目中,在项目的META-INF目录下创建一个context.xml文件

  目录结构如下图所示:

  

  在tomcat服务器的lib目录下添加Oracle、MySQL、SQLServer三种数据库的驱动jar包,如下图所示:

  

2.2、在context.xml文件中加入JNDI的配置信息

  在context.xml文件中加入如下配置信息

 1 <Context>

 2     <!-- 使用阿里巴巴的DruidDataSource配置针对Oracle数据库的JNDI数据源 -->

 3     <Resource 

 4         name="jdbc/OracleDataSource"

 5         factory="com.alibaba.druid.pool.DruidDataSourceFactory"

 6         auth="Container"

 7         type="javax.sql.DataSource"

 8         driverClassName="oracle.jdbc.OracleDriver"

 9         url="jdbc:oracle:thin:@192.168.1.229:1521:lead"

10         username="lead_oams"

11         password="p"

12         maxActive="50"

13         maxWait="10000"

14         removeabandoned="true"

15         removeabandonedtimeout="60"

16         logabandoned="false"

17         filters="stat"/>

18         

19     <!-- 使用阿里巴巴的DruidDataSource配置针对MySQL数据库的JNDI数据源 -->

20      <Resource 

21         name="jdbc/MysqlDataSource"

22         factory="com.alibaba.druid.pool.DruidDataSourceFactory"

23         auth="Container"

24         type="javax.sql.DataSource"

25         driverClassName="com.mysql.jdbc.Driver"

26         url="jdbc:mysql://192.168.1.233:3306/lead_oams?useUnicode=true&amp;characterEncoding=utf-8"

27         username="lead_system"

28         password="password"

29         maxActive="50"

30         maxWait="10000"

31         removeabandoned="true"

32         removeabandonedtimeout="60"

33         logabandoned="false"

34         filters="stat"/>

35         

36     <!--使用阿里巴巴的DruidDataSource配置针对SQLServer数据库的JNDI数据源-->

37     <Resource 

38         name="jdbc/SqlServerDataSource"

39         auth="Container"

40         factory="com.alibaba.druid.pool.DruidDataSourceFactory" 

41         type="javax.sql.DataSource"

42         driverClass="com.microsoft.sqlserver.jdbc.SQLServerDriver"

43         url="jdbc:sqlserver://192.168.1.61:1433;DatabaseName=gaclTest"

44         username="sa" 

45         password="p@ssw0rd"

46         maxActive="50"

47         maxWait="10000"

48         removeabandoned="true"

49         removeabandonedtimeout="60"

50         logabandoned="false"

51         filters="stat"/>

52 </Context>

   配置项中指定了各个参数后,在连接池内部是这么使用这些参数的。数据库连接池在初始化的时候会创建initialSize个连接,当有数据库操作时,会从池中取出一个连接。如果当前池中正在使用的连接数等于maxActive,则会等待一段时间,等待其他操作释放掉某一个连接,如果这个等待时间超过了maxWait,则会报错;如果当前正在使用的连接数没有达到maxActive,则判断当前是否空闲连接,如果有则直接使用空闲连接,如果没有则新建立一个连接。在连接使用完毕后,不是将其物理连接关闭,而是将其放入池中等待其他操作复用。同时连接池内部有机制判断,如果当前的总的连接数少于miniIdle,则会建立新的空闲连接,以保证连接数得到miniIdle。如果当前连接池中某个连接在空闲了timeBetweenEvictionRunsMillis时间后任然没有使用,则被物理性的关闭掉。有些数据库连接的时候有超时限制(mysql连接在8小时后断开),或者由于网络中断等原因,连接池的连接会出现失效的情况,这时候设置一个testWhileIdle参数为true,可以保证连接池内部定时检测连接的可用性,不可用的连接会被抛弃或者重建,最大情况的保证从连接池中得到的Connection对象是可用的。当然,为了保证绝对的可用性,你也可以使用testOnBorrow为true(即在获取Connection对象时检测其可用性),
不过这样会影响性能。

2.3、在web.xml引用JDNI数据源

  在web.xml文件中加入如下的配置引用JNDI数据源

 1 <?xml version="1.0" encoding="UTF-8"?>

 2 <web-app version="2.5" 

 3     xmlns="http://java.sun.com/xml/ns/javaee" 

 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

 5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 

 6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

 7   <welcome-file-list>

 8     <welcome-file>index.jsp</welcome-file>

 9   </welcome-file-list>

10   

11   <!-- 

12       JNDI配置的资源引用:

13   • res-ref-name:表示引用资源的名称

14   • res-type:此资源对应的类型为javax.sql.DataSource

15   • res-auth:容器授权管理

16    -->

17    <!--Oracle数据库JNDI数据源引用 -->

18   <resource-ref>

19       <description>Oracle DB Connection</description>

20       <res-ref-name>jdbc/OracleDataSource</res-ref-name>

21       <res-type>javax.sql.DataSource</res-type>

22       <res-auth>Container</res-auth>

23  </resource-ref>

24   

25   <!--MySQL数据库JNDI数据 -->

26   <resource-ref>

27       <description>MySQL DB Connection</description>

28       <res-ref-name>jdbc/MysqlDataSource</res-ref-name>

29       <res-type>javax.sql.DataSource</res-type>

30       <res-auth>Container</res-auth>

31   </resource-ref>

32   

33    <!--SQLServer数据库JNDI数据源引用 -->

34   <resource-ref>

35       <description>SQLServer DB Connection</description>

36       <res-ref-name>jdbc/SqlServerDataSource</res-ref-name>

37       <res-type>javax.sql.DataSource</res-type>

38       <res-auth>Container</res-auth>

39   </resource-ref>

40 </web-app>

2.4、测试JNDI数据源

  部署Druid_JNDI_Config Web应用到Tomcat服务器测试JNDI数据源,如下图所示:

  

  部署到tomcat服务器的webapps目录之后,tomcat服务器就会自动在\conf\Catalina\localhost目录下生成一个Druid_JNDI_Config.xml文件,如下图所示:

  

  Druid_JNDI_Config.xml文件中的内容就是我们在META-INF目录的context.xml文件中配置的那些内容。

  jsp测试页面如下:

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

 2 <%--引入JSTL标签库 --%>

 3 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

 4 <%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>

 5 <!DOCTYPE HTML>

 6 <html>

 7   <head>

 8     <title>DRUID配置JNDI数据源连接测试</title>

 9   </head>

10   

11   <body>

12     <h3>针对MySQL数据库JNDI数据源测试</h3>

13         <%--使用sql:query标签发送SQL语句去数据库查询数据,查询的结果集保存到rs变量当中,dataSource属性指明使用的数据源--%>

14         <sql:query var="rs" dataSource="jdbc/MysqlDataSource">

15             <%--MySQL JNDI数据源测试 SQL--%>

16              select * from lead_oams_applications

17         </sql:query>

18         <%--使用c:forEach标签遍历查询结果集rs中的每一行--%>

19         <c:forEach var="row" items="${rs.rows}">

20             <%--${row.字段名}获取字段的值--%>

21             ${row.resourceid}---${row.app_name}<br/>

22         </c:forEach>

23         <hr/>

24         <h3>针对Oracle数据库JNDI数据源测试</h3>

25           <%--使用sql:query标签发送SQL语句去数据库查询数据,查询的结果集保存到rs变量当中,dataSource属性指明使用的数据源--%>

26         <sql:query var="rs" dataSource="jdbc/OracleDataSource">

27             <%--Oracle JNDI数据源测试 SQL--%>

28             SELECT * FROM LEAD_OAMS_DBSOURCES

29         </sql:query>

30         <%--使用c:forEach标签遍历查询结果集rs中的每一行--%>

31         <c:forEach var="row" items="${rs.rows}">

32             <%--${row.字段名}获取字段的值--%>

33             ${row.RESOURCEID}---${row.DBSOURCE_NAME}---${row.DBSOURCE_TYPE}<br/>

34         </c:forEach>

35         <hr/>

36         <h3>SQLServer JNDI数据源测试</h3>

37         <%--使用sql:query标签发送SQL语句去数据库查询数据,查询的结果集保存到rs变量当中,dataSource属性指明使用的数据源--%>

38         <sql:query var="rs" dataSource="jdbc/SqlServerDataSource">

39             <%--SQLServer JNDI数据源测试 SQL--%>

40             select * from t_demo

41         </sql:query>

42         <%--使用c:forEach标签遍历查询结果集rs中的每一行--%>

43         <c:forEach var="row" items="${rs.rows}">

44             <%--${row.字段名}获取字段的值--%>

45             ${row.id}---${row.name}<br/>

46         </c:forEach>

47   </body>

48 </html>

  运行结果如下:

  

三、在Java代码中获取JNDI中的数据源

3.1、获取JNDI中的数据源

  编写一个JdbcUtil工具类,JdbcUtil工具类负责从JNDI容器中获取DataSource,再通过DataSource获取数据库连接。

代码如下:

  1 package me.gacl.util;

  2 

  3 /**

  4  * <p>ClassName: JdbcUtil<p>

  5  * <p>Description: 从JNDI容器中获取DataSource,再通过DataSource获取数据库连接<p>

  6  */

  7 import java.sql.Connection;

  8 import java.sql.ResultSet;

  9 import java.sql.SQLException;

 10 import java.sql.Statement;

 11 import javax.naming.Context;

 12 import javax.naming.InitialContext;

 13 import javax.naming.NamingException;

 14 import com.alibaba.druid.pool.DruidDataSource;

 15 

 16 public class JdbcUtil {

 17     

 18 /*

 19  web.xml文件中的JNDI数据源引用配置

 20  

 21   <!--Oracle数据库JNDI数据源引用 -->

 22   <resource-ref>

 23       <description>Oracle DB Connection</description>

 24       <res-ref-name>jdbc/OracleDataSource</res-ref-name>

 25       <res-type>javax.sql.DataSource</res-type>

 26       <res-auth>Container</res-auth>

 27  </resource-ref>

 28   

 29   <!--MySQL数据库JNDI数据 -->

 30   <resource-ref>

 31       <description>MySQL DB Connection</description>

 32       <res-ref-name>jdbc/MysqlDataSource</res-ref-name>

 33       <res-type>javax.sql.DataSource</res-type>

 34       <res-auth>Container</res-auth>

 35   </resource-ref>

 36   

 37    <!--SQLServer数据库JNDI数据源引用 -->

 38   <resource-ref>

 39       <description>SQLServer DB Connection</description>

 40       <res-ref-name>jdbc/SqlServerDataSource</res-ref-name>

 41       <res-type>javax.sql.DataSource</res-type>

 42       <res-auth>Container</res-auth>

 43   </resource-ref>

 44 */

 45     

 46     //Oracle数据库配置的JNDI数据源连接名,后面跟的是DataSource名,DataSource名在web.xml文件中的<res-ref-name></res-ref-name>进行了配置

 47     private static final String ORACLE_DB_JNDINAME = "java:comp/env/jdbc/OracleDataSource";

 48     //MySQL数据库配置的JNDI数据源连接名,java:comp/env是必须加的,后面跟的是DataSource名

 49     private static final String MYSQL_DB_JNDINAME = "java:comp/env/jdbc/MysqlDataSource";

 50     //SQLServer数据库配置的JNDI数据源连接名,java:comp/env是必须加的,后面跟的是DataSource名

 51     private static final String SQLSERVER_DB_JNDINAME = "java:comp/env/jdbc/SqlServerDataSource";

 52     

 53     private static DruidDataSource dsOracle = null;

 54     private static DruidDataSource dsMySql = null;

 55     private static DruidDataSource dsSqlServer = null;

 56     

 57     static{

 58         try {

 59             //1、初始化名称查找上下文

 60             Context ctx = new InitialContext();

 61             //2、通过JNDI名称找到DataSource

 62             dsOracle = (DruidDataSource) ctx.lookup(ORACLE_DB_JNDINAME);

 63             dsMySql = (DruidDataSource) ctx.lookup(MYSQL_DB_JNDINAME);

 64             dsSqlServer = (DruidDataSource) ctx.lookup(SQLSERVER_DB_JNDINAME);

 65         } catch (NamingException e) {

 66             e.printStackTrace();

 67         }

 68     }

 69 

 70     /**

 71      * MethodName: getOracleConnection

 72      * Description: 获取Oracle数据库连接

 73      * @author xudp        

 74      * @return

 75      * @throws SQLException

 76      */

 77     public static Connection getOracleConnection() throws SQLException {

 78         return dsOracle.getConnection();

 79     }

 80     

 81     /**

 82      * MethodName: getMySqlConnection

 83      * Description: 获取MySQL数据库连接

 84      * @author xudp        

 85      * @return

 86      * @throws SQLException

 87      */

 88     public static Connection getMySqlConnection() throws SQLException {

 89         return dsMySql.getConnection();

 90     }

 91     

 92     /**

 93      * MethodName: getSqlServerConnection

 94      * Description: 获取SQLServer数据库连接

 95      * @author xudp        

 96      * @return

 97      * @throws SQLException

 98      */

 99     public static Connection getSqlServerConnection() throws SQLException {

100         return dsSqlServer.getConnection();

101     }

102 

103     /**

104     * @Method: release

105     * @Description: 释放资源,

106     *     要释放的资源包括Connection数据库连接对象,负责执行SQL命令的Statement对象,存储查询结果的ResultSet对象

107     * @Anthor:孤傲苍狼

108     *

109     * @param conn

110     * @param st

111     * @param rs

112     */ 

113     public static void release(Connection conn,Statement st,ResultSet rs){

114         if(rs!=null){

115             try{

116                 //关闭存储查询结果的ResultSet对象

117                 rs.close();

118             }catch (Exception e) {

119                 e.printStackTrace();

120             }

121             rs = null;

122         }

123         if(st!=null){

124             try{

125                 //关闭负责执行SQL命令的Statement对象

126                 st.close();

127             }catch (Exception e) {

128                 e.printStackTrace();

129             }

130         }

131         

132         if(conn!=null){

133             try{

134                 //关闭Connection数据库连接对象

135                 conn.close();

136             }catch (Exception e) {

137                 e.printStackTrace();

138             }

139         }

140     }

141 }

3.2、测试JNDI数据源

  编写一个测试的Servlet,测试代码如下:

  1 package me.gacl.test;

  2 

  3 import java.io.IOException;

  4 import java.sql.Connection;

  5 import java.sql.PreparedStatement;

  6 import java.sql.ResultSet;

  7 import java.sql.SQLException;

  8 import java.util.ArrayList;

  9 import java.util.LinkedHashMap;

 10 import java.util.List;

 11 import java.util.Map;

 12 import javax.servlet.ServletException;

 13 import javax.servlet.http.HttpServlet;

 14 import javax.servlet.http.HttpServletRequest;

 15 import javax.servlet.http.HttpServletResponse;

 16 import me.gacl.util.JdbcUtil;

 17 

 18 /**

 19  * <p>ClassName: JNDITestServlet<p>

 20  * <p>Description: <p>

 21  * <p>Company:广州利迪网络科技有限公司 <p>    

 22  * @author xudp

 23  * @version 1.0 V

 24  * @createTime 2014-10-23 上午09:32:52

 25  */

 26 public class JNDITestServlet extends HttpServlet {

 27 

 28     public void doGet(HttpServletRequest request, HttpServletResponse response)

 29             throws ServletException, IOException {

 30         

 31         //Oracle数据库连接

 32         Connection oracleConnection = null;

 33         //MySql数据库连接

 34         Connection mySqlConnection = null;

 35         //SQLServer数据库连接

 36         Connection sqlServerConnection = null;

 37         

 38         //负责执行SQL的PreparedStatement对象

 39         PreparedStatement pstmtOracle = null;

 40         PreparedStatement pstmtMySQL = null;

 41         PreparedStatement pstmtSqlServer = null;

 42         

 43         //查询出来的结果集

 44         ResultSet rsOracle = null;

 45         ResultSet rsMySQL = null;

 46         ResultSet rsSqlServer = null;

 47         

 48         //存储查询出来的数据,每一行数据映射成一个Map,字段名作为key,字段的值作为value

 49         List<Map<String, String>> oracleDataList = new ArrayList<Map<String, String>>();

 50         List<Map<String, String>> mySqlDataList = new ArrayList<Map<String, String>>();

 51         List<Map<String, String>> sqlServerDataList = new ArrayList<Map<String, String>>();

 52         

 53         try {

 54             

 55             //获取Oracle数据库连接

 56              oracleConnection = JdbcUtil.getOracleConnection();

 57             //获取MySql数据库连接

 58              mySqlConnection = JdbcUtil.getMySqlConnection();

 59             //获取SQLServer数据库连接

 60              sqlServerConnection =JdbcUtil.getSqlServerConnection();

 61             

 62              String oracleDb_Sql = "SELECT * FROM LEAD_OAMS_DBSOURCES";

 63              String mySqlDb_Sql = "SELECT * FROM LEAD_OAMS_APPLICATIONS";

 64              String sqlServerDb_Sql = "SELECT * FROM T_DEMO";

 65                 

 66              pstmtOracle = oracleConnection.prepareStatement(oracleDb_Sql);

 67              pstmtMySQL = mySqlConnection.prepareStatement(mySqlDb_Sql);

 68              pstmtSqlServer = sqlServerConnection.prepareStatement(sqlServerDb_Sql);

 69             

 70              //执行查询,查询结果存储到ResultSet结果集中

 71              rsOracle = pstmtOracle.executeQuery();

 72              rsMySQL = pstmtMySQL.executeQuery();

 73              rsSqlServer = pstmtSqlServer.executeQuery();

 74             

 75             //循环结果集中的数据 

 76             while(rsOracle.next()){

 77                 Map<String, String> oracleDataMap = new LinkedHashMap<String, String>();

 78                 //取出结果集中的数据,每一行数据映射成一个map集合

 79                 oracleDataMap.put("resourceid", rsOracle.getString("RESOURCEID"));

 80                 oracleDataMap.put("dbsource_name", rsOracle.getString("DBSOURCE_NAME"));

 81                 oracleDataMap.put("dbsource_type", rsOracle.getString("DBSOURCE_TYPE"));

 82                 //将代表每一行数据的Map集合添加到List集合中

 83                 oracleDataList.add(oracleDataMap);

 84             }

 85             

 86             while(rsMySQL.next()){

 87                 Map<String, String> mySqlDataMap = new LinkedHashMap<String, String>();

 88                 mySqlDataMap.put("resourceid", rsMySQL.getString("resourceid"));

 89                 mySqlDataMap.put("app_name", rsMySQL.getString("app_name"));

 90                 mySqlDataList.add(mySqlDataMap);

 91             }

 92             

 93             while(rsSqlServer.next()){

 94                 Map<String, String> sqlServerDataMap = new LinkedHashMap<String, String>();

 95                 sqlServerDataMap.put("id", rsSqlServer.getString("id"));

 96                 sqlServerDataMap.put("name", rsSqlServer.getString("name"));

 97                 sqlServerDataList.add(sqlServerDataMap);

 98             }

 99             

100             //将数据集合存储到request对象发送到页面进行显示

101             request.setAttribute("oracleDataList", oracleDataList);

102             request.setAttribute("mySqlDataList", mySqlDataList);

103             request.setAttribute("sqlServerDataList", sqlServerDataList);

104             //跳转到JNDITest.jsp页面显示数据

105             request.getRequestDispatcher("/JNDITest.jsp").forward(request, response);

106             

107         } catch (SQLException e) {

108             e.printStackTrace();

109         }finally{

110             //释放资源

111             JdbcUtil.release(oracleConnection, pstmtOracle, rsOracle);

112             JdbcUtil.release(mySqlConnection, pstmtMySQL, rsMySQL);

113             JdbcUtil.release(sqlServerConnection, pstmtSqlServer, rsSqlServer);

114         }

115     }

116     

117     public void doPost(HttpServletRequest request, HttpServletResponse response)

118             throws ServletException, IOException {

119         doGet(request,response);

120     }

121 }

  JNDITest.jsp页面代码如下:

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

 2 <%--引入JSTL标签库 --%>

 3 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

 4 <!DOCTYPE HTML>

 5 <html>

 6   <head>

 7     <title>JNDI测试</title>

 8   </head>

 9   

10   <body>

11         <h3>从Oracle数据库中取出来的数据</h3>

12         <%--使用c:forEach标签遍历List集合--%>

13         <c:forEach var="oracleDataMap" items="${oracleDataList}">

14             ${oracleDataMap.resourceid}---${oracleDataMap.dbsource_name}---${oracleDataMap.dbsource_type}<br/>

15         </c:forEach>

16         <hr/>

17         <h3>从mySql数据库中取出来的数据</h3>

18         <%--使用c:forEach标签遍历List集合--%>

19         <c:forEach var="mySqlDataMap" items="${mySqlDataList}">

20             ${mySqlDataMap.resourceid}---${mySqlDataMap.app_name}<br/>

21         </c:forEach>

22         <hr/>

23         <h3>从sqlServer数据库中取出来的数据</h3>

24         <%--使用c:forEach标签遍历List集合--%>

25         <c:forEach var="sqlServerDataMap" items="${sqlServerDataList}">

26             ${sqlServerDataMap.id}---${sqlServerDataMap.name}<br/>

27         </c:forEach>

28   </body>

29 </html>

  运行结果如下:

  

你可能感兴趣的:(tomcat)