# springboot-multi-datasource
**Repository Path**: mengbaoyuxuan/springboot-multi-datasource
## Basic Information
- **Project Name**: springboot-multi-datasource
- **Description**: springboot使用druid配置多数据源(oracle+mysql),mybatis作为持久层组件
- **Primary Language**: Java
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 5
- **Forks**: 2
- **Created**: 2019-05-14
- **Last Updated**: 2023-05-18
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# springboot-multi-datasource
#### 介绍
springboot使用druid配置多数据源(oracle+mysql),mybatis作为持久层组件
#### 软件架构
软件架构说明
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
#### 使用说明
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
### 问题记录
#### 一、数据库导入导出限制
执行
```sql
show variables like '%secure%';
```
结果:
```$xslt
require_secure_transport OFF
secure_file_priv C:/ProgramData/MySQL/MySQL Server 8.0/Uploads
```
关于`secure_file_priv`的三种说明:
- NULL: 表示不允许导入导出,secure-file-priv注释即可
- 空值: 表示不受任何限制,secure-file-priv=
- 指定路径:表示只能在指定路径导入导出
#### 二、日期字段格式问题
oracle DATE类型字段导出来格式为yyyy-MM-dd HH:mm:ss.S
但表结构限制字段为14位,已超长,需要对日期去掉.S的值
#### 三、日期字段为空load报错
(1)问题重现
执行脚本:
```sql
load data infile 'E:/oracle/BDC_SEND_MUSICCONTINFO_891_1-818.txt'replace into table `BDC_SEND_MUSICCONTINFO_891` fields terminated by ';' lines terminated by '\n' IGNORE 1 LINES (`SEC_ID`,`PROC_ID`,`NODE`,`PROV_CODE`,`STATUS`,`ERROR_CODE`,`SEND_TIME`,`RECEIVE_TIME`,`CREATE_DATE`,`LAST_UPDATE`,`SEND_AMOUNT`,`FILE_NAME`,`PART_MONTH`,`ORDER_STATUS`);
```
结果:
```text
### Error updating database. Cause: com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Incorrect datetime value: '' for column 'LAST_UPDATE' at row 1 ### The error may exist in file [E:\workspace\springboot-multi-datasource\target\classes\mybatis\mysql\mapper\MysqlTableMapper.xml] ### The error may involve com.eipv.multidatasource.mapper.mysql.MysqlTableMapper.loadInDb-Inline ### The error occurred while setting parameters ### SQL: load data infile 'E:/oracle/BDC_SEND_MUSICCONTINFO_891_1-818.txt'replace into table `BDC_SEND_MUSICCONTINFO_891` fields terminated by ';' lines terminated by '\n' IGNORE 1 LINES (`SEC_ID`,`PROC_ID`,`NODE`,`PROV_CODE`,`STATUS`,`ERROR_CODE`,`SEND_TIME`,`RECEIVE_TIME`,`CREATE_DATE`,`LAST_UPDATE`,`SEND_AMOUNT`,`FILE_NAME`,`PART_MONTH`,`ORDER_STATUS`); ### Cause: com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Incorrect datetime value: '' for column 'LAST_UPDATE' at row 1 ; Data truncation: Incorrect datetime value: '' for column 'LAST_UPDATE' at row 1; nested exception is com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Incorrect datetime value: '' for column 'LAST_UPDATE' at row 1
```
(2)分析
- 原因:
```text
STRICT_TRANS_TABLES的工作方式:
· 对于事务性存储引擎,在语句中任何地方出现的不良数据值均会导致放弃语句并执行回滚。
· 对于非事务性存储引擎,如果错误出现在要插入或更新的第1行,将放弃语句。(在这种情况下,可以认为语句未改变表,就像事务表一样)。首行后出现的错误不会导致放弃语句。取而代之的是,将调整不良数据值,并给出告警,而不是错误。换句话讲,使用STRICT_TRANS_TABLES后,错误值会导致MySQL执行回滚操作,如果可以,所有更新到此为止。
```
- 查看sql_mode配置
```sql
show VARIABLES like '%sql_mode%';
```
- 修改配置:
```text
D:\ProgramData\MySQL\MySQL Server 8.0\my.ini
#sql-mode="STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION"
sql-mode="NO_ENGINE_SUBSTITUTION"
```
- 重启mysql并重新执行load脚本,发现还是不能执行,于是,通过程序来执行动态sql查询sql_mode,竟然sql_mode还是STRICT_TRANS_TABLES,为什么呢,网上这种资料找了半天也没找到,
于是开启mysql查询日志general_log(修改my.ini或my.cnf,修改对应值为1),通过查看查询日志发现如下
注意第四行,每次查询会给session级别设置严格模式,即使mysql已经设置了sql_mode,因此找到原因就好办。在执行sql前将session
级别的sql_mode设置为空,这样就不会受到限制了。
```text
2019-05-16T08:53:57.646571Z 49 Query SET NAMES utf8mb4
2019-05-16T08:53:57.646856Z 49 Query SET character_set_results = NULL
2019-05-16T08:53:57.647150Z 49 Query SET autocommit=1
2019-05-16T08:53:57.647490Z 49 Query SET sql_mode='STRICT_TRANS_TABLES'
2019-05-16T08:53:57.647820Z 49 Query SHOW WARNINGS
2019-05-16T08:53:57.648434Z 49 Query SELECT @@session.transaction_read_only
2019-05-16T08:53:57.648751Z 49 Query SELECT @@session.transaction_isolation
2019-05-16T08:53:57.707698Z 49 Query set sql_mode='';
2019-05-16T08:53:57.707919Z 49 Query show VARIABLES like '%sql_mode%'
```
修改后的sql
```sql
```
附设置严格模式原因:
- D:\lvm\maven\repos2\mysql\mysql-connector-java\8.0.15\mysql-connector-java-8.0.15.jar!\com\mysql\cj\jdbc\ConnectionImpl.class
```java
private void setupServerForTruncationChecks() throws SQLException {
try {
synchronized(this.getConnectionMutex()) {
RuntimeProperty jdbcCompliantTruncation = this.propertySet.getProperty(PropertyKey.jdbcCompliantTruncation);
if ((Boolean)jdbcCompliantTruncation.getValue()) {
String currentSqlMode = this.session.getServerSession().getServerVariable("sql_mode");
boolean strictTransTablesIsSet = StringUtils.indexOfIgnoreCase(currentSqlMode, "STRICT_TRANS_TABLES") != -1;
if (currentSqlMode != null && currentSqlMode.length() != 0 && strictTransTablesIsSet) {
if (strictTransTablesIsSet) {
jdbcCompliantTruncation.setValue(false);
}
} else {
StringBuilder commandBuf = new StringBuilder("SET sql_mode='");
if (currentSqlMode != null && currentSqlMode.length() > 0) {
commandBuf.append(currentSqlMode);
commandBuf.append(",");
}
commandBuf.append("STRICT_TRANS_TABLES'");
this.session.execSQL((Query)null, commandBuf.toString(), -1, (NativePacketPayload)null, false, this.nullStatementResultSetFactory, this.database, (ColumnDefinition)null, false);
jdbcCompliantTruncation.setValue(false);
}
}
}
} catch (CJException var9) {
throw SQLExceptionsMapping.translateException(var9, this.getExceptionInterceptor());
}
}
```