《SpringBoot2从入门到工程实战》第七篇:集成Druid连接池

我们都知道,java的高性能,根本原因其实不是因为Java的jvm或者静态编译,而是因为Java的长链接,而长链接的性能的提升,主要是依赖连接池,所以针对MySQL这种数据库,在实际使用时,使用自动管理的MySQL连接池就可以大幅提升业务代码的响应速度,本章我们主要介绍针对MySQL的连接池Druid连接池的使用。

本章示例工程名称:springboot_worker_druid

代码地址:https://github.com/stamhe/SpringBoot-Work-Example

目录结构如下:



示例MySQL建表语句:

create database article_201908;
use article_201908;

CREATE TABLE `t_article_201908_007` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL DEFAULT '',
  `summary` varchar(1024) NOT NULL DEFAULT '',
  `status` int(11) NOT NULL DEFAULT '0',
  `type` int(11) NOT NULL,
  `user_id` bigint(20) NOT NULL DEFAULT '0',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `public_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;


create database user_201908;
use user_201908;

CREATE TABLE `users_201908_007` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(70) NOT NULL,
  `email` varchar(70) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

pom.xml内容:

<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.stamhe</groupId>
  <artifactId>springboot_worker_druid</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>springboot_worker_druid</name>
  <url>http://maven.apache.org</url>


	<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>
  
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    
      <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        
	    <dependency>  
	        <groupId>org.springframework.boot</groupId>  
	        <artifactId>spring-boot-starter-jdbc</artifactId>  
	    </dependency>  
	    
	    <dependency>  
	        <groupId>mysql</groupId>  
	        <artifactId>mysql-connector-java</artifactId>  
	        <version>8.0.15</version>
	    </dependency> 
	    
	    <dependency>
		    <groupId>com.alibaba</groupId>
		    <artifactId>druid-spring-boot-starter</artifactId>
		    <version>1.1.13</version>
	    </dependency>
	    
	    <dependency>
	      <groupId>org.mybatis.spring.boot</groupId>
	      <artifactId>mybatis-spring-boot-starter</artifactId>
	      <version>1.3.3</version>
	    </dependency>
    
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <scope>test</scope>
        </dependency>
    </dependencies>
    <!-- 
    使用Spring Boot微服务搭建框架,在eclipse和Idea下能正常运行,但是在打成jar包部署或者直接使用java -jar命令的时候,
    提示了xxxxxx.jar中没有主清单属性.
    添加 spring-boot-maven-plugin然后再执行mvn install 或者 mvn clean package 即可解决.
    -->
    <build>
      <plugins>
          <plugin>
              <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
      </plugins>
     </build>
</project>

App.java的内容:

package com.stamhe.springboot;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;

/*
首先要将SpringBoot自带的DataSourceAutoConfiguration禁掉,因为它会读取application.properties文件的spring.datasource.*属性并自动配置单数据源。
在@SpringBootApplication注解中添加exclude属性即可
*/
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@ComponentScan({"com.stamhe.springboot"})
@MapperScan("com.stamhe.springboot.mapper")
public class App 
{
    public static void main( String[] args )
    {
    	SpringApplication.run(App.class, args);
    }
}

UserModel.java的内容:

package com.stamhe.springboot.model;


/*

create database user_201908;
use user_201908;

CREATE TABLE `users_201908_007` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(70) NOT NULL,
  `email` varchar(70) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

 */
public class UserModel {
	private Long id;
    private String name;
    private String email;
    
    
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	
	@Override
	public String toString() {
		return "UserModel [id=" + id + ", name=" + name + ", email=" + email + "]";
	}
}

ArticleModel.java的内容:

package com.stamhe.springboot.model;

import java.util.Date;

/*
create database article_201908;
use article_201908;

CREATE TABLE `t_article_201908_007` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL DEFAULT '',
  `summary` varchar(1024) NOT NULL DEFAULT '',
  `status` int(11) NOT NULL DEFAULT '0',
  `type` int(11) NOT NULL,
  `user_id` bigint(20) NOT NULL DEFAULT '0',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `public_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
 */
public class ArticleModel {
	private Long id;
    private String title;
    private String summary;
    private Integer status;
    private Integer type;
    private Long userId;
    
