理解数据库连接池-结合SpringMVC + MySQL + druid实例

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>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,681评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,710评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,623评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,202评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,232评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,368评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,795评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,461评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,647评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,476评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,525评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,226评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,785评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,857评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,090评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,647评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,215评论 2 341

推荐阅读更多精彩内容