Druid 介绍
Druid 是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池、插件框架和 SQL 解析器组成。该项目主要是为了扩展 JDBC 的一些限制,可以让程序员实现一些特殊的需求,比如向密钥服务请求凭证、统计 SQL 信息、SQL 性能收集、SQL 注入检查、SQL 翻译等,程序员可以通过定制来实现自己需要的功能。
Druid 首先是一个数据库连接池,但它不仅仅是一个数据库连接池,它还包含一个 ProxyDriver,一系列内置的 JDBC 组件库,一个 SQL Parser。在 Javad 的世界中 Druid 是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括 DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。
Druid 可以做什么
Spring Boot 集成 Druid
Druid Spring Boot Starter
非常令人高兴的是,阿里为 Druid 也提供了 Spring Boot Starter 的支持。官网这样解释:Druid Spring Boot Starter 用于帮助在 Spring Boot 项目中轻松集成 Druid 数据库连接池和监控。
Druid Spring Boot Starter 主要做了哪些事情呢?其实这个组件包很简单,主要是提供了很多自动化的配置,按照 Spring Boot 的理念对很多的内容进行了预配置,让我们在使用的时候更加的简单和方便。
注:第一部分为代码,第二部分为增删改查操作的截图,完整代码可在github下载。
github地址:https://github.com/zjh746140129/Spring-Boot2.0
项目结构截图:
1、编写成绩类、学生类、分页类
package com.boot.model;
import java.io.Serializable;
/**
* @Description: 成绩类
* @Author: zhoujh
* @CreateDate: 2018/6/20$ 下午9:27$
* @Version: 1.0
*/
public class Score implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private Long sid;
private Double chineseScore;
private Double mathScore;
private Double englishScore;
public Score() {
}
public Score(String id, Long sid, Double chineseScore, Double mathScore, Double englishScore) {
this.id = id;
this.sid = sid;
this.chineseScore = chineseScore;
this.mathScore = mathScore;
this.englishScore = englishScore;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Long getSid() {
return sid;
}
public void setSid(Long sid) {
this.sid = sid;
}
public Double getChineseScore() {
return chineseScore;
}
public void setChineseScore(Double chineseScore) {
this.chineseScore = chineseScore;
}
public Double getMathScore() {
return mathScore;
}
public void setMathScore(Double mathScore) {
this.mathScore = mathScore;
}
public Double getEnglishScore() {
return englishScore;
}
public void setEnglishScore(Double englishScore) {
this.englishScore = englishScore;
}
}
package com.boot.model;
import java.io.Serializable;
import java.util.List;
/**
* @Description: 学生类
* @Author: zhoujh
* @CreateDate: 2018/6/20$ 下午9:27$
* @Version: 1.0
*/
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String name;
private Integer age;
private String email;
private String address;
private List scoreList;
public Student() {
}
public Student(Long id, String name, Integer age, String email, String address) {
this.id = id;
this.name = name;
this.age = age;
this.email = email;
this.address = address;
}
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 Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List getScoreList() {
return scoreList;
}
public void setScoreList(List scoreList) {
this.scoreList = scoreList;
}
}
package com.boot.model;
import com.boot.common.PageParam;
import org.apache.commons.lang3.builder.ToStringBuilder;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* @Description: 分页封装数据
* @Author: zhoujh
* @CreateDate: 2018/6/20$ 下午10:11$
* @Version: 1.0
*/
public class Page implements Serializable {
private static final long serialVersionUID = -2020350783443768083L;
private int currentPage = 1; //当前页数
private long totalPage; //总页数
private long totalNumber; //总记录数
private List list; //数据集
public static Page NULL = new Page(0, 0, 15, new ArrayList());
public Page() {
super();
}
/**
* @param beginLine 当前页数
* @param totalNumber 总记录数
* @param pageSize 页大小
* @param list 页数据
*/
public Page(int beginLine, long totalNumber, int pageSize, List list) {
super();
this.currentPage = beginLine / pageSize + 1;
this.totalNumber = totalNumber;
this.list = list;
this.totalPage = totalNumber % pageSize == 0 ? totalNumber
/ pageSize : totalNumber / pageSize + 1;
}
public Page(PageParam pageParam, long totalNumber, List list){
super();
this.currentPage = pageParam.getCurrentPage();
this.totalNumber = totalNumber;
this.list = list;
this.totalPage = totalNumber % pageParam.getPageSize() == 0 ? totalNumber
/ pageParam.getPageSize() : totalNumber / pageParam.getPageSize() + 1;
}
public static long getSerialVersionUID() {
return serialVersionUID;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public long getTotalPage() {
return totalPage;
}
public void setTotalPage(long totalPage) {
this.totalPage = totalPage;
}
public long getTotalNumber() {
return totalNumber;
}
public void setTotalNumber(long totalNumber) {
this.totalNumber = totalNumber;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
2、编写mapper.xml
and ${criterion.condition}
and ${criterion.condition} #{criterion.value}
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
and ${criterion.condition}
#{listItem}
and ${criterion.condition}
and ${criterion.condition} #{criterion.value}
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
and ${criterion.condition}
#{listItem}
id, chinese_score, english_score, math_score, sid
delete from score
where id = #{id,jdbcType=VARCHAR}
insert into score (id, chinese_score, english_score,
math_score, sid)
values (#{id,jdbcType=VARCHAR}, #{chineseScore,jdbcType=DOUBLE}, #{englishScore,jdbcType=DOUBLE},
#{mathScore,jdbcType=DOUBLE}, #{sid,jdbcType=BIGINT})
insert into score
id,
chinese_score,
english_score,
math_score,
sid,
#{id,jdbcType=VARCHAR},
#{chineseScore,jdbcType=DOUBLE},
#{englishScore,jdbcType=DOUBLE},
#{mathScore,jdbcType=DOUBLE},
#{sid,jdbcType=BIGINT},
update score
id = #{record.id,jdbcType=VARCHAR},
chinese_score = #{record.chineseScore,jdbcType=DOUBLE},
english_score = #{record.englishScore,jdbcType=DOUBLE},
math_score = #{record.mathScore,jdbcType=DOUBLE},
sid = #{record.sid,jdbcType=BIGINT},
update score
set id = #{record.id,jdbcType=VARCHAR},
chinese_score = #{record.chineseScore,jdbcType=DOUBLE},
english_score = #{record.englishScore,jdbcType=DOUBLE},
math_score = #{record.mathScore,jdbcType=DOUBLE},
sid = #{record.sid,jdbcType=BIGINT}
update score
chinese_score = #{chineseScore,jdbcType=DOUBLE},
english_score = #{englishScore,jdbcType=DOUBLE},
math_score = #{mathScore,jdbcType=DOUBLE},
sid = #{sid,jdbcType=BIGINT},
where id = #{id,jdbcType=VARCHAR}
update score
set chinese_score = #{chineseScore,jdbcType=DOUBLE},
english_score = #{englishScore,jdbcType=DOUBLE},
math_score = #{mathScore,jdbcType=DOUBLE},
sid = #{sid,jdbcType=BIGINT}
where id = #{id,jdbcType=VARCHAR}
and ${criterion.condition}
and ${criterion.condition} #{criterion.value}
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
and ${criterion.condition}
#{listItem}
and ${criterion.condition}
and ${criterion.condition} #{criterion.value}
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
and ${criterion.condition}
#{listItem}
id, address, age, email, name
delete from student
where id = #{id,jdbcType=BIGINT}
insert into student (id, address, age,
email, name)
values (#{id,jdbcType=BIGINT}, #{address,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER},
#{email,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR})
insert into student
id,
address,
age,
email,
name,
#{id,jdbcType=BIGINT},
#{address,jdbcType=VARCHAR},
#{age,jdbcType=INTEGER},
#{email,jdbcType=VARCHAR},
#{name,jdbcType=VARCHAR},
update student
id = #{record.id,jdbcType=BIGINT},
address = #{record.address,jdbcType=VARCHAR},
age = #{record.age,jdbcType=INTEGER},
email = #{record.email,jdbcType=VARCHAR},
name = #{record.name,jdbcType=VARCHAR},
update student
set id = #{record.id,jdbcType=BIGINT},
address = #{record.address,jdbcType=VARCHAR},
age = #{record.age,jdbcType=INTEGER},
email = #{record.email,jdbcType=VARCHAR},
name = #{record.name,jdbcType=VARCHAR}
update student
address = #{address,jdbcType=VARCHAR},
age = #{age,jdbcType=INTEGER},
email = #{email,jdbcType=VARCHAR},
name = #{name,jdbcType=VARCHAR},
where id = #{id,jdbcType=BIGINT}
update student
set address = #{address,jdbcType=VARCHAR},
age = #{age,jdbcType=INTEGER},
email = #{email,jdbcType=VARCHAR},
name = #{name,jdbcType=VARCHAR}
where id = #{id,jdbcType=BIGINT}
3、编写mapper
package com.boot.mapper.one;
import com.boot.model.Score;
import java.util.List;
/**
* Created by zhoujh on 2018/6/29.
*/
public interface ScoreMapper {
int deleteByPrimaryKey(String id);
int insert(Score record);
int insertSelective(Score record);
Score selectByPrimaryKey(String id);
int updateByPrimaryKeySelective(Score record);
int updateByPrimaryKey(Score record);
List getListScore();
}
package com.boot.mapper;
import com.boot.model.Score;
import java.util.List;
/**
* Created by zhoujh on 2018/6/29.
*/
public interface ScoreMapper {
int deleteByPrimaryKey(String id);
int insert(Score record);
int insertSelective(Score record);
Score selectByPrimaryKey(String id);
int updateByPrimaryKeySelective(Score record);
int updateByPrimaryKey(Score record);
List getListScore();
}
4、编写service
package com.boot.service;
import com.boot.mapper.one.ScoreMapper;
import com.boot.model.Score;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* 学生成绩类service
* Created by zhoujh on 2018/6/25.
*/
@Service
public class ScoreService {
@Resource
private ScoreMapper scoreMapper;
public List findStudentScore(){
return scoreMapper.getListScore();
}
public Score findByKeyScore(String id){
return scoreMapper.selectByPrimaryKey(id);
}
}
package com.boot.service;
import com.boot.mapper.two.StudentMapper;
import com.boot.model.Student;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* 学生类service
* Created by zhoujh on 2018/6/25.
*/
@Service
public class StudentService {
@Resource
private StudentMapper studentMapper;
/**
* 新增学生
* @param student
* @return
*/
public int addStudent(Student student){
return this.studentMapper.insert(student);
}
/**
* 删除学生
* @param id
* @return
*/
public int deleteStudent(Long id){
return this.studentMapper.deleteByPrimaryKey(id);
}
/**
* 修改学生信息
* @param student
* @return
*/
public int updateStudent(Student student){
return this.studentMapper.updateByPrimaryKey(student);
}
/**
* 查询学生信息
* @param id
* @return
*/
public Student selectStudentById(Long id){
return this.studentMapper.selectByPrimaryKey(id);
}
/**
* 查询所有学生(分页)
* @return
*/
public PageInfo selectAllStudent(int pageNum, int pageSize){
PageHelper.startPage(pageNum, pageSize);
List studentList = this.studentMapper.getList();
PageInfo result = new PageInfo(studentList);
return result;
}
/**
* 查询所有学生成绩(分页)
* @return
*/
public PageInfo findAllStudentScore(int pageNum, int pageSize){
PageHelper.startPage(pageNum, pageSize);
List studentList = this.studentMapper.selectStudentScore();
PageInfo result = new PageInfo(studentList);
return result;
}
/**
* 查询所有学生总数(用于分页)
* @return
*/
public int selectStudentCount(){
return this.studentMapper.getCount();
}
/**
* 查询所有学生
* @return
*/
public List findAllStudent(){
return this.studentMapper.getList();
}
}
5、分页工具类
package com.boot.common;
import org.apache.commons.lang3.builder.ToStringBuilder;
/**
* @Description: 分页工具类
* @Author: zhoujh
* @CreateDate: 2018/6/20$ 下午10:15$
* @Version: 1.0
*/
public class PageParam {
private int beginLine; //起始行
private Integer pageSize = 3;
private Integer currentPage=0; // 当前页
public int getBeginLine() {
return pageSize*currentPage;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getCurrentPage() {
return currentPage;
}
public void setCurrentPage(Integer currentPage) {
this.currentPage = currentPage;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
6、 编写controller
package com.boot.controller;
import com.boot.model.Score;
import com.boot.model.Student;
import com.boot.service.ScoreService;
import com.boot.service.StudentService;
import com.google.gson.Gson;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* 学生controller
* Created by zhoujh on 2018/6/25.
*/
@RestController
public class StudentController {
@Resource
private StudentService studentService;
@Resource
private ScoreService scoreService;
/**
* 新增学生
* @param student
* @return
*/
@RequestMapping("/add")
public int saveStudent(Student student){
return this.studentService.addStudent(student);
}
/**
* 删除学生
* @param id
* @return
*/
@RequestMapping("/delete")
public int deleteStudent(Long id){
return this.studentService.deleteStudent(id);
}
/**
* 修改学生信息
* @param student
* @return
*/
@RequestMapping("/update")
public int updateStudent(Student student){
return this.studentService.updateStudent(student);
}
/**
* 查询学生信息
* @param id
* @return
*/
@RequestMapping("/select")
public Student findStudentById(Long id){
return this.studentService.selectStudentById(id);
}
@ResponseBody
@RequestMapping("/getList")
public Object findAllStudent(
@RequestParam(name = "pageNum", required = false, defaultValue = "1")
int pageNum,
@RequestParam(name = "pageSize", required = false, defaultValue = "10")
int pageSize){
return studentService.selectAllStudent(pageNum,pageSize);
}
@ResponseBody
@RequestMapping("/getAllStudentScore")
public Object findAllStudentScore(
@RequestParam(name = "pageNum", required = false, defaultValue = "1")
int pageNum,
@RequestParam(name = "pageSize", required = false, defaultValue = "10")
int pageSize){
return studentService.findAllStudentScore(pageNum,pageSize);
}
/**
* 测试多数据获取数据
* @return
*/
@ResponseBody
@RequestMapping("/multiDataSourceQueryDB")
public String multiDataSourceFindDB(){
Score score = this.scoreService.findByKeyScore("1");
System.out.println("成绩"+score.getChineseScore());
String rs = "";
List studentList = this.studentService.findAllStudent();
List scoreList = this.scoreService.findStudentScore();
Gson gson = new Gson();
String stuStr = gson.toJson(studentList).toString();
String scoreStr = gson.toJson(scoreList).toString();
rs += "学生数据库:"+stuStr+"\n"+"成绩库数据"+scoreStr;
return rs;
}
// @RequestMapping("/getList")
// public Page getList(HttpServletRequest request) {
// Map map = new HashMap<>();
// map.put("beginLine","0");
// map.put("pageSize","2");
// List users = studentService.selectAllStudent(map);
// long count = this.studentService.selectStudentCount();
// Page page = new Page(0,count,1,users);
// return page;
// }
}
7、多数据源配置类
package com.boot.config;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
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 javax.sql.DataSource;
/**
* 多数据源配置读取
* Created by zhoujh on 2018/6/29.
*/
@Configuration
public class MultiDataSourceConfig {
@Primary
@Bean(name = "oneDataSource")
@ConfigurationProperties("spring.datasource.druid.one")
public DataSource dataSourceOne(){
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "twoDataSource")
@ConfigurationProperties("spring.datasource.druid.two")
public DataSource dataSourceTwo(){
return DruidDataSourceBuilder.create().build();
}
}
package com.boot.config;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
/**
* 获取第一个数据源配置
* Created by zhoujh on 2018/6/29.
*/
@Configuration
@MapperScan(basePackages = "com.boot.mapper.one", sqlSessionTemplateRef = "oneSqlSessionTemplate")
public class OneDataSourceConfig {
@Bean(name = "oneSqlSessionFactory")
@Primary
public SqlSessionFactory oneSqlSessionFactory(@Qualifier("oneDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mybatis/*.xml"));
return bean.getObject();
}
@Bean(name = "oneTransactionManager")
@Primary
public DataSourceTransactionManager oneTransactionManager(@Qualifier("oneDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "oneSqlSessionTemplate")
@Primary
public SqlSessionTemplate oneSqlSessionTemplate(@Qualifier("oneSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
package com.boot.config;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
/**
* 获取第二个数据源配置
* Created by zhoujh on 2018/6/29.
*/
@Configuration
@MapperScan(basePackages = "com.boot.mapper.two", sqlSessionTemplateRef = "twoSqlSessionTemplate")
public class TwoSourceConfig {
@Bean(name = "twoSqlSessionFactory")
public SqlSessionFactory twoSqlSessionFactory(@Qualifier("twoDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mybatis/*.xml"));
return bean.getObject();
}
@Bean(name = "twoTransactionManager")
public DataSourceTransactionManager twoTransactionManager(@Qualifier("twoDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "twoSqlSessionTemplate")
public SqlSessionTemplate twoSqlSessionTemplate(@Qualifier("twoSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
8、启动类
package com.boot;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
public class BootDruidMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(BootDruidMybatisApplication.class, args);
}
}
9、配置文件
mybatis.type-aliases-package=com.boot.model
server.port=8099
spring.datasource.druid.one.driverClassName = com.mysql.jdbc.Driver
spring.datasource.druid.one.url = jdbc:mysql://localhost:3306/school_score?useUnicode=true&characterEncoding=utf-8
spring.datasource.druid.one.username = root
spring.datasource.druid.one.password = root
spring.datasource.druid.two.driverClassName = com.mysql.jdbc.Driver
spring.datasource.druid.two.url = jdbc:mysql://localhost:3306/school_student?useUnicode=true&characterEncoding=utf-8
spring.datasource.druid.two.username = root
spring.datasource.druid.two.password = root
#pagehelper
pagehelper.helper-dialect=mysql
pagehelper.reasonable=true
pagehelper.support-methods-arguments=true
pagehelper.params=count=countSql
pagehelper.returnPageInfo = check
# 初始化大小,最小,最大链接数
spring.datasource.druid.initial-size=3
spring.datasource.druid.min-idle=3
spring.datasource.druid.max-active=10
# 配置获取连接等待超时的时间
spring.datasource.druid.max-wait=60000
# 监控后台的账户和密码
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=admin
# 配置StatFilter
spring.datasource.druid.filter.stat.log-slow-sql=true
spring.datasource.druid.filter.stat.slow-sql-millis=2000
10、完整pom.xml
4.0.0
com.boot
boot-druid-mybatis
0.0.1-SNAPSHOT
jar
boot-druid-mybatis
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
2.0.3.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-web
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.2
org.apache.commons
commons-lang3
3.6
mysql
mysql-connector-java
runtime
com.github.pagehelper
pagehelper-spring-boot-starter
1.2.5
com.alibaba
druid-spring-boot-starter
1.1.10
org.springframework.boot
spring-boot-starter-test
test
com.google.code.gson
gson
2.8.0
org.springframework.boot
spring-boot-maven-plugin
1、查询(查询2个库,使用postman测试)
http://localhost:8099/multiDataSourceQueryDB