Background : 현재 대부분의 프로젝트는 다중 데이터 소스
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);
}
}
엔티티
사용자엔티티
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://…이 설정되어 있기 때문에 동일한 오류가 보고
됩니다
. 해결책은 제가 흘끗 보지 않았다면 jdbc:log4jdbc를 사용했습니다: 정말 어디가 문제인지 모르겠습니다.
솔루션 : SQL이 매개변수를 완전히 출력하도록 주로 사용하십시오. mybatsi와 jpa 모두? 매개변수를 표시하려면 종속성을 추가하기만 하면 됩니다.
<dependency>
<groupId>com.googlecode.log4jdbc</groupId>
<artifactId>log4jdbc</artifactId>
<version>1.2</version>
</dependency>
게다가 이건 mysql5 버전만 지원하는 것 같은데 이전에 jpa 프로젝트에서 유행했던 일관된 콘솔이 있긴 하지만 프로젝트 운영에 영향을 주지 않는다는 것이 이유다. 해결방법 알아보고 업데이트 해보세요~