为Tomcat数据连接池配置JNDI数据源

这篇文章将向你展示

如何创建JNDI资源,它代表着在Tomcat中的JDBC数据源。
以及如何配置一个java web app 来使其能够访问JNDI数据源。

使用JNDI数据源的好处有:

1-使用由container提供的数据库连接池,(tomcat能使用Commons DBCP和 Commons Pool作为实现-tomcat-dbcp.jar);
2-将数据库连接分工作从web应用程序中分离出来;
3-使得在container中部署的应用之间能够分享数据库连接;

下面的实例在Tomcat7,Mysql5.5中进行测试。

1 - 首先创建一个数据库和表

create database usersdb;

use usersdb;

CREATE TABLE `users` ( `user_id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(45) NOT NULL, `password` varchar(45) NOT NULL, `email` varchar(45) NOT NULL, PRIMARY KEY (`user_id`) );

这个表创建了一个usersdb 和一个表 users.
切记插入一些数据到这个表中。

use usersdb;
INSERT INTO users (username, password, email) VALUES ('Wilson', 'docd', '[email protected]');
INSERT INTO users (username, password, email) VALUES ('Willims', 'docd', '[email protected]');
INSERT INTO users (username, password, email) VALUES ('jordan', 'docd', '[email protected]');
INSERT INTO users (username, password, email) VALUES ('kobe', 'docd', '[email protected]');
INSERT INTO users (username, password, email) VALUES ('tlyson', 'docd', '[email protected]');
INSERT INTO users (username, password, email) VALUES ('kimi', 'docd', '[email protected]');

为了使mysql数据库和java应用程序之间能够交互,一定要确保MySQL Connector/J 的library包加入到
calsspath中。这里我们需要将mysql-connector-java-VERSION-bin.jar文件复制到 $CATALINA_BASE/lib
目录下。如果你只在你的电脑上安装了一个Tomcat,那么$CATALINA_BASE就是tomcat的安装目录。
例如在我的windows中,是D:\apache-tomcat-7.0.61。

这么做能够帮助Tomcat加载MySQL JDBC driver,当它发现有JNDI数据源配置时。

2 配置context

为了声明刚才创建的数据库的JNDI数据源,需要创建一个带有如下内容的 Resource XML元素

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

将这个元素加入到一个context.xml文件的根元素之中,有两个地方可以放置context.xml文件。

1 在web应用程序的 /META-INF目录中: JNDI数据源只有应用程序本身能够使用,不能在应用程序之间共享。
这个配置将是依着这个程序来设定的。
2 在 $CATALINA_BASE/conf 目录中:这是首选的地方,因为这样JNDI数据源将能够在程序间共享,同时也是独立于应用程序而设置的。

这里,我们将采用第二种做法。
参数说明:
为Tomcat数据连接池配置JNDI数据源_第1张图片
注意:
1-如果你使用的Tomcat在Eclipse IDE中,你需要修改的是 Servers project 下的 context.xml 文件,
因为Eclipse使用的是复制来的Tomcat配置。
2-如果两个同名资源都定义在context.xml文件中,并分别放置在META-INF目录和$CATALINA_BASE/conf目录中,
那么内部版本优先。

3 配置web.xml文件

在web.xml文件中加入以下声明:

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

这一声明是为了使得JNDI数据源在特定的命名空间jdbc/UsersDB下在应用程序中可用。

4 编写测试JSP页面 UsersList.jsp

内容如下:

<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<sql:query var="listUsers" dataSource="jdbc/UsersDB">
    select username, email from users;
</sql:query>

<!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>Users List</title>
</head>
<body>
    <div align="center">
        <table border="1" cellpadding="5">
            <caption><h2>List of users</h2></caption>
            <tr>
                <th>Name</th>
                <th>Email</th>
            </tr>
            <c:forEach var="user" items="${listUsers.rows}">
                <tr>
                    <td><c:out value="${user.username}" /></td>
                    <td><c:out value="${user.email}" /></td>
                </tr>
            </c:forEach>
        </table>
    </div>
</body>
</html>

5 在Java Servlet中获取和使用数据源

查找配置好的数据源的java代码如下:

Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup("java:comp/env");
DataSource ds = (DataSource) envContext.lookup("jdbc/UsersDB");
Connection conn = ds.getConnection();

得到连接(connection)后我们可以像在JDBC中一样检索。

Statement statement = conn.createStatement();
String sql = "select username, email from users";
ResultSet rs = statement.executeQuery(sql);
// iterates over the result set...

一下是完整的代码:

package net.codejava.jdbc;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

/** * This servlet class demonstrates how to access a JNDI DataSource that * represents a JDBC connection. * @author www.codejava.net */
@WebServlet("/listUsers")
public class UsersListServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        PrintWriter writer = response.getWriter();
        try {
            Context initContext = new InitialContext();
            Context envContext = (Context) initContext.lookup("java:comp/env");
            DataSource ds = (DataSource) envContext.lookup("jdbc/UsersDB");
            Connection conn = ds.getConnection();

            Statement statement = conn.createStatement();
            String sql = "select username, email from users";
            ResultSet rs = statement.executeQuery(sql);

            int count = 1;
            while (rs.next()) {
                writer.println(String.format("User #%d: %-15s %s", count++, 
                        rs.getString("username"), rs.getString("email")));

            }
        } catch (NamingException ex) {
            System.err.println(ex);
        } catch (SQLException ex) {
            System.err.println(ex);
        }
    }

}

为Tomcat数据连接池配置JNDI数据源_第2张图片

可选的,我们还可以使用@Resource注解,(javax.annotation.Resource)来替代上面的查找代码。
例如,可以像下面一样声明一个dataSource:

@Resource(name = "jdbc/UserDb")
private DataSource dataSource;

当Tomcat发现这个注解符号,Tomcat将查找对应的资源并注入程序中。
完整的测试代码如下:

@WebServlet("/listUsers")
public class UsersListServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Resource(name = "jdbc/UsersDB")
    private DataSource dataSource;

    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        PrintWriter writer = response.getWriter();
        try {
            Connection conn = dataSource.getConnection();

            Statement statement = conn.createStatement();
            String sql = "select username, email from users";
            ResultSet rs = statement.executeQuery(sql);

            int count = 1;

            while (rs.next()) {
                writer.println(String.format("User #%d: %-15s %s", count++,
                        rs.getString("username"), rs.getString("email")));

            }
        } catch (SQLException ex) {
            System.err.println(ex);
        }
    }

}

翻自http://www.codejava.net

你可能感兴趣的:(jndi数据源配置)