Commit 6f18adb54a259a9db0cfdaec33c4b07d0b3d40ef

Authored by YunaiV
1 parent 7db1a58b

适配 Oracle 数据库

1. 修复配置中心的 DAO 查询报错
2. 适配 LIMIT 1 的查询
yudao-framework/yudao-spring-boot-starter-config/src/main/java/cn/iocoder/yudao/framework/apollo/internals/ConfigFrameworkDAO.java
@@ -15,12 +15,12 @@ import java.util.List; @@ -15,12 +15,12 @@ import java.util.List;
15 public interface ConfigFrameworkDAO { 15 public interface ConfigFrameworkDAO {
16 16
17 /** 17 /**
18 - * 查询是否存在比 maxUpdateTime 更新记录更晚的配置 18 + * 查询是否存在比 maxUpdateTime 的更新记录数量
19 * 19 *
20 * @param maxUpdateTime 最大更新时间 20 * @param maxUpdateTime 最大更新时间
21 * @return 是否存在 21 * @return 是否存在
22 */ 22 */
23 - boolean selectExistsByUpdateTimeAfter(Date maxUpdateTime); 23 + int selectCountByUpdateTimeGt(Date maxUpdateTime);
24 24
25 /** 25 /**
26 * 查询配置列表 26 * 查询配置列表
yudao-framework/yudao-spring-boot-starter-config/src/main/java/cn/iocoder/yudao/framework/apollo/internals/DBConfigRepository.java
@@ -24,7 +24,6 @@ import java.util.List; @@ -24,7 +24,6 @@ import java.util.List;
24 import java.util.Properties; 24 import java.util.Properties;
25 import java.util.concurrent.Executors; 25 import java.util.concurrent.Executors;
26 import java.util.concurrent.ScheduledExecutorService; 26 import java.util.concurrent.ScheduledExecutorService;
27 -import java.util.function.Predicate;  
28 27
29 @Slf4j 28 @Slf4j
30 public class DBConfigRepository extends AbstractConfigRepository { 29 public class DBConfigRepository extends AbstractConfigRepository {
@@ -172,7 +171,7 @@ public class DBConfigRepository extends AbstractConfigRepository { @@ -172,7 +171,7 @@ public class DBConfigRepository extends AbstractConfigRepository {
172 if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据 171 if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据
173 log.info("[loadConfigIfUpdate][首次加载全量配置]"); 172 log.info("[loadConfigIfUpdate][首次加载全量配置]");
174 } else { // 判断数据库中是否有更新的配置 173 } else { // 判断数据库中是否有更新的配置
175 - if (!configFrameworkDAO.selectExistsByUpdateTimeAfter(maxUpdateTime)) { 174 + if (configFrameworkDAO.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
176 return null; 175 return null;
177 } 176 }
178 log.info("[loadConfigIfUpdate][增量加载全量配置]"); 177 log.info("[loadConfigIfUpdate][增量加载全量配置]");
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/config/IdTypeEnvironmentPostProcessor.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.mybatis.config; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.mybatis.config;
2 2
3 import cn.hutool.core.util.StrUtil; 3 import cn.hutool.core.util.StrUtil;
4 import cn.iocoder.yudao.framework.common.util.collection.SetUtils; 4 import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
  5 +import cn.iocoder.yudao.framework.mybatis.core.enums.SqlConstants;
5 import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils; 6 import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils;
6 import com.baomidou.mybatisplus.annotation.DbType; 7 import com.baomidou.mybatisplus.annotation.DbType;
7 import com.baomidou.mybatisplus.annotation.IdType; 8 import com.baomidou.mybatisplus.annotation.IdType;
@@ -41,6 +42,9 @@ public class IdTypeEnvironmentPostProcessor implements EnvironmentPostProcessor @@ -41,6 +42,9 @@ public class IdTypeEnvironmentPostProcessor implements EnvironmentPostProcessor
41 // TODO 芋艿:暂时没有找到特别合适的地方,先放在这里 42 // TODO 芋艿:暂时没有找到特别合适的地方,先放在这里
42 setJobStoreDriverIfPresent(environment, dbType); 43 setJobStoreDriverIfPresent(environment, dbType);
43 44
  45 + // 初始化 SQL 静态变量
  46 + SqlConstants.init(dbType);
  47 +
44 // 如果非 NONE,则不进行处理 48 // 如果非 NONE,则不进行处理
45 IdType idType = getIdType(environment); 49 IdType idType = getIdType(environment);
46 if (idType != IdType.NONE) { 50 if (idType != IdType.NONE) {
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/enums/SqlConstants.java
1 package cn.iocoder.yudao.framework.mybatis.core.enums; 1 package cn.iocoder.yudao.framework.mybatis.core.enums;
2 2
  3 +import com.baomidou.mybatisplus.annotation.DbType;
  4 +
3 /** 5 /**
4 * SQL相关常量类 6 * SQL相关常量类
5 * 7 *
6 * @author 芋道源码 8 * @author 芋道源码
7 */ 9 */
8 -public interface SqlConstants { 10 +public class SqlConstants {
  11 +
  12 + /**
  13 + * 数据库的类型
  14 + */
  15 + public static DbType DB_TYPE;
9 16
10 - String LIMIT1 = "LIMIT 1"; 17 + public static void init(DbType dbType) {
  18 + DB_TYPE = dbType;
  19 + }
11 20
12 } 21 }
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/QueryWrapperX.java
1 package cn.iocoder.yudao.framework.mybatis.core.query; 1 package cn.iocoder.yudao.framework.mybatis.core.query;
2 2
  3 +import cn.hutool.core.lang.Assert;
  4 +import cn.iocoder.yudao.framework.mybatis.core.enums.SqlConstants;
3 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 5 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
4 import com.baomidou.mybatisplus.core.toolkit.ArrayUtils; 6 import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
5 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; 7 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@@ -124,4 +126,24 @@ public class QueryWrapperX<T> extends QueryWrapper<T> { @@ -124,4 +126,24 @@ public class QueryWrapperX<T> extends QueryWrapper<T> {
124 return this; 126 return this;
125 } 127 }
126 128
  129 + /**
  130 + * 设置只返回最后一条
  131 + *
  132 + * TODO 芋艿:不是完美解,需要在思考下。如果使用多数据源,并且数据源是多种类型时,可能会存在问题:实现之返回一条的语法不同
  133 + *
  134 + * @return this
  135 + */
  136 + public QueryWrapperX<T> limit1() {
  137 + Assert.notNull(SqlConstants.DB_TYPE, "获取不到数据库的类型");
  138 + switch (SqlConstants.DB_TYPE) {
  139 + case ORACLE:
  140 + case ORACLE_12C:
  141 + super.eq("ROWNUM", 1);
  142 + break;
  143 + default:
  144 + super.last("LIMIT 1");
  145 + }
  146 + return this;
  147 + }
  148 +
127 } 149 }
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/config/ConfigDAOImpl.java
@@ -2,12 +2,10 @@ package cn.iocoder.yudao.module.infra.dal.mysql.config; @@ -2,12 +2,10 @@ package cn.iocoder.yudao.module.infra.dal.mysql.config;
2 2
3 import cn.iocoder.yudao.framework.apollo.internals.ConfigFrameworkDAO; 3 import cn.iocoder.yudao.framework.apollo.internals.ConfigFrameworkDAO;
4 import cn.iocoder.yudao.framework.apollo.internals.dto.ConfigRespDTO; 4 import cn.iocoder.yudao.framework.apollo.internals.dto.ConfigRespDTO;
5 -import org.springframework.jdbc.core.BeanPropertyRowMapper;  
6 import org.springframework.jdbc.core.JdbcTemplate; 5 import org.springframework.jdbc.core.JdbcTemplate;
7 import org.springframework.jdbc.datasource.DriverManagerDataSource; 6 import org.springframework.jdbc.datasource.DriverManagerDataSource;
8 7
9 import javax.sql.DataSource; 8 import javax.sql.DataSource;
10 -import java.sql.ResultSet;  
11 import java.util.Date; 9 import java.util.Date;
12 import java.util.List; 10 import java.util.List;
13 11
@@ -26,14 +24,18 @@ public class ConfigDAOImpl implements ConfigFrameworkDAO { @@ -26,14 +24,18 @@ public class ConfigDAOImpl implements ConfigFrameworkDAO {
26 } 24 }
27 25
28 @Override 26 @Override
29 - public boolean selectExistsByUpdateTimeAfter(Date maxUpdateTime) {  
30 - return jdbcTemplate.query("SELECT id FROM infra_config WHERE update_time > ? LIMIT 1",  
31 - ResultSet::next, maxUpdateTime); 27 + public int selectCountByUpdateTimeGt(Date maxUpdateTime) {
  28 + return jdbcTemplate.queryForObject("SELECT COUNT(*) FROM infra_config WHERE update_time > ?",
  29 + Integer.class, maxUpdateTime);
32 } 30 }
33 31
34 @Override 32 @Override
35 public List<ConfigRespDTO> selectList() { 33 public List<ConfigRespDTO> selectList() {
36 - return jdbcTemplate.query("SELECT `key`, `value`, update_time, deleted FROM infra_config", new BeanPropertyRowMapper<>(ConfigRespDTO.class)); 34 + return jdbcTemplate.query("SELECT config_key, value, update_time, deleted FROM infra_config",
  35 + (rs, rowNum) -> new ConfigRespDTO().setKey(rs.getString("config_key"))
  36 + .setValue(rs.getString("value"))
  37 + .setUpdateTime(rs.getDate("update_time"))
  38 + .setDeleted(rs.getBoolean("deleted")));
37 } 39 }
38 40
39 } 41 }
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http
@@ -9,7 +9,7 @@ tenant-id: {{appTenentId}} @@ -9,7 +9,7 @@ tenant-id: {{appTenentId}}
9 } 9 }
10 10
11 ### 请求 /send-sms-code 接口 => 成功 11 ### 请求 /send-sms-code 接口 => 成功
12 -POST {{appApi}}/member/send-sms-code 12 +POST {{appApi}}/member/auth/send-sms-code
13 Content-Type: application/json 13 Content-Type: application/json
14 tenant-id: {{appTenentId}} 14 tenant-id: {{appTenentId}}
15 15
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/sms/SmsCodeMapper.java
1 package cn.iocoder.yudao.module.system.dal.mysql.sms; 1 package cn.iocoder.yudao.module.system.dal.mysql.sms;
2 2
3 -import cn.iocoder.yudao.framework.mybatis.core.enums.SqlConstants;  
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 4 +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
6 import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsCodeDO; 5 import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsCodeDO;
7 import org.apache.ibatis.annotations.Mapper; 6 import org.apache.ibatis.annotations.Mapper;
8 7
@@ -18,12 +17,12 @@ public interface SmsCodeMapper extends BaseMapperX&lt;SmsCodeDO&gt; { @@ -18,12 +17,12 @@ public interface SmsCodeMapper extends BaseMapperX&lt;SmsCodeDO&gt; {
18 * @return 手机验证码 17 * @return 手机验证码
19 */ 18 */
20 default SmsCodeDO selectLastByMobile(String mobile, String code, Integer scene) { 19 default SmsCodeDO selectLastByMobile(String mobile, String code, Integer scene) {
21 - return selectOne(new LambdaQueryWrapperX<SmsCodeDO>()  
22 - .eq(SmsCodeDO::getCode, mobile)  
23 - .eqIfPresent(SmsCodeDO::getScene, scene)  
24 - .eqIfPresent(SmsCodeDO::getCode, code)  
25 - .orderByDesc(SmsCodeDO::getId)  
26 - .last(SqlConstants.LIMIT1)); 20 + return selectOne(new QueryWrapperX<SmsCodeDO>()
  21 + .eq("mobile", mobile)
  22 + .eqIfPresent("scene", scene)
  23 + .eqIfPresent("code", code)
  24 + .orderByDesc("id")
  25 + .limit1());
27 } 26 }
28 27
29 } 28 }