数据源与JNDI资源实现JSP数据库连接池实例

名词解释:JNDI的全称是java命名与目录接口(Java Naming and Directory Interface),是一个应用程序设计的API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口。我们可以把JNDI简单地理解为是一种将对象和名字绑定的技术,即指定一个资源名称,将该名称与某一资源或服务相关联,当需要访问其他组件和资源时,就需要使用JNDI服务进行定位,应用程序可以通过名字获取对应的对象或服务。

1.context.xml文件设置

  数据源:Tomcat根目录\conf\context.xml文件(没有直接创建也可以)或者在JSP项目WebRoot目录下的META-INF目录中创建一个context.xml文件,添加Context节点,如下:

1 <Context>
2     <Resource name="jdbc/test" auth="Application" type="javax.sql.DataSource"
3         maxActive="100" maxIdle="30" maxWait="10000" username="sa" password="1234"
4         driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver" url="jdbc:sqlserver://192.168.2.254:1433;DatabaseName=test" />
5 </Context>

name:指定Resource的JNDI名字。

auth:可以写成Container和Application。Container表示由容器创建Resource,Application表示由Web应用创建和管理Resource。

type:指定Resource所属的Java类名。

maxActive:指定数据库连接池中处于活动状态的数据库连接的最大数目。

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

maxWait:指定数据库连接池中数据库连接处于空闲状态的最长时间(以毫秒为单位),超出这时间将会抛出异常。

username:指定连接数据库的用户名。

password:指定连接数据库的口令。

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

url:指定连接数据库的URL。

2.web.xml文件的配置

  在Web应用程序的WEB-INF/web.xml文件中的<web-app>节点下添加<resource-ref>元素,内容如下:

1 <web-app>
2     ...
3     <resource-ref>
4         <description>news DataSource</description>
5         <res-ref-name>jdbc/test</res-ref-name>
6         <res-type>javax.sql.DataSource</res-type>
7         <res-auth>Container</res-auth>
8     </resource-ref>
9 </web-app>

description:对所引用资源的说明。

res-ref-name:指定所引用资源的JNDI名字,与<Resource>元素中的name属性对应。

res-type:指定所引用资源的类名字,与<Resource>元素中的type属性对应。

res-auth:指定管理所引用资源的Manager,与<Resource>元素中的auth属性对应。

3.在Web应用中添加数据库连接jar文件。

