# 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()); } } ```