    private Date createTime;
    private Date publicTime;
    private Date updateTime;
    
    
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getSummary() {
		return summary;
	}
	public void setSummary(String summary) {
		this.summary = summary;
	}
	public Integer getStatus() {
		return status;
	}
	public void setStatus(Integer status) {
		this.status = status;
	}
	public Integer getType() {
		return type;
	}
	public void setType(Integer type) {
		this.type = type;
	}
	public Long getUserId() {
		return userId;
	}
	public void setUserId(Long userId) {
		this.userId = userId;
	}
	public Date getCreateTime() {
		return createTime;
	}
	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}
	public Date getPublicTime() {
		return publicTime;
	}
	public void setPublicTime(Date publicTime) {
		this.publicTime = publicTime;
	}
	public Date getUpdateTime() {
		return updateTime;
	}
	public void setUpdateTime(Date updateTime) {
		this.updateTime = updateTime;
	}
	
	@Override
	public String toString() {
		return "ArticleModel [id=" + id + ", title=" + title + ", summary=" + summary + ", status=" + status + ", type="
				+ type + ", userId=" + userId + ", createTime=" + createTime + ", publicTime=" + publicTime
				+ ", updateTime=" + updateTime + "]";
	}
}

UserMapper.java内容:

package com.stamhe.springboot.mapper.user;

import java.util.List;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectKey;
import org.springframework.context.annotation.Configuration;

import com.stamhe.springboot.model.UserModel;


@Configuration
public interface UserMapper 
{
	@Select("select * from users_201908_007 where id=#{id}")
	@Results({
		@Result(property="id", column="id"),
		@Result(property="name", column="name"),
		@Result(property="email", column="email"),
	})
	public UserModel getOne(Long id);
	

	@Select("select * from users_201908_007")
	@Results({
		@Result(property="id", column="id"),
		@Result(property="name", column="name"),
		@Result(property="email", column="email"),
	})
	public List<UserModel> getAll();
	

	// userModel.getId()
	@Insert("insert into users_201908_007 (name, email) "
			+ "values (#{name}, #{email})")
	@SelectKey(statement="select LAST_INSERT_ID()", keyProperty="id", before=false, resultType=long.class)
	public void insert(UserModel userModel);	
}

ArticleMapper.java内容:

package com.stamhe.springboot.mapper.article;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectKey;
import org.apache.ibatis.annotations.Update;
import org.springframework.context.annotation.Configuration;

import com.stamhe.springboot.model.ArticleModel;

@Configuration
public interface ArticleMapper 
{
	@Select("select * from t_article_201908_007 where id=#{id}")
	@Results({
		@Result(property="userId", column="user_id"),
		@Result(property="createTime", column="create_time"),
		@Result(property="updateTime", column="update_time"),
		@Result(property="publicTime", column="public_time"),
	})
	public ArticleModel getOne(Long id);
	

	@Select("select * from t_article_201908_007")
	@Results({
		@Result(property="userId", column="user_id"),
		@Result(property="createTime", column="create_time"),
		@Result(property="updateTime", column="update_time"),
		@Result(property="publicTime", column="public_time"),
	})
	public List<ArticleModel> getAll();
	
	// articleModel.getId()
	@Insert("insert into t_article_201908_007 (title, summary, status, type, user_id, create_time, update_time, public_time) "
			+ "values (#{title}, #{summary}, #{status}, #{type}, #{userId}, #{createTime}, #{updateTime}, #{publicTime})")
	@SelectKey(statement="select LAST_INSERT_ID()", keyProperty="id", before=false, resultType=long.class)
	public void insert(ArticleModel articleModel);
	
	// 返回受影响的行数
	@Update("update t_article_201908_007 set summary=#{summary} where id=#{id}")
	public Integer update(ArticleModel articleModel);
	
	// 返回受影响的行数
	@Delete("delete from t_article_201908_007 where id=#{id}")
	public Integer delete(@Param("id")Long id);
}

UserDSConfig.java内容:

package com.stamhe.springboot.dsconfig;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;

/*
 * 由于我们在SpringBootApplication中禁掉了自动数据源配置,需要在这儿手动创建 application.properteis 中的数据源
 */
