1、數(shù)據(jù)庫連接池簡介
數(shù)據(jù)庫連接是一種關(guān)鍵的剩岳、有限的贞滨、昂貴的資源,這一點在多用戶的網(wǎng)頁應用程序中體現(xiàn)得尤為突出拍棕。對數(shù)據(jù)庫連接的管理能顯著影響到整個應用程序的伸縮性和健壯性晓铆,影響到程序的性能指標,數(shù)據(jù)庫連接池正是針對這個問題提出來的绰播。
數(shù)據(jù)庫連接池負責分配尤蒿、管理和釋放數(shù)據(jù)庫連接,它允許應用程序重復使用一個現(xiàn)有的數(shù)據(jù)庫連接幅垮,而不是再重新建立一個;釋放空閑時間超過最大空閑時間的數(shù)據(jù)庫連接來避免因為沒有釋放數(shù)據(jù)庫連接而引起的數(shù)據(jù)庫連接遺漏尾组,這項技術(shù)能明顯提高對數(shù)據(jù)庫操作的性能忙芒。
1.1數(shù)據(jù)庫連接池配置的幾個注意事項:
1. 最小連接數(shù)
是連接池一直保持的數(shù)據(jù)庫連接,所以如果應用程序?qū)?shù)據(jù)庫連接的使用量不大讳侨,將會有大量的數(shù)據(jù)庫連接資源被浪費呵萨。
2. 最大連接數(shù)
是連接池能申請的最大連接數(shù),如果數(shù)據(jù)庫連接請求超過此數(shù)跨跨,后面的數(shù)據(jù)庫連接請求將被加入到等待隊列中潮峦,這會影響之后的數(shù)據(jù)庫操作。
3. 最小連接數(shù)與最大連接數(shù)差距
最小連接數(shù)與最大連接數(shù)相差太大勇婴,那么最先的連接請求將會獲利忱嘹,之后超過最小連接數(shù)量的連接請求等價于建立一個新的數(shù)據(jù)庫連接。不過耕渴,這些大于最小連接數(shù)的數(shù)據(jù)庫連接在使用完不會馬上被釋放拘悦,它將被放到連接池中等待重復使用或是空閑超時后被釋放。
1.2 Java中常見數(shù)據(jù)庫連接池
1****橱脸、C3P0:是一個開放源代碼的JDBC連接池础米,它在lib目錄中與Hibernate [2] 一起發(fā)布分苇,包括了實現(xiàn)jdbc3和jdbc2擴展規(guī)范說明的Connection 和Statement 池的DataSources 對象。
3****屁桑、DBCP:DBCP(DataBase Connection Pool)數(shù)據(jù)庫連接池医寿,是Java數(shù)據(jù)庫連接池的一種,由Apache開發(fā)蘑斧,通過數(shù)據(jù)庫連接池靖秩,可以讓程序自動管理數(shù)據(jù)庫連接的釋放和斷開。
4****乌叶、DBPool:是一個高效盆偿、易配置的數(shù)據(jù)庫連接池。它除了支持連接池應有的功能之外准浴,還包括了一個對象池事扭,使用戶能夠開發(fā)一個滿足自己需求的數(shù)據(jù)庫連接池。
5****乐横、XAPool:是一個XA數(shù)據(jù)庫連接池求橄。它實現(xiàn)了javax.sql.XADataSource并提供了連接池工具。
6****葡公、SmartPool:是一個連接池組件罐农,它模仿應用服務(wù)器對象池的特性。SmartPool能夠解決一些臨界問題如連接泄漏(connection leaks)催什、連接阻塞涵亏、打開的JDBC對象(如Statements、PreparedStatements)等蒲凶。
7****气筋、BoneCP:是一個快速、開源的數(shù)據(jù)庫連接池旋圆。幫用戶管理數(shù)據(jù)連接宠默,讓應用程序能更快速地訪問數(shù)據(jù)庫。比C3P0/DBCP連接池速度快25倍灵巧。
8****搀矫、Druid:Druid不僅是一個數(shù)據(jù)庫連接池,還包含一個ProxyDriver刻肄、一系列內(nèi)置的JDBC組件庫瓤球、一個SQL Parser。
支持所有JDBC兼容的數(shù)據(jù)庫肄方,包括Oracle冰垄、MySql、Derby、Postgresql虹茶、SQL Server逝薪、H2等。
Druid針對Oracle和MySql做了特別優(yōu)化蝴罪,比如:
Oracle的PS Cache內(nèi)存占用優(yōu)化
MySql的ping檢測優(yōu)化
Druid提供了MySql董济、Oracle、Postgresql要门、SQL-92的SQL的完整支持虏肾,這是一個手寫的高性能SQL Parser,支持Visitor模式欢搜,使得分析SQL的抽象語法樹很方便封豪。
簡單SQL語句用時10微秒以內(nèi),復雜SQL用時30微秒炒瘟。
通過Druid提供的SQL Parser可以在JDBC層攔截SQL做相應處理吹埠,比如說分庫分表、審計等疮装。Druid防御SQL注入攻擊的WallFilter缘琅,就是通過Druid的SQL Parser分析語義實現(xiàn)的
1.3連接池的原理
連接池基本的思想是在系統(tǒng)初始化的時候,將數(shù)據(jù)庫連接作為對象存儲在內(nèi)存中廓推,當用戶需要訪問數(shù)據(jù)庫時刷袍,并非建立一個新的連接,而是從連接池中取出一個已建立的空閑連接對象樊展。使用完畢后呻纹,用戶也并非將連接關(guān)閉,而是將連接放回連接池中专缠,以供下一個請求訪問使用居暖。而連接的建立、斷開都由連接池自身來管理藤肢。同時,還可以通過設(shè)置連接池的參數(shù)來控制連接池中的初始連接數(shù)糯景、連接的上下限數(shù)以及每個連接的最大使用次數(shù)嘁圈、最大空閑時間等等。也可以通過其自身的管理機制來監(jiān)視數(shù)據(jù)庫連接的數(shù)量蟀淮、使用情況等最住。
2、Druid簡介
Druid是阿里巴巴的一個開源數(shù)據(jù)庫連接池怠惶,基于Apache 2.0協(xié)議涨缚,可以免費自由使用。很多人都說它是目前最好的數(shù)據(jù)庫連接池策治,在功能脓魏、性能兰吟、擴展性方面,都超過其他數(shù)據(jù)庫連接池茂翔,包括DBCP混蔼、C3P0、BoneCP珊燎、Proxool惭嚣、JBoss DataSource。但它不僅僅是一個數(shù)據(jù)庫連接池悔政,它還包含一個ProxyDriver晚吞,一系列內(nèi)置的JDBC組件庫,一個SQL Parser谋国。
Druid支持所有JDBC兼容的數(shù)據(jù)庫槽地,包括Oracle、MySql烹卒、Derby闷盔、Postgresql、SQL Server旅急、H2等等逢勾,并且Druid針對Oracle和MySql做了特別優(yōu)化,比如Oracle的PS Cache內(nèi)存占用優(yōu)化藐吮,MySql的ping檢測優(yōu)化溺拱。
Druid能夠提供強大的監(jiān)控和擴展功能,通過Druid提供的監(jiān)控功能谣辞,監(jiān)控SQL的執(zhí)行時間迫摔、ResultSet持有時間、返回行數(shù)泥从、更新行數(shù)句占、錯誤次數(shù)、錯誤堆棧信息躯嫉,可以清楚知道連接池和SQL的工作情況纱烘,能夠詳細統(tǒng)計SQL的執(zhí)行性能,這對于線上分析數(shù)據(jù)庫訪問性能有幫助祈餐。
源碼地址: https://github.com/alibaba/druid
下面就以實例的方式說明druid的使用和開啟監(jiān)控功能:
這里我結(jié)合SpringMVC + MySQL + druid實現(xiàn)
3擂啥、創(chuàng)建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* *數(shù)據(jù)訪問接口*** **@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**實現(xiàn)*** **@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* *業(yè)務(wù)接口*** **@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* *業(yè)務(wù)接口實現(xiàn)類*** **@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 { //注入業(yè)務(wù)接口 @Autowired private UserService userService; */**
* SpringMVC* *參數(shù)綁定* **/* @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最小連接池數(shù)量
spring.druid.maxActive最大連接池數(shù)量
spring.druid.maxWait獲取連接時最大等待時間至扰,單位毫秒
spring.druid.timeBetweenEvictionRunsMillis配置間隔多久才進行一次檢測,檢測需要關(guān)閉的空閑連接塌碌,單位是毫秒
spring.druid.minEvictableIdleTimeMillis配置一個連接在池中最小生存的時間渊胸,單位是毫秒
spring.druid.validationQuery測試連接
spring.druid.testWhileIdle申請連接的時候檢測,建議配置為true台妆,不影響性能翎猛,并且保證安全性
spring.druid.testOnBorrow獲取連接時執(zhí)行檢測,建議關(guān)閉接剩,影響性能
spring.druid.testOnReturn歸還連接時執(zhí)行檢測切厘,建議關(guān)閉,影響性能
spring.druid.poolPreparedStatements是否開啟PSCache懊缺,PSCache對支持游標的數(shù)據(jù)庫性能提升巨大疫稿,oracle建議開啟,mysql下建議關(guān)閉
spring.druid.maxPoolPreparedStatementPerConnectionSize開啟poolPreparedStatements后生效
spring.druid.filters配置擴展插件鹃两,常用的插件有=>stat:監(jiān)控統(tǒng)計 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 輸出日志事件的發(fā)生位置,即輸出日志信息的語句處于它所在的類的第幾行 # %m 輸出代碼中指定的信息馋记,如log(message)中的message
# %n 輸出一個回車換行符号坡,Windows平臺為“rn”,Unix平臺為“n” # %p 輸出優(yōu)先級梯醒,即ERROR宽堆,INFO,WARN茸习,ERROR畜隶,F(xiàn)ATAL。如果是調(diào)用debug()輸出的号胚,則為ERROR代箭,依此類推 # %r 輸出自應用啟動到輸出該日志信息所耗費的毫秒數(shù) # %t 輸出產(chǎn)生該日志事件的線程名</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數(shù)據(jù)源--> <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}" /> <!-- 配置間隔多久才進行一次檢測,檢測需要關(guān)閉的空閑連接乙帮,單位是毫秒 --> <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結(jié)尾的請求--> <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>