理解數(shù)據(jù)庫連接池-結(jié)合SpringMVC + MySQL + druid實例

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>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末晨缴,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子峡捡,更是在濱河造成了極大的恐慌击碗,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件们拙,死亡現(xiàn)場離奇詭異稍途,居然都是意外死亡,警方通過查閱死者的電腦和手機砚婆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門械拍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人装盯,你說我怎么就攤上這事坷虑。” “怎么了埂奈?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵迄损,是天一觀的道長。 經(jīng)常有香客問我挥转,道長海蔽,這世上最難降的妖魔是什么鸵熟? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任狂塘,我火速辦了婚禮,結(jié)果婚禮上点把,老公的妹妹穿的比我還像新娘借宵。我一直安慰自己幌衣,他們只是感情好,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布壤玫。 她就那樣靜靜地躺著豁护,像睡著了一般。 火紅的嫁衣襯著肌膚如雪欲间。 梳的紋絲不亂的頭發(fā)上楚里,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機與錄音猎贴,去河邊找鬼班缎。 笑死蝴光,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的达址。 我是一名探鬼主播蔑祟,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼沉唠!你這毒婦竟也來了疆虚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤满葛,失蹤者是張志新(化名)和其女友劉穎径簿,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體纱扭,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡牍帚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了乳蛾。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片暗赶。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖肃叶,靈堂內(nèi)的尸體忽然破棺而出蹂随,到底是詐尸還是另有隱情,我是刑警寧澤因惭,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布岳锁,位于F島的核電站,受9級特大地震影響蹦魔,放射性物質(zhì)發(fā)生泄漏激率。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一勿决、第九天 我趴在偏房一處隱蔽的房頂上張望乒躺。 院中可真熱鬧,春花似錦低缩、人聲如沸嘉冒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽讳推。三九已至,卻和暖如春玩般,著一層夾襖步出監(jiān)牢的瞬間银觅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工坏为, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留究驴,地道東北人慨仿。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像纳胧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子帘撰,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容