@Configuration
@MapperScan(basePackages = {"com.stamhe.springboot.mapper.user"}, sqlSessionFactoryRef = "sqlSessionFactoryObj01")
public class UserDSConfig {
    @Bean(name = "ds_db01")
    @Primary
    @ConfigurationProperties(prefix="spring.datasource.user")
    public DataSource DB01DataSource() {
    	DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
    	return setDataSource(dataSource);
    }

    @Bean(name="sqlSessionFactoryObj01")
    @Primary
    public SqlSessionFactory sqlSessionFactory1(@Qualifier("ds_db01") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);

        return factoryBean.getObject();
    }

    @Bean(name="sqlSessionTemplateObj01")
    public SqlSessionTemplate sqlSessionTemplate1(@Qualifier("sqlSessionFactoryObj01") SqlSessionFactory sqlSessionFactory) throws Exception {
        SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory); // 使用上面配置的Factory
        return template;
    }
    
    /**
     * 设置Druid参数
     * @param dataSource
     * @return
     * @throws SQLException 
     */
    public DruidDataSource setDataSource(DruidDataSource druidDataSource)
    {
        // 初始化大小,最小,最大
        druidDataSource.setMaxActive(10);
        druidDataSource.setInitialSize(3);
        druidDataSource.setMinIdle(3);
        
        // 配置获取连接等待超时的时间 单位: ms
        druidDataSource.setMaxWait(100);
        
        // 打开后,增强timeBetweenEvictionRunsMillis的周期性连接检查,minIdle内的空闲连接,每次检查强制验证连接有效性. 参考:https://github.com/alibaba/druid/wiki/KeepAlive_cn
        druidDataSource.setKeepAlive(true);
        // 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位: ms
        druidDataSource.setTimeBetweenEvictionRunsMillis(30000);
        // 配置一个连接在池中最小生存的时间,单位: ms
        druidDataSource.setMinEvictableIdleTimeMillis(300000);

        // 配置一个连接在池中最小生存的时间,单位: ms
        druidDataSource.setMinEvictableIdleTimeMillis(300000);
        
        // 用来检测连接是否有效的sql,要求是一个查询语句。 如果validationQuery为null,testOnBorrow、testOnReturn、 testWhileIdle都不会其作用。
        druidDataSource.setValidationQuery("select 'x'");
        
        // 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于 timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
        druidDataSource.setTestWhileIdle(true);
        // 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
        druidDataSource.setTestOnBorrow(false);
        // 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
        druidDataSource.setTestOnReturn(false);
        
        /* 打开PSCache,并且指定每个连接上PSCache的大小。
        如果用Oracle,则把poolPreparedStatements配置为true,
        mysql可以配置为false。分库分表较多的数据库,建议配置为false */
        druidDataSource.setPoolPreparedStatements(false);
        // 指定每个连接上PSCache的大小
        druidDataSource.setMaxOpenPreparedStatements(20);
        // 合并多个DruidDataSource的监控数据
        //druidDataSource.setUseGlobalDataSourceStat(true);
        
        // 自动提交设置为 true
        druidDataSource.setDefaultAutoCommit(true);
        
        /*
         * 连接泄露检查,打开removeAbandoned功能 , 连接从连接池借出后,长时间不归还,将触发强制回连接。回收周期随timeBetweenEvictionRunsMillis进行.
         * 如果连接为从连接池借出状态,并且未执行任何sql,并且从借出时间起已超过removeAbandonedTimeout时间,则强制归还连接到连接池中。
         */
        druidDataSource.setRemoveAbandoned(true);
        // 单位: s
        druidDataSource.setRemoveAbandonedTimeout(5);
        // 关闭abanded连接时输出错误日志,这样出现连接泄露时可以通过错误日志定位忘记关闭连接的位置
        druidDataSource.setLogAbandoned(true);
        
        //配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
        /*
        属性类型是字符串,通过别名的方式配置扩展插件, 
		常用的插件有: 
		监控统计用的filter:stat  
		日志用的filter:log4j 
		防御sql注入的filter:wall
         */
        try {
        	druidDataSource.setFilters("stat,wall,slf4j");
        }catch(Exception e) {
        	e.printStackTrace();
        }
        // 配置监控统计日志的输出间隔,每次输出所有统计数据会重置,酌情开启. 单位: ms
        druidDataSource.setTimeBetweenLogStatsMillis(10000);
            
    	return druidDataSource;
    }
}

