4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.8.RELEASE
wen
druid
0.0.1-SNAPSHOT
druid
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-web
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.2.0
com.alibaba
druid
1.0.18
mysql
mysql-connector-java
log4j
log4j
1.2.17
org.springframework.boot
spring-boot-maven-plugin
值得一提的是:pom文件有个log4j文件包,这个必须要添加,因为后面的druid配置文件内有个log4j的值,不加上的话会导致配置文件出错而连不上druid
# 主数据源,默认的
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone = GMT
spring.datasource.username=root
spring.datasource.password=
spring.datasource.filters=stat,wall,log4j
# 更多数据源
custom.datasource.names=ds1,ds2
custom.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
custom.datasource.ds1.url=jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone = GMT
custom.datasource.ds1.username=root
custom.datasource.ds1.password=
custom.datasource.ds1.filters=stat,wall,log4j
custom.datasource.ds2.driver-class-name=com.mysql.cj.jdbc.Driver
custom.datasource.ds2.url=jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone = GMT
custom.datasource.ds2.username=root
custom.datasource.ds2.password=
spring.http.encoding.charset=utf-8
# 下面为连接池的补充设置,应用到上面所有数据源中
# 初始化大小,最小,最大
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
# 配置获取连接等待超时的时间
spring.datasource.maxWait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
# 打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
数据库连接的url账户密码根据自己的情况作出修改
数据库设计为一个主表,两个从表,设定为都包含test表
建表语句:
CREATE TABLE `test` (
`id` int(11) unsigned zerofill NOT NULL AUTO_INCREMENT,
`name` varchar(36) NOT NULL,
`age` int(2) NOT NULL,
`gender` varchar(2) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
entity包内的MasterUser.java 和 CustomUser.java:
package wen.druid.entity;
public class MasterUser {
private Integer id;
private String name;
private Integer age;
private String gender;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name == null ? null : name.trim();
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender == null ? null : gender.trim();
}
}
package wen.druid.entity;
public class CustomUser {
private Integer id;
private String name;
private Integer age;
private String gender;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name == null ? null : name.trim();
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender == null ? null : gender.trim();
}
}
MasterUserMapper.xml
id, name,age,gender
insert into test (id, name, age, gender)
values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},
#{age,jdbcType=INTEGER}, #{gender,jdbcType=VARCHAR})
insert into test
id,
name,
age,
gender,
#{id,jdbcType=INTEGER},
#{name,jdbcType=VARCHAR},
#{age,jdbcType=INTEGER},
#{gender,jdbcType=VARCHAR},
delete from test
where id = #{id,jdbcType=INTEGER}
update test
name = #{name,jdbcType=VARCHAR},
age = #{age,jdbcType=INTEGER},
gender = #{gender,jdbcType=VARCHAR},
where id = #{id,jdbcType=INTEGER}
update test
set name = #{name,jdbcType=VARCHAR},
age = #{age,jdbcType=INTEGER},
gender = #{gender,jdbcType=VARCHAR}
where id = #{id,jdbcType=INTEGER}
CustomUserMapper.xml
id, name,age,gender
insert into test
(id, name, age, gender)
values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},
#{age,jdbcType=INTEGER}, #{gender,jdbcType=VARCHAR})
insert into test
id,
name,
age,
gender,
#{id,jdbcType=INTEGER},
#{name,jdbcType=VARCHAR},
#{age,jdbcType=INTEGER},
#{gender,jdbcType=VARCHAR},
delete from test
where id = #{id,jdbcType=INTEGER}
update test
name = #{name,jdbcType=VARCHAR},
age = #{age,jdbcType=INTEGER},
gender = #{gender,jdbcType=VARCHAR},
where id = #{id,jdbcType=INTEGER}
update test
set name = #{name,jdbcType=VARCHAR},
age = #{age,jdbcType=INTEGER},
gender = #{gender,jdbcType=VARCHAR}
where id = #{id,jdbcType=INTEGER}
package wen.druid.mapper;
import wen.druid.entity.CustomUser;
public interface CustomUserMapper {
int deleteByPrimaryKey(Integer id);
int insert(CustomUser customUser);
int insertSelective(CustomUser customUser);
CustomUser selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(CustomUser customUser);
int updateByPrimaryKey(CustomUser customUser);
}
package wen.druid.mapper;
import wen.druid.entity.MasterUser;
public interface MasterUserMapper {
int deleteByPrimaryKey(Integer id);
int insert(MasterUser masterUser);
int insertSelective(MasterUser masterUser);
MasterUser selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(MasterUser masterUser);
int updateByPrimaryKey(MasterUser masterUser);
}
package wen.druid.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import wen.druid.entity.MasterUser;
import wen.druid.mapper.MasterUserMapper;
@Service
public class MasterUserService {
@Autowired
private MasterUserMapper masterUserMapper;
public MasterUser getMasterUser(Integer id) {
return masterUserMapper.selectByPrimaryKey(id);
}
public int insert() {
MasterUser masterUser = new MasterUser();
masterUser.setName("your papa");
masterUser.setAge(48);
masterUser.setGender("M");
return masterUserMapper.insert(masterUser);
}
}
package wen.druid.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import wen.druid.entity.CustomUser;
import wen.druid.mapper.CustomUserMapper;
@Service
public class CustomUserService {
@Autowired
private CustomUserMapper customUserMapper;
public CustomUser getCustomUser(Integer id) {
return customUserMapper.selectByPrimaryKey(id);
}
public int insert() {
CustomUser customUser = new CustomUser();
customUser.setName("mama");
customUser.setAge(49);
customUser.setGender("F");
return customUserMapper.insert(customUser);
}
}
主数据源配置,需要加 @Primary:
MasterDataSourceConfig.java
package wen.druid.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
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 org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = MasterDataSourceConfig.PACKAGES, sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDataSourceConfig {
static final String PACKAGES = "wen.druid.mapper";
private static final String MAPPER_LOCAL = "classpath:mapper/*.xml";
@Primary
@Bean(name = "masterDataSource")
@ConfigurationProperties("spring.datasource")
public DruidDataSource druidDataSource() {
return new DruidDataSource();
}
@Primary
@Bean(name = "masterTransactionManager")
public DataSourceTransactionManager masterTransactionManager() {
return new DataSourceTransactionManager(druidDataSource());
}
@Primary
@Bean(name = "masterSqlSessionFactory")
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
final SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCAL));
return sessionFactoryBean.getObject();
}
}
CustomDataSourceConfig.java
从数据源配置 不需要加@Primary:
package wen.druid.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
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.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
@Configuration
@MapperScan(basePackages = CustomDataSourceConfig.PACKAGES, sqlSessionFactoryRef = "customSqlSessionFactory")
public class CustomDataSourceConfig {
static final String PACKAGES = "wen.druid.mapper";
private static final String MAPPER_LOCAL = "classpath:mapper/*.xml";
@Bean(name = "customDataSource")
@ConfigurationProperties("custom.datasource.ds1")
public DruidDataSource druidDataSource() {
return new DruidDataSource();
}
@Bean(name = "customTransactionManager")
public DataSourceTransactionManager customTransactionManager() {
return new DataSourceTransactionManager(druidDataSource());
}
@Bean(name = "customSqlSessionFactory")
public SqlSessionFactory customSqlSessionFactory(@Qualifier("customDataSource") DruidDataSource dataSource) throws Exception {
final SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCAL));
return sessionFactoryBean.getObject();
}
}
DruidStatViewServlet.java
package wen.druid.config;
import com.alibaba.druid.support.http.StatViewServlet;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
@SuppressWarnings("serial")
@WebServlet(urlPatterns = "/druid/*",
initParams = {
@WebInitParam(name = "allow", value = "192.168.16.110,127.0.0.1"),// IP白名单 (没有配置或者为空,则允许所有访问)
@WebInitParam(name = "deny", value = "192.168.16.111"),// IP黑名单 (存在共同时,deny优先于allow)
@WebInitParam(name = "loginUsername", value = "Stephanie"),// 用户名
@WebInitParam(name = "loginPassword", value = "admin"),// 密码
@WebInitParam(name = "resetEnable", value = "false")// 禁用HTML页面上的“Reset All”功能
})
public class DruidStatViewServlet extends StatViewServlet {
}
上文中的druid控制端用户名为:Stephanie,密码为admin
package wen.druid.config;
import com.alibaba.druid.support.http.WebStatFilter;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
@WebFilter(filterName = "druidWebStatFilter", urlPatterns = "/*",
initParams = {
@WebInitParam(name = "exclusions", value = "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*")// 忽略资源
})
public class DruidStatFilter extends WebStatFilter {
}
package wen.druid;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan
public class DruidApplication {
public static void main(String[] args) {
SpringApplication.run(DruidApplication.class, args);
}
}