Background : Most of the current projects are multi-data source
pom dependencies
. Use spring-boot-starter-data-jdbc to write business, and druid-spring-boot-starter to configure most sources
<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 file
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
Configuration class
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);
}
}
Entity
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;
}
Start the class and test
the jdbc mapping rule to automatically match the hump, so you can name it according to the hump
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;
// }
}
Stepping on the pit collection
1. Because **jdbc:log4jdbc:**mysql://… is set on the url, the same error is reported
Failed to obtain JDBC Connection; nested exception is java.sql.SQLException:
To be honest, this error has been reported for a long time. The solution, if I hadn't glanced at it, I used jdbc:log4jdbc: I really don't know where the problem is.
Solution : Use this mainly to let sql print out the parameters completely. Both mybatsi and jpa? To display parameters, just add dependencies.
<dependency>
<groupId>com.googlecode.log4jdbc</groupId>
<artifactId>log4jdbc</artifactId>
<version>1.2</version>
</dependency>
In addition, this seems to only support the mysql5 version. There is a consistent console that has been popular in the jpa project before, but it does not affect the operation of the project, which is the reason. Find out how to solve it and update it~