1、数据库连接池简介
数据库连接是一种关键的、有限的、昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标,数据库连接池正是针对这个问题提出来的。
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏,这项技术能明显提高对数据库操作的性能。
1.1数据库连接池配置的几个注意事项:
1. 最小连接数
是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费。
2. 最大连接数
是连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求将被加入到等待队列中,这会影响之后的数据库操作。
3. 最小连接数与最大连接数差距
最小连接数与最大连接数相差太大,那么最先的连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接。不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,它将被放到连接池中等待重复使用或是空闲超时后被释放。
1.2 Java中常见数据库连接池
1****、C3P0:是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate [2] 一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。
3****、DBCP:DBCP(DataBase Connection Pool)数据库连接池,是Java数据库连接池的一种,由Apache开发,通过数据库连接池,可以让程序自动管理数据库连接的释放和断开。
4****、DBPool:是一个高效、易配置的数据库连接池。它除了支持连接池应有的功能之外,还包括了一个对象池,使用户能够开发一个满足自己需求的数据库连接池。
5****、XAPool:是一个XA数据库连接池。它实现了javax.sql.XADataSource并提供了连接池工具。
6****、SmartPool:是一个连接池组件,它模仿应用服务器对象池的特性。SmartPool能够解决一些临界问题如连接泄漏(connection leaks)、连接阻塞、打开的JDBC对象(如Statements、PreparedStatements)等。
7****、BoneCP:是一个快速、开源的数据库连接池。帮用户管理数据连接,让应用程序能更快速地访问数据库。比C3P0/DBCP连接池速度快25倍。
8****、Druid:Druid不仅是一个数据库连接池,还包含一个ProxyDriver、一系列内置的JDBC组件库、一个SQL Parser。
支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等。
Druid针对Oracle和MySql做了特别优化,比如:
Oracle的PS Cache内存占用优化
MySql的ping检测优化
Druid提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,这是一个手写的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象语法树很方便。
简单SQL语句用时10微秒以内,复杂SQL用时30微秒。
通过Druid提供的SQL Parser可以在JDBC层拦截SQL做相应处理,比如说分库分表、审计等。Druid防御SQL注入攻击的WallFilter,就是通过Druid的SQL Parser分析语义实现的
1.3连接池的原理
连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等。也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。
2、Druid简介
Druid是阿里巴巴的一个开源数据库连接池,基于Apache 2.0协议,可以免费自由使用。很多人都说它是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。但它不仅仅是一个数据库连接池,它还包含一个ProxyDriver,一系列内置的JDBC组件库,一个SQL Parser。
Druid支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等等,并且Druid针对Oracle和MySql做了特别优化,比如Oracle的PS Cache内存占用优化,MySql的ping检测优化。
Druid能够提供强大的监控和扩展功能,通过Druid提供的监控功能,监控SQL的执行时间、ResultSet持有时间、返回行数、更新行数、错误次数、错误堆栈信息,可以清楚知道连接池和SQL的工作情况,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能有帮助。
源码地址: https://github.com/alibaba/druid
下面就以实例的方式说明druid的使用和开启监控功能:
这里我结合SpringMVC + MySQL + druid实现
3、创建Maven工程
4、pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ts</groupId>
<artifactId>druid_datasource_monitor2</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>druid_datasource_monitor Maven Webapp</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>4.3.23.RELEASE</spring.version>
<mysql.driver.version>5.1.38</mysql.driver.version>
<druid.version>1.1.16</druid.version>
<postgresql.version>42.2.5</postgresql.version>
</properties>
<dependencies> <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt --> <dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.4</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjtools --> <dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.9.4</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency> <!--Spring--> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency> <!--test--> <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency> <!--mysql--> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.driver.version}</version>
</dependency> <!-- druid --> <dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency> <!-- postgresql --> <dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
</dependency> <!-- mysql --> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
</dependency> <!--Servlet--> <dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency> <!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<finalName>druid_datasource_monitor</finalName>
<plugins> <!-- 编译插件 --> <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin> <!-- tomcat7-maven-plugin --> <plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/</path>
<port>8080</port>
<uriEncoding>UTF-8</uriEncoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
5、POJO
User.java
<pre style="background:#2B2B2B">package com.ts.pojo;
import java.io.Serializable;
import java.util.Date; */**
* **@Author*** *ZQ* ** **@Description** //**TODO* *用户实体类*** **@Date** 13:45 2019/6/17
**/* public class User implements Serializable { private Integer id;
private String name;
private String sex;
private Date birthday;
private String email;
private String loginName;
private String pwd;
private String address;
public User() {
} public User(String name, String sex, Date birthday, String email) { this.name = name;
this.sex = sex;
this.birthday = birthday;
this.email = email; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getLoginName() {
return loginName; } public void setLoginName(String loginName) { this.loginName = loginName; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", sex='" + sex + '\'' + ", birthday=" + birthday + ", email='" + email + '\'' + ", loginName='" + loginName + '\'' + ", pwd='" + pwd + '\'' + ", address='" + address + '\'' + '}'; }
}</pre>
6、Dao
UserDao.java
<pre style="background:#2B2B2B">package com.ts.dao;
import com.ts.pojo.User;
import java.util.List; */**
* **@Author*** *ZQ* ** **@Description** //**TODO* *数据访问接口*** **@Date** 10:50 2019/5/13
* **@Param
*** **@return
****/* public interface UserDao { */**
* **@Author*** *ZQ* ** **@Description** //**TODO* *按照名称和密码查询*** **@Date** 10:51 2019/5/13
* **@Param** [name, pwd]
* **@return** boolean
**/* User selectByNameAndPwd(String name, String pwd)throws Exception; */**
* **@Author*** *ZQ* ** **@Description** //**TODO* *按照**ID**查询*** **@Date** 13:59 2019/6/17
* **@Param** [id]
* **@return** com.ts.pojo.User
**/* User selectById(int id)throws Exception; */**
* **@Author*** *ZQ* ** **@Description** //**TODO* *按照名称模糊查询*** **@Date** 13:59 2019/6/17
* **@Param** [name]
* **@return** java.util.List*<*com.ts.pojo.User*> ***/* List<User> selectByName(String name)throws Exception; //插入 int insert(User user)throws Exception;
//更新 int udpate(User user)throws Exception; //删除 int deleteById(int id)throws Exception; }</pre>
UserDaoImpl.java
<pre style="background:#2B2B2B">package com.ts.dao.impl;
import com.ts.dao.UserDao;
import com.ts.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List; */***
* **@Author*** *ZQ* ** **@Description** //**TODO Da**实现*** **@Date** 10:51 2019/6/17
**/* @Repository public class UserDaoImpl implements UserDao { @Autowired private JdbcTemplate jdbcTemplate;
private RowMapper<User> rowMapper = new RowMapper<User>() { @Override public User mapRow(ResultSet resultSet, int i) throws SQLException {
User user = new User(); user.setId(resultSet.getInt("id")); user.setName(resultSet.getString("name")); user.setLoginName(resultSet.getString("loginName")); user.setPwd(resultSet.getString("pwd")); user.setSex(resultSet.getString("sex")); user.setBirthday(resultSet.getDate("birthday")); user.setAddress(resultSet.getString("address")); user.setEmail(resultSet.getString("email"));
return user; }
}; @Override public User selectByNameAndPwd(String name, String pwd) throws Exception {
String sql = "select * from users where loginName = ? and pwd = ?"; Object[] args ={name,pwd};
return jdbcTemplate.queryForObject(sql,args,rowMapper); } @Override public User selectById(int id) throws Exception {
String sql = "select * from users where id = ?"; Object[] args ={id};
return jdbcTemplate.queryForObject(sql,args,rowMapper); } @Override public List<User> selectByName(String name) throws Exception {
String sql = "select * from users where name like ?"; Object[] args ={"%"+name+"%"};
return jdbcTemplate.query(sql,args,new BeanPropertyRowMapper<User>(User.class)); // return jdbcTemplate.query(sql,args,rowMapper); //自定义RowMapper } @Override public int insert(User user) throws Exception {
String sql = "insert into users(name,loginName,pwd,sex,birthday,address,email) values(?,?,?,?,?,?,?)"; Object[] args ={user.getName(),user.getLoginName(),user.getPwd(),user.getSex(), user.getBirthday(),user.getAddress(),user.getEmail()};
return jdbcTemplate.update(sql,args); } @Override public int udpate(User user) throws Exception {
String sql = "update users set name=? where id=?"; Object[] args ={user.getName(),user.getId()};
return jdbcTemplate.update(sql,args); } @Override public int deleteById(int id) throws Exception {
String sql = "delete from users where id=?";
return jdbcTemplate.update(sql,id); }
}</pre>
7 Service
UserService.java
<pre style="background:#2B2B2B">package com.ts.service;
import com.ts.pojo.User;
import java.util.List; */**
* **@Author*** *ZQ* ** **@Description** //**TODO* *业务接口*** **@Date** 10:54 2019/6/17
**/* public interface UserService {
User login(String name, String pwd); User search(int id); List<User> search(String name); }</pre>
UserServiceImpl.java
<pre style="background:#2B2B2B">package com.ts.service.impl;
import com.ts.dao.UserDao;
import com.ts.pojo.User;
import com.ts.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List; */**
* **@Author*** *ZQ* ** **@Description** //**TODO* *业务接口实现类*** **@Date** 13:49 2019/6/17
**/* @Service public class UserServiceImpl implements UserService { //依赖注入 @Autowired private UserDao userDao; */**
* **@Author*** *ZQ* ** **@Description** //**TODO* *登录*** **@Date** 10:55 2019/6/17
* **@Param** [name, pwd]
* **@return** boolean
**/* @Override public User login(String name, String pwd) { try { return userDao.selectByNameAndPwd(name,pwd); } catch (Exception e) {
e.printStackTrace(); } return null; } @Override public User search(int id) { try { return userDao.selectById(id); } catch (Exception e) {
e.printStackTrace(); } return null; } @Override public List<User> search(String name) { try {
return userDao.selectByName(name); } catch (Exception e) {
e.printStackTrace(); } return null; }
}</pre>
8、控制器
UserController.java
<pre style="background:#2B2B2B">package com.ts.controller;
import com.ts.pojo.User;
import com.ts.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpSession; */**
* **@Author*** *ZQ* ** **@Description** //**TODO* *控制器*** **@Date** 10:48 2019/6/17
**/* @Controller public class UserController { //注入业务接口 @Autowired private UserService userService; */**
* SpringMVC* *参数绑定* **/* @RequestMapping("/login.do") public ModelAndView login(String username,String password,HttpSession session)throws Exception {
ModelAndView mv = new ModelAndView(); User user = userService.login(username,password);
if(user!=null){
session.setAttribute("CurrUser",username); mv.setViewName("success"); }else{
mv.setViewName("error"); } return mv; } @GetMapping("/search.do") public String search(String name, Model model){
model.addAttribute("userList",userService.search(name));
return "search"; }
}</pre>
9、视图
login.jsp
<pre style="background:#2B2B2B"><%--
Created by IntelliJ IDEA.
User: zq
Date: 2019/6/17
Time: 11:03
To change this template use File``` Settings``` File Templates.
--%> <%@ **page** contentType="text/html;charset=UTF-8" language="java" %> <html>
<head>
<title>用户登录</title>
</head>
<body>
<form action="login.do" method="post">
<fieldset>
<legend>用户登录</legend> 用户:<input type="text" name="username"><br> 密码:<input type="password" name="password"><br>
<input type="submit" value="登 录">
</fieldset>
</form>
<a href="search.jsp">查询</a>
</body>
</html></pre>
success.jsp
<pre style="background:#2B2B2B"><%--
Created by IntelliJ IDEA.
User: zq
Date: 2019/6/17
Time: 11:04
To change this template use File``` Settings``` File Templates.
--%> <%@ **page** contentType="text/html;charset=UTF-8" language="java" %> <html>
<head>
<title>登录成功</title>
</head>
<body>
<h1>${CurrUser},登录成功!</h1>
<a href="login.jsp">返回</a>
</body>
</html></pre>
error.jsp
<pre style="background:#2B2B2B"><%--
Created by IntelliJ IDEA.
User: zq
Date: 2019/6/17
Time: 11:05
To change this template use File``` Settings``` File Templates.
--%> <%@ **page** contentType="text/html;charset=UTF-8" language="java" %> <html>
<head>
<title>登录失败</title>
</head>
<body>
<h1>登录失败!</h1>
<a href="login.jsp">返回</a>
</body>
</html></pre>
search.jsp
<pre style="background:#2B2B2B"><%--
Created by IntelliJ IDEA.
User: zq
Date: 2019/6/17
Time: 15:25
To change this template use File``` Settings``` File Templates.
--%> <%@ **page** contentType="text/html;charset=UTF-8" language="java" %> <%@**taglib** prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html>
<head>
<title>用户查询</title>
</head>
<body>
<form action="search.do">
<fieldset>
<input name="name" placeholder="请输入用户名">
<button>Search</button>
</fieldset>
</form> <**c****:if** test="${not empty userList}"> <hr>
<table border="1">
<tr>
<td>编号</td>
<td>姓名</td>
<td>性别</td>
<td>登录名</td>
<td>地址</td>
<td>邮箱</td>
</tr> <**c****:forEach** var="user" items="${userList}"> <tr>
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.sex}</td>
<td>${user.loginName}</td>
<td>${user.address}</td>
<td>${user.email}</td>
</tr> </**c****:forEach**> </table> </**c****:if**> </body>
</html></pre>
10、 配置文件
main\resources\jdbc.properties
<pre style="background:#2B2B2B"># postgreSQL 的配置 #jdbc.driverClassName=org.postgresql.Driver
#jdbc.url=jdbc:postgresql://localhost:5432/test
#jdbc.username=test
#jdbc.password=123
# MySQL配置 jdbc.driverClassName=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/test?serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true jdbc.username=root jdbc.password=root # druid 的一些配置 spring.druid.initialSize=5 spring.druid.minIdle=5 spring.druid.maxActive=20 spring.druid.maxWait=60000 spring.druid.timeBetweenEvictionRunsMillis=60000 spring.druid.minEvictableIdleTimeMillis=300000 spring.druid.validationQueryTimeout=60000 spring.druid.validationQuery=SELECT 1 spring.druid.testWhileIdle=true spring.druid.testOnBorrow=false spring.druid.testOnReturn=false spring.druid.poolPreparedStatements=false spring.druid.maxPoolPreparedStatementPerConnectionSize=20 spring.druid.defaultAutoCommit=true spring.druid.filters=stat,wall,log4j spring.druid.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 </pre>
配置选项说明:
spring.druid.initialSize初始化连接大小
spring.druid.minIdle最小连接池数量
spring.druid.maxActive最大连接池数量
spring.druid.maxWait获取连接时最大等待时间,单位毫秒
spring.druid.timeBetweenEvictionRunsMillis配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.druid.minEvictableIdleTimeMillis配置一个连接在池中最小生存的时间,单位是毫秒
spring.druid.validationQuery测试连接
spring.druid.testWhileIdle申请连接的时候检测,建议配置为true,不影响性能,并且保证安全性
spring.druid.testOnBorrow获取连接时执行检测,建议关闭,影响性能
spring.druid.testOnReturn归还连接时执行检测,建议关闭,影响性能
spring.druid.poolPreparedStatements是否开启PSCache,PSCache对支持游标的数据库性能提升巨大,oracle建议开启,mysql下建议关闭
spring.druid.maxPoolPreparedStatementPerConnectionSize开启poolPreparedStatements后生效
spring.druid.filters配置扩展插件,常用的插件有=>stat:监控统计 log4j:日志 wall:防御sql注入
spring.druid.connectionProperties通过connectProperties属性来打开mergeSql功能;慢SQL记录
main\resources\log4j.properties
<pre style="background:#2B2B2B">#定义输出格式 ConversionPattern=%d %-5p [%t] %c - %m%n log4j.rootLogger=ERROR,Console #Console log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.Console.Threshold=ERROR log4j.appender.Console.Target=System.out log4j.appender.Console.layout=org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern=${ConversionPattern} #log4j.appender.Console.encoding=UTF-8
# %c 输出日志信息所属的类的全名 # %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy-MM-dd HH:mm:ss},输出类似:2002-10-18- 22:10:28
# %f 输出日志信息所属的类的类名 # %l 输出日志事件的发生位置,即输出日志信息的语句处于它所在的类的第几行 # %m 输出代码中指定的信息,如log(message)中的message
# %n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n” # %p 输出优先级,即ERROR,INFO,WARN,ERROR,FATAL。如果是调用debug()输出的,则为ERROR,依此类推 # %r 输出自应用启动到输出该日志信息所耗费的毫秒数 # %t 输出产生该日志事件的线程名</pre>
main\resources\spring-dao.xml
<pre style="background:#2B2B2B"><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--导入属性文件--> <context:property-placeholder location="classpath*:jdbc.properties"/> <!--配置Druid数据源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" /> <!-- 配置初始化大小、最小、最大 --> <property name="initialSize" value="${spring.druid.initialSize}" />
<property name="minIdle" value="${spring.druid.minIdle}" />
<property name="maxActive" value="${spring.druid.maxActive}" /> <!-- 配置获取连接等待超时的时间 --> <property name="maxWait" value="${spring.druid.maxWait}" /> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="${spring.druid.timeBetweenEvictionRunsMillis}" /> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="${spring.druid.minEvictableIdleTimeMillis}" />
<property name="validationQuery" value="${spring.druid.validationQuery}" />
<property name="validationQueryTimeout" value="${spring.druid.validationQueryTimeout}"/>
<property name="testWhileIdle" value="${spring.druid.testWhileIdle}" /> <!-- 这里建议配置为TRUE,防止取到的连接不可用 --> <property name="testOnBorrow" value="${spring.druid.testOnBorrow}" />
<property name="testOnReturn" value="${spring.druid.testOnReturn}" /> <!-- 打开PSCache,并且指定每个连接上PSCache的大小 --> <property name="poolPreparedStatements" value="${spring.druid.poolPreparedStatements}" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="${spring.druid.maxPoolPreparedStatementPerConnectionSize}" /> <!-- 这里配置提交方式,默认就是true,可以不用配置 --> <property name="defaultAutoCommit" value="${spring.druid.defaultAutoCommit}" />
<property name="filters" value="${spring.druid.filters}" />
<property name="connectionProperties" value="${spring.druid.connectionProperties}" />
</bean> <!--模板--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans></pre>
main\resources\spring-mvc.xml
<pre style="background:#2B2B2B"><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
"> <!--扫描包--> <context:component-scan base-package="com.ts" /> <!--使用注解--> <mvc:annotation-driven/> <!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 配置前缀和后缀 --> <property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans></pre>
main\resources\spring-service.xml
<pre style="background:#2B2B2B"><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- druidSpring配置 --> <bean id="druid-stat-interceptor" class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor">
</bean>
<bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut" scope="prototype">
<property name="patterns">
<list>
<value>com.ts.service.*</value>
<value>com.ts.dao.*</value>
</list>
</property>
</bean>
<aop:config proxy-target-class="true">
<aop:advisor advice-ref="druid-stat-interceptor" pointcut-ref="druid-stat-pointcut" />
</aop:config>
</beans></pre>
11、web.xml
<pre style="background:#2B2B2B"><?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list> <!-- 配置Spring 前置控制器 Servlet --> <servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-*.xml</param-value>
</init-param>
</servlet> <!-- 控制器 拦截 以 .do结尾的请求--> <servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping> <!-- 使用Spring的过滤器,解决中文乱码问题 --> <filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app></pre>