背景:现在的项目大多数都是多数据源
pom依赖
使用spring-boot-starter-data-jdbc去写业务、druid-spring-boot-starter配置多数源
<dependencies>
<!-- web支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- druid -->
<!-- <dependency>-->
<!-- <groupId>com.alibaba</groupId>-->
<!-- <artifactId>druid</artifactId>-->
<!-- <version>1.1.23</version>-->
<!-- </dependency>-->
<!-- druid 的 start -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.13</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.1-jre</version>
</dependency>
</dependencies>
yml文件
spring:
profiles:
active: dev
server:
port: 9990
---
spring:
profiles: dev
datasource:
druid:
cms:
url: jdbc:mysql://localhost:3306/***_test
username: root
password: 3306
max-active: 5
bms:
url: jdbc:mysql://localhost:3306/***_test
username: root
password: 3306
max-activ: 5
配置类
DataSourceConfig
package com.pingfan.cms.config;
import com.alibaba.druid.filter.logging.LogFilter;
import com.alibaba.druid.filter.logging.Slf4jLogFilter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.google.common.collect.Lists;
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;
import java.util.concurrent.TimeUnit;
/**
* @author liuyuanyuan on 2023/2/19
*/
@Configuration
public class DataSourceConfig {
@Bean(name = "cmsSource")
@Primary
@ConfigurationProperties("spring.datasource.druid.cms")
public DataSource cmsDataSource() {
return cmsConfig(DruidDataSourceBuilder.create().build());
}
private DruidDataSource cmsConfig(DruidDataSource dataSource) {
dataSource.setInitialSize(1);
dataSource.setMaxActive(5);
dataSource.setMinIdle(1);
dataSource.setMaxWait(TimeUnit.MILLISECONDS.toMillis(3000));
dataSource.setValidationQuery("SELECT 1");
dataSource.setTestOnBorrow(false);
dataSource.setTestOnReturn(false);
dataSource.setTestWhileIdle(true);
dataSource.setPoolPreparedStatements(false);
dataSource.setConnectionErrorRetryAttempts(0);
dataSource.setBreakAfterAcquireFailure(true);
dataSource.setTimeBetweenEvictionRunsMillis(TimeUnit.MILLISECONDS.toMillis(800));
dataSource.setMinEvictableIdleTimeMillis(TimeUnit.MINUTES.toMillis(5));
//用于统计监控信息
StatFilter statfilter = new StatFilter();
//(慢SQL记录)用来配置SQL慢的标准 1s 的sql 会被error 出来
statfilter.setSlowSqlMillis(1000);
statfilter.setLogSlowSql(true);
LogFilter logFilter = new Slf4jLogFilter();
dataSource.setProxyFilters(Lists.newArrayList(statfilter, logFilter));
return dataSource;
}
@Bean(name = "bmsSource")
@ConfigurationProperties("spring.datasource.druid.bms")
public DataSource bmsDataSource() {
return bmsConfig(DruidDataSourceBuilder.create().build());
}
private DataSource bmsConfig(DruidDataSource dataSource) {
dataSource.setInitialSize(1);
dataSource.setMaxActive(5);
dataSource.setMinIdle(1);
dataSource.setMaxWait(TimeUnit.MILLISECONDS.toMillis(3000));
dataSource.setValidationQuery("SELECT 1");
dataSource.setTestOnBorrow(false);
dataSource.setTestOnReturn(false);
dataSource.setTestWhileIdle(true);
dataSource.setPoolPreparedStatements(false);
dataSource.setConnectionErrorRetryAttempts(0);
dataSource.setBreakAfterAcquireFailure(true);
dataSource.setTimeBetweenEvictionRunsMillis(TimeUnit.MILLISECONDS.toMillis(800));
dataSource.setMinEvictableIdleTimeMillis(TimeUnit.MINUTES.toMillis(5));
StatFilter statfilter = new StatFilter();
statfilter.setSlowSqlMillis(1000);
statfilter.setLogSlowSql(true);
LogFilter logFilter = new Slf4jLogFilter();
dataSource.setProxyFilters(Lists.newArrayList(statfilter, logFilter));
return dataSource;
}
}
JdbcTemplateConfig
package com.pingfan.cms.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
/**
* @author liuyuanyuan on 2023/2/19
*/
@Configuration
public class JdbcTemplateConfig {
@Bean
public JdbcTemplate cmsJdbcTemplate(@Qualifier("cmsSource") DataSource cmsDataSource){
return new JdbcTemplate(cmsDataSource);
}
@Bean
public JdbcTemplate bmsJdbcTemplate(@Qualifier("bmsSource") DataSource bmsDataSource){
return new JdbcTemplate(bmsDataSource);
}
}
实体
UserEntity
package com.pingfan.cms.model.bms;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* @author liuyuanyuan on 2023/2/19
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UserEntity {
Long id;
String name;
String email;
@JSONField(serialize = false)
String password;
@JSONField(name = "created_at")
Date createdAt;
@JSONField(name = "updated_at")
Date updatedAt;
}
启动类并且测试
jdbc映射规则会自动匹配驼峰,所以按照驼峰命名即可
package com.pingfan.cms;
import com.pingfan.cms.model.bms.UserEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
/**
* @author liuyuanyuan on 2023/2/18
*/
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class})
public class SpringJdbcMain implements CommandLineRunner, ApplicationContextAware {
private ApplicationContext applicationContext;
Logger logger = LoggerFactory.getLogger(SpringJdbcMain.class);
@Autowired
@Qualifier("bmsJdbcTemplate")
private JdbcTemplate bmsJdbcTemplate;
@Autowired
@Qualifier("cmsJdbcTemplate")
private JdbcTemplate cmsJdbcTemplate;
// @Autowired
// DataSource dataSource;
public static void main(String[] args) {
SpringApplication.run(SpringJdbcMain.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println(">>>>>>>>>>>>>>>>>服务启动执行");
//showIOCBean();
System.out.println("done");
//showConnection();
List<UserEntity> bmsUser = this.bmsJdbcTemplate.query("select * from users where id =20", new BeanPropertyRowMapper<>(UserEntity.class));
System.out.println(bmsUser);
}
private void showConnection() throws SQLException {
// logger.info("dataSource:{}", dataSource.getClass().getName());
// Connection connection = dataSource.getConnection();
// logger.info("connection:{}", connection.toString());
}
private void showIOCBean() {
Arrays.stream(this.applicationContext.getBeanDefinitionNames()).forEach(bean->{
System.out.println(bean);
});
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext=applicationContext;
}
// @Bean
// public DataSource dataSource() {
// DruidDataSource dataSource = new DruidDataSource();
// dataSource.setUrl("jdbc:mysql://localhost:3306/bms_test");
// dataSource.setUsername("root");
// dataSource.setPassword("3306");
// return dataSource;
// }
}
踩坑合集
1、由于在url上设置了**jdbc:log4jdbc:**mysql://…造成一致报错
Failed to obtain JDBC Connection; nested exception is java.sql.SQLException:
说实话这个报错看了半天都是各种解法,要不是我看了一眼我用了jdbc:log4jdbc:还真不知道问题出现在哪。
解决:用这个主要是让sql完整的打印出参数。mybatsi和jpa都是?显示参数的,添加依赖即可。
<dependency>
<groupId>com.googlecode.log4jdbc</groupId>
<artifactId>log4jdbc</artifactId>
<version>1.2</version>
</dependency>
另外这个貌似只支持mysql5版本,之前用jpa项目有一个一致控制台一直爆红但不影响项目运行,就是它的原因。找到怎么解决在更新吧~