ArticleDSConfig.java内容:

package com.stamhe.springboot.dsconfig;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;

/*
 * 由于我们在SpringBootApplication中禁掉了自动数据源配置,需要在这儿手动创建 application.properteis 中的数据源
 */
@Configuration
@MapperScan(basePackages = {"com.stamhe.springboot.mapper.article"}, sqlSessionFactoryRef = "sqlSessionFactoryObj02")
public class ArticleDSConfig {
    @Bean(name="ds_db02")
    @ConfigurationProperties(prefix="spring.datasource.article")
    public DataSource DB02DataSource() {
    	DruidDataSource dataSource =  DruidDataSourceBuilder.create().build();
    	return setDataSource(dataSource);
    }

    @Bean(name="sqlSessionFactoryObj02")
    @Primary
    public SqlSessionFactory sqlSessionFactory1(@Qualifier("ds_db02") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);

        return factoryBean.getObject();
    }

    @Bean(name="sqlSessionTemplateObj02")
    public SqlSessionTemplate sqlSessionTemplate1(@Qualifier("sqlSessionFactoryObj02") SqlSessionFactory sqlSessionFactory) throws Exception {
        SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory); // 使用上面配置的Factory
        return template;
    }
    
    /**
     * 设置Druid参数
     * @param dataSource
     * @return
     * @throws SQLException 
     */
    public DruidDataSource setDataSource(DruidDataSource druidDataSource)
    {
        // 初始化大小,最小,最大
        druidDataSource.setMaxActive(10);
        druidDataSource.setInitialSize(3);
        druidDataSource.setMinIdle(3);
        
        // 配置获取连接等待超时的时间 单位: ms
        druidDataSource.setMaxWait(100);
        
        // 打开后,增强timeBetweenEvictionRunsMillis的周期性连接检查,minIdle内的空闲连接,每次检查强制验证连接有效性. 参考:https://github.com/alibaba/druid/wiki/KeepAlive_cn
        druidDataSource.setKeepAlive(true);
        // 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位: ms
        druidDataSource.setTimeBetweenEvictionRunsMillis(30000);
        // 配置一个连接在池中最小生存的时间,单位: ms
        druidDataSource.setMinEvictableIdleTimeMillis(300000);

        // 配置一个连接在池中最小生存的时间,单位: ms
        druidDataSource.setMinEvictableIdleTimeMillis(300000);
        
        // 用来检测连接是否有效的sql,要求是一个查询语句。 如果validationQuery为null,testOnBorrow、testOnReturn、 testWhileIdle都不会其作用。
        druidDataSource.setValidationQuery("select 'x'");
        
        // 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于 timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
        druidDataSource.setTestWhileIdle(true);
        // 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
        druidDataSource.setTestOnBorrow(false);
        // 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
        druidDataSource.setTestOnReturn(false);
        
        /* 打开PSCache,并且指定每个连接上PSCache的大小。
        如果用Oracle,则把poolPreparedStatements配置为true,
        mysql可以配置为false。分库分表较多的数据库,建议配置为false */
        druidDataSource.setPoolPreparedStatements(false);
        // 指定每个连接上PSCache的大小
        druidDataSource.setMaxOpenPreparedStatements(20);
        // 合并多个DruidDataSource的监控数据
        //druidDataSource.setUseGlobalDataSourceStat(true);
        
        // 自动提交设置为 true
        druidDataSource.setDefaultAutoCommit(true);
        
        /*
         * 连接泄露检查,打开removeAbandoned功能 , 连接从连接池借出后,长时间不归还,将触发强制回连接。回收周期随timeBetweenEvictionRunsMillis进行.
         * 如果连接为从连接池借出状态,并且未执行任何sql,并且从借出时间起已超过removeAbandonedTimeout时间,则强制归还连接到连接池中。
         */
        druidDataSource.setRemoveAbandoned(true);
        // 单位: s
        druidDataSource.setRemoveAbandonedTimeout(5);
        // 关闭abanded连接时输出错误日志,这样出现连接泄露时可以通过错误日志定位忘记关闭连接的位置
        druidDataSource.setLogAbandoned(true);
        
        //配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
        /*
        属性类型是字符串,通过别名的方式配置扩展插件, 
		常用的插件有: 
		监控统计用的filter:stat  
		日志用的filter:log4j 
		防御sql注入的filter:wall
         */
        try {
        	druidDataSource.setFilters("stat,wall,slf4j");
        }catch(Exception e) {
        	e.printStackTrace();
        }
        // 配置监控统计日志的输出间隔,每次输出所有统计数据会重置,酌情开启. 单位: ms
        druidDataSource.setTimeBetweenLogStatsMillis(10000);
            
    	return druidDataSource;
    }
}

