数据源与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 }
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>
7.如果Context文件中auth属性设置为:Container,需要将数据库连接的jar文件复制到Tomcat的lib目录下。如果auth属性设置为:Application,则不需要复制到Tomcat的lib目录下。
8.部署运行界面大功告成。