18. Tomcat 数据源
1.数据库和连接池
在DataSource中事先建立了多个数据库连接,这些数据库连接保存在连接池(ConnectPool)中。java程序访问数据库时,只需要从连接池中取出空闲状态的数据库连接,当程序访问数据库结束,再将数据库连接放回连接池,这样做可以调高访问数据库的效率。
如果Web应用每次接收到客户的请求,都和数控建立一个连接,数控操作结束就断开连接,这样会消费大量的时间和资源。因为数据库每次配置连接都要将Connection对象加载到内存中,再验证用户名和密码。
2.数据源和JNDI资源
从Tomcat 5.5开始,Tomcat 内置了DBCP的数据源实现,所以可以非常方便地配置DBCP数据源。不管配置哪种数据源,都需要提供特定地数据库的JDBC驱动
由于DataSource对象是由Tomcat提供的,因此不能够在程序中创建一个DataSource对象,而要采用JNDI技术来获得DataSource对象的引用。
可以简单的把JNDI理解为一种将对象和名字绑定的技术,对象工厂负责生产出对象,这些对象都和唯一的名字绑定,外部程序可以通过名字来获得某个对象的引用。在javax.naming包中提供了Context接口,该接口提供了将对象和名字绑定,以及通过名字检索对象的方法。
Context接口方法
方 法 | 描 述 |
---|---|
bind(String name,Object obj) | 将对象与一个名字绑定 |
lookup(String name) | 返回与指定的名字绑定的对象 |
Tomcat把DataSource作为一种可配置的JNDI资源来处理。生成DataSource对象的工厂org.apache.commons.dbcp.BasicDataSourceFactory。
3.配置数据源
此处与Tomcat8.5 +mysql数据库为例,配置Tomcat数据源并使用,官方文档 地址
1.安装驱动
将数据库驱动放到$CATALINA_HOME/lib
目录中,其中$CATALINA_HOME
指的是tomcat的安目录,下同
2. 准备数据库和表
CREATE DATABASE `mis` DEFAULT CHARACTER SET utf8mb4;
USE `mis`;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(500) DEFAULT NULL,
`password` varchar(500) DEFAULT NULL,
`nickname` varchar(500) DEFAULT NULL,
`lastlogin` datetime DEFAULT NULL,
`ctime` datetime DEFAULT CURRENT_TIMESTAMP,
`valid` varchar(10) DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=104 DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
insert into `user`(`id`,`username`,`password`,`nickname`,`lastlogin`,`ctime`,`valid`) values (1,'admin','123456','管理員','2021-07-30 10:20:49','2021-07-30 10:20:50','1'),(2,'root','!@#$%^&*','系统管理員','2021-07-30 11:01:44','2021-07-30 11:01:44','1'),(4,'0user','123456','0系统管理員','2021-07-30 15:54:02','2021-07-30 15:54:03','1'),(5,'1user','123456','1系统管理員','2021-07-30 15:54:06','2021-07-30 15:54:05','1'),(6,'2user','123456','2系统管理員','2021-07-30 15:54:06','2021-07-30 15:54:06','1'),(7,'3user','123456','3系统管理員','2021-07-30 15:54:06','2021-07-30 15:54:06','1'),(8,'4user','123456','4系统管理員','2021-07-30 15:54:06','2021-07-30 15:54:06','1'),(9,'5user','123456','5系统管理員','2021-07-30 15:54:06','2021-07-30 15:54:06','1'),(10,'6user','123456','6系统管理員','2021-07-30 15:54:06','2021-07-30 15:54:06','1'),(11,'7user','123456','7系统管理員','2021-07-30 15:54:06','2021-07-30 15:54:06','1'),(12,'8user','123456','8系统管理員','2021-07-30 15:54:06','2021-07-30 15:54:06','1');
3 配置上下文资源 Context configuration
修改$CATALINA_HOME/conf/context.xml
,在Context
节点中追加Resource
标签,完整内容如下
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
--><!-- The contents of this file will be loaded for each web application -->
<Context>
<!-- Default set of monitored resources. If one of these changes, the -->
<!-- web application will be reloaded. -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
<Resource name="jdbc/DBMis" auth="Container" type="javax.sql.DataSource"
maxTotal="100" maxIdle="30" maxWaitMillis="10000"
username="root" password="root" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mis"/>
</Context>
注意如果是使用eclipse的Tomcat插件,则有可能此文件会被覆盖,可以找到Eclipse中Server下的Context.xml中进行配置,eclipse中的context.xml位置大致如下
4.在web.xml中配置引用jdni数据源
创建项目,并在web.xml中配置资源的引用
web.xml如下
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>tomcat_datasouece</display-name>
<resource-ref>
<description>Tomcat数据源引用</description>
<res-ref-name>jdbc/DBMis</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
5.在Java中获取数据源连接
package com.neuedu.servlet;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
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;
/**
* 获取数据源
*/
@WebServlet("/ds")
public class DataSourceServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
DataSource ds = null;
Connection conn = null;
try {
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
ds = (DataSource)envContext.lookup("jdbc/DBMis");
conn = ds.getConnection();
System.out.println("通过JNDI上下文获取 配置好的【数据源】:"+ds);
System.out.println("通过JNDI上下文获取 配置好的【连接】:"+conn);
} catch (NamingException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
response.setContentType("text/html;charset=utf-8");
response.getWriter().
append("Served at: ").
append(request.getContextPath()).
append("<div>ds: "+ds+"</div>").
append("<div>conn: "+conn+"</div>");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