UserController.java内容:

package com.stamhe.springboot.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.stamhe.springboot.mapper.user.UserMapper;
import com.stamhe.springboot.model.UserModel;

@RestController
@RequestMapping("/user")
public class UserController {

	@Autowired
	private UserMapper userMapper;
	
	// http://localhost:8080/user/add
	@RequestMapping("/add")
	public Long addAction()
	{
		Long id = 0L;

		UserModel userModel = new UserModel();
		userModel.setName("user-测试-201908-006");
		userModel.setEmail("stamhe-201908-006@gmail.com");
		
		userMapper.insert(userModel);
		
		id = userModel.getId();
		
		return id;
	}
	
	// http://localhost:8080/user/detail/1
	@RequestMapping(value="/detail/{id}")
	public UserModel detailAction(@PathVariable("id")Long id)
	{
		UserModel userModel = userMapper.getOne(id);
		return userModel;
	}
}

ArticleController.java内容:

package com.stamhe.springboot.controller;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.stamhe.springboot.mapper.article.ArticleMapper;
import com.stamhe.springboot.model.ArticleModel;

@RestController
@RequestMapping("/article")
public class ArticleController {

	@Autowired
	private ArticleMapper articleMapper;
	
	// http://localhost:8080/article/add
	@RequestMapping("/add")
	public Long addAction()
	{
		Long id = 0L;

		ArticleModel articleModel = new ArticleModel();

		articleModel.setTitle("article-测试-201908-002");
		articleModel.setSummary("article-测试-201908-002");
		articleModel.setStatus(1);
		articleModel.setType(1);
		articleModel.setUserId(1L);
		articleModel.setCreateTime(new Date());
		articleModel.setUpdateTime(new Date());
		articleModel.setPublicTime(new Date());
        articleMapper.insert(articleModel);
        id = articleModel.getId();
        
		return id;
	}
	
	// http://localhost:8080/article/detail/1
	@RequestMapping(value="/detail/{id}")
	public ArticleModel detailAction(@PathVariable("id")Long id)
	{
		ArticleModel articleModel = articleMapper.getOne(id);
		return articleModel;
	}
}

application.properties内容:

spring.datasource.user.url = jdbc:mysql://127.0.0.1:3306/user_201908?useUnicode=true&characterEncoding=UTF-8&useSSL=false
spring.datasource.user.driverClassName = com.mysql.cj.jdbc.Driver
spring.datasource.user.username = root
spring.datasource.user.password = 
spring.datasource.user.type = com.alibaba.druid.pool.DruidDataSource


spring.datasource.article.url = jdbc:mysql://localhost:3306/article_201908?useUnicode=true&characterEncoding=UTF-8&useSSL=false
spring.datasource.article.driverClassName = com.mysql.cj.jdbc.Driver
spring.datasource.article.username = root
spring.datasource.article.password = 
spring.datasource.article.type = com.alibaba.druid.pool.DruidDataSource


mybatis.type-aliases-package = com.stamhe.springboot.model

下面为示例实例运行起来后,数据库的连接情况:

可见每个库有3个连接长期存在,原因为我们在DSConfig的setDataSource方法中,有如下代码:

        druidDataSource.setMaxActive(10);
        druidDataSource.setInitialSize(3);
        druidDataSource.setMinIdle(3);

这三个参数,是用来初始化Druid的最大活跃连接数、初始连接数、最小空闲连接数这三个参数的。

《SpringBoot2从入门到工程实战》第七篇:集成Druid连接池》有1个想法

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

code

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据