4.编写使用数据源和JNDI资源,创建采用数据库连接池Connection对象的SqlHelper.java文件(在helper包中创建的),代码如下:

  1 package helper;
  2 import java.lang.reflect.*;
  3 import java.sql.*;
  4 import java.util.*;
  5 
  6 import javax.naming.Context;
  7 import javax.naming.InitialContext;
  8 import javax.naming.NamingException;
  9 import javax.sql.DataSource;
 10 
 11 public class SqlHelper {
 12     
 13     private static Connection getConnection() throws ClassNotFoundException,
 14             SQLException {
 15         Connection conn = null;
 16         try {
 17             Context ctx = new InitialContext();
 18             // 获取与逻辑名相关联的数据源对象
 19             DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/test");
 20             conn = ds.getConnection();
 21         } catch (NamingException e) {
 22             // TODO Auto-generated catch block
 23             e.printStackTrace();
 24         } catch (SQLException e) {
 25             // TODO Auto-generated catch block
 26             e.printStackTrace();
 27         }
 28         return conn;
 29     }
 30 
 31     public static int executeNonQuery(String cmdText)
 32             throws ClassNotFoundException, SQLException {
 33         int result = -1;
 34         Connection con = null;
 35         PreparedStatement ps = null;
 36         try {
 37             con = getConnection();
 38             ps = con.prepareStatement(cmdText);
 39             result = ps.executeUpdate();
 40         }catch (Exception e) {
 41             System.out.println(e);
 42         } finally {
 43             close(con, ps, null);
 44         }
 45         return result;
 46     }
 47 
 48     public static int executeScalar(String cmdText) throws SQLException,
 49             ClassNotFoundException {
 50         int result = -1;
 51         Connection con = null;
 52         PreparedStatement ps = null;
 53         ResultSet rs = null;
 54         try {
 55             con = getConnection();
 56             ps = con.prepareStatement(cmdText);
 57             rs = ps.executeQuery();
 58             if (rs.next()) {
 59                 result = rs.getInt(1);
 60             }
 61         }catch (Exception e) {
 62             System.out.println(e);
 63         } finally {
 64             close(con, ps, rs);
 65         }
 66         return result;
 67     }
 68 
 69     public static <T> List<T> executeList(Class<T> cls, String cmdText)
 70             throws ClassNotFoundException, SQLException,
 71             InstantiationException, IllegalAccessException {
 72         List<T> list = new ArrayList<T>();
 73         Connection con = null;
 74         PreparedStatement ps = null;
 75         ResultSet rs = null;
 76         try {
 77             con = getConnection();
 78             ps = con.prepareStatement(cmdText);
 79             rs = ps.executeQuery();
 80             while (rs.next()) {
 81                 T obj = executeResultSet(cls, rs);
 82                 list.add(obj);
 83             }
 84         } catch (Exception e) {
 85             System.out.println(e);
 86         }finally {
 87             close(con, ps, rs);
 88         }
 89         return list;
 90     }
 91 
 92     public static <T> T executeEntity(Class<T> cls, String cmdText)
 93             throws SQLException, ClassNotFoundException,
 94             InstantiationException, IllegalAccessException {
 95         T obj = null;
 96         Connection con = null;
 97         PreparedStatement ps = null;
 98         ResultSet rs = null;
 99         try {
100             con = getConnection();
101             ps = con.prepareStatement(cmdText);
102             rs = ps.executeQuery();
103             while (rs.next()) {
104                 obj = executeResultSet(cls, rs);
105                 break;
106             }
107         } catch (Exception e) {
108             System.out.println(e);
109         }finally {
110             close(con, ps, rs);
111         }
112         return obj;
113     }
114 
115     private static <T> T executeResultSet(Class<T> cls, ResultSet rs)
116             throws InstantiationException, IllegalAccessException, SQLException {
117         T obj = cls.newInstance();
118         ResultSetMetaData rsm = rs.getMetaData();
119         int columnCount = rsm.getColumnCount();
120 //        Field[] fields = cls.getFields();
121         Field[] fields = cls.getDeclaredFields();
122         for (int i = 0; i < fields.length; i++) {
123             Field field = fields[i];
124             String fieldName = field.getName();
125             for (int j = 1; j <= columnCount; j++) {
126                 String columnName = rsm.getColumnName(j);
127                 if (fieldName.equalsIgnoreCase(columnName)) {
128                     Object value = rs.getObject(j);
129                     field.setAccessible(true);
130                     field.set(obj, value);
131                     break;
132                 }
133             }
134         }
135         return obj;
136     }
137 
138     private static void close(Connection con, PreparedStatement ps, ResultSet rs)
139             throws SQLException {
140         if (rs != null) {
141             rs.close();
142             rs = null;
143         }
144         if (ps != null ) {
145             ps.close();
146             ps = null;
147         }
148         if (con != null) {
149             con.close();
150             con = null;
151         }
152     }
153 }
View Code

5.搭建entity,dal,bll包。(三层是从net开发转过来的,也可以使用do包,dao包)。

6.JSP页面使用代码如下:

 1 <%@ page language="java" import="java.util.*,bll.*,entity.*" pageEncoding="UTF-8"%>
 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 3 <html>
 4 <head>
 5 <title>采用数据源和JNDI资源方式,创建并使用数据库连接池对象访问数据库实例。</title>
 6 </head>
 7 <body>
 8 <div>
 9 <h1>采用数据源和JNDI资源方式,创建并使用数据库连接池对象访问数据库实例。</h1>
10     <%
11         List<Student> list = StudentBLL.Select();
12         for (Student student : list) {
13             out.println(String.format(
14                     "<ol><li>StudentId:%d</li><li>StudentName:%s</li><li>Phone:%s</li><li>Email:%s</li><li>Address:%s</li></ol>",
15                     student.getStudentId(), student.getStudentName(),
16                     student.getPhone(), student.getEmail(),
17                     student.getAddress()));
18         }
19     %>
20 </div>
21 </body>
22 </html>
View Code

7.如果Context文件中auth属性设置为:Container,需要将数据库连接的jar文件复制到Tomcat的lib目录下。如果auth属性设置为:Application,则不需要复制到Tomcat的lib目录下。

8.部署运行界面大功告成。

posted @ 2014-03-31 10:57  —八戒—  阅读(2942)  评论(0编辑  收藏  举报