配置Tomcat数据源
在实际开发中,我们有时候还会使用服务器提供给我们的数据库连接池,比如我们希望Tomcat服务器在启动的时候可以帮我们创建一个数据库连接池,那么我们在应用程序中就不需要手动去创建数据库连接池,直接使用Tomcat服务器创建好的数据库连接池即可。要想让Tomcat服务器在启动的时候帮我们创建一个数据库连接池,那么需要简单配置一下Tomcat服务器。
4.1、JNDI技术简介
JNDI(Java Naming and Directory Interface),Java命名和目录接口,它对应于J2SE中的javax.naming包,
这 套API的主要作用在于:它可以把Java对象放在一个容器中(JNDI容器),并为容器中的java对象取一个名称,以后程序想获得Java对象,只需 通过名称检索即可。其核心API为Context,它代表JNDI容器,其lookup方法为检索容器中对应名称的对象。
Tomcat服务器创建的数据源是以JNDI资源的形式发布的,所以说在Tomat服务器中配置一个数据源实际上就是在配置一个JNDI资源,通过查看Tomcat文档,我们知道使用如下的方式配置tomcat服务器的数据源:
1 <Context> 2 <Resource name="jdbc/datasource" auth="Container" 3 type="javax.sql.DataSource" username="root" password="XDP" 4 driverClassName="com.mysql.jdbc.Driver" 5 url="jdbc:mysql://localhost:3306/jdbcstudy" 6 maxActive="8" maxIdle="4"/> 7 </Context>
服务器创建好数据源之后,我们的应用程序又该怎么样得到这个数据源呢,Tomcat服务器创建好数据源之后是以JNDI的形式绑定到一个JNDI容器中的,我们可以把JNDI想象成一个大大的容器,我们可以往这个容器中存放一些对象,一些资源,JNDI容器中存放的对象和资源都会有一个独一无二的名称,应用程序想从JNDI容器中获取资源时,只需要告诉JNDI容器要获取的资源的名称,JNDI根据名称去找到对应的资源后返回给应用程序。我们平时做javaEE开发时,服务器会为我们的应用程序创建很多资源,比如request对象,response对象,服务器创建的这些资源有两种方式提供给我们的应用程序使用:第一种是通过方法参数的形式传递进来,比如我们在Servlet中写的doPost和doGet方法中使用到的request对象和response对象就是服务器以参数的形式传递给我们的。第二种就是JNDI的方式,服务器把创建好的资源绑定到JNDI容器中去,应用程序想要使用资源时,就直接从JNDI容器中获取相应的资源即可。
对于上面的name="jdbc/datasource"数据源资源,在应用程序中可以用如下的代码去获取
1 Context initCtx = new InitialContext(); 2 Context envCtx = (Context) initCtx.lookup("java:comp/env"); 3 dataSource = (DataSource)envCtx.lookup("jdbc/datasource");
此种配置下,数据库的驱动jar文件需放置在tomcat的lib下
4.2、配置Tomcat数据源
1、在Web项目的WebRoot目录下的META-INF目录创建一个context.xml文件
2、在context.xml文件配置tomcat服务器的数据源
1 <Context> 2 <Resource 3 name="jdbc/datasource" 4 auth="Container" 5 type="javax.sql.DataSource" 6 username="root" 7 password="XDP" 8 driverClassName="com.mysql.jdbc.Driver" 9 url="jdbc:mysql://localhost:3306/jdbcstudy" 10 maxActive="8" 11 maxIdle="4"/> 12 </Context>
3、将数据库的驱动jar文件需放置在tomcat的lib下
4、在获取数据库连接的工具类(如jdbcUtils)的静态代码块中获取JNDI容器中的数据源
1 package me.gacl.util; 2 3 import java.sql.Connection; 4 import java.sql.ResultSet; 5 import java.sql.SQLException; 6 import java.sql.Statement; 7 import javax.naming.Context; 8 import javax.naming.InitialContext; 9 import javax.sql.DataSource; 10 11 /** 12 * @ClassName: JdbcUtils_DBCP 13 * @Description: 数据库连接工具类 14 * @author: 孤傲苍狼 15 * @date: 2014-10-4 下午6:04:36 16 * 17 */ 18 public class JdbcUtils_JNDI { 19 20 private static DataSource ds = null; 21 //在静态代码块中创建数据库连接池 22 static{ 23 try{ 24 //初始化JNDI 25 Context initCtx = new InitialContext(); 26 //得到JNDI容器 27 Context envCtx = (Context) initCtx.lookup("java:comp/env"); 28 //从JNDI容器中检索name为jdbc/datasource的数据源 29 ds = (DataSource)envCtx.lookup("jdbc/datasource"); 30 }catch (Exception e) { 31 throw new ExceptionInInitializerError(e); 32 } 33 } 34 35 /** 36 * @Method: getConnection 37 * @Description: 从数据源中获取数据库连接 38 * @Anthor:孤傲苍狼 39 * @return Connection 40 * @throws SQLException 41 */ 42 public static Connection getConnection() throws SQLException{ 43 //从数据源中获取数据库连接 44 return ds.getConnection(); 45 } 46 47 /** 48 * @Method: release 49 * @Description: 释放资源, 50 * 释放的资源包括Connection数据库连接对象,负责执行SQL命令的Statement对象,存储查询结果的ResultSet对象 51 * @Anthor:孤傲苍狼 52 * 53 * @param conn 54 * @param st 55 * @param rs 56 */ 57 public static void release(Connection conn,Statement st,ResultSet rs){ 58 if(rs!=null){ 59 try{ 60 //关闭存储查询结果的ResultSet对象 61 rs.close(); 62 }catch (Exception e) { 63 e.printStackTrace(); 64 } 65 rs = null; 66 } 67 if(st!=null){ 68 try{ 69 //关闭负责执行SQL命令的Statement对象 70 st.close(); 71 }catch (Exception e) { 72 e.printStackTrace(); 73 } 74 } 75 76 if(conn!=null){ 77 try{ 78 //将Connection连接对象还给数据库连接池 79 conn.close(); 80 }catch (Exception e) { 81 e.printStackTrace(); 82 } 83 } 84 } 85 }
写一个Servlet测试JNDI数据源
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 javax.servlet.ServletException; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest; 10 import javax.servlet.http.HttpServletResponse; 11 import me.gacl.util.JdbcUtils_JNDI; 12 13 public class JNDITest extends HttpServlet { 14 15 public void doGet(HttpServletRequest request, HttpServletResponse response) 16 throws ServletException, IOException { 17 Connection conn = null; 18 PreparedStatement st = null; 19 ResultSet rs = null; 20 try{ 21 //获取数据库连接 22 conn = JdbcUtils_JNDI.getConnection(); 23 String sql = "insert into test1(name) values(?)"; 24 st = conn.prepareStatement(sql); 25 st.setString(1, "gacl"); 26 st.executeUpdate(); 27 //获取数据库自动生成的主键 28 rs = st.getGeneratedKeys(); 29 if(rs.next()){ 30 System.out.println(rs.getInt(1)); 31 } 32 }catch (Exception e) { 33 e.printStackTrace(); 34 }finally{ 35 //释放资源 36 JdbcUtils_JNDI.release(conn, st, rs); 37 } 38 } 39 40 public void doPost(HttpServletRequest request, HttpServletResponse response) 41 throws ServletException, IOException { 42 doGet(request, response); 43 } 44 45 }