Commit 6f18adb54a259a9db0cfdaec33c4b07d0b3d40ef
1 parent
7db1a58b
适配 Oracle 数据库
1. 修复配置中心的 DAO 查询报错 2. 适配 LIMIT 1 的查询
Showing
8 changed files
with
56 additions
and
21 deletions
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 | 15 | public interface ConfigFrameworkDAO { |
| 16 | 16 | |
| 17 | 17 | /** |
| 18 | - * 查询是否存在比 maxUpdateTime 更新记录更晚的配置 | |
| 18 | + * 查询是否存在比 maxUpdateTime 的更新记录数量 | |
| 19 | 19 | * |
| 20 | 20 | * @param maxUpdateTime 最大更新时间 |
| 21 | 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 | 24 | import java.util.Properties; |
| 25 | 25 | import java.util.concurrent.Executors; |
| 26 | 26 | import java.util.concurrent.ScheduledExecutorService; |
| 27 | -import java.util.function.Predicate; | |
| 28 | 27 | |
| 29 | 28 | @Slf4j |
| 30 | 29 | public class DBConfigRepository extends AbstractConfigRepository { |
| ... | ... | @@ -172,7 +171,7 @@ public class DBConfigRepository extends AbstractConfigRepository { |
| 172 | 171 | if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据 |
| 173 | 172 | log.info("[loadConfigIfUpdate][首次加载全量配置]"); |
| 174 | 173 | } else { // 判断数据库中是否有更新的配置 |
| 175 | - if (!configFrameworkDAO.selectExistsByUpdateTimeAfter(maxUpdateTime)) { | |
| 174 | + if (configFrameworkDAO.selectCountByUpdateTimeGt(maxUpdateTime) == 0) { | |
| 176 | 175 | return null; |
| 177 | 176 | } |
| 178 | 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 | 2 | |
| 3 | 3 | import cn.hutool.core.util.StrUtil; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.util.collection.SetUtils; |
| 5 | +import cn.iocoder.yudao.framework.mybatis.core.enums.SqlConstants; | |
| 5 | 6 | import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils; |
| 6 | 7 | import com.baomidou.mybatisplus.annotation.DbType; |
| 7 | 8 | import com.baomidou.mybatisplus.annotation.IdType; |
| ... | ... | @@ -41,6 +42,9 @@ public class IdTypeEnvironmentPostProcessor implements EnvironmentPostProcessor |
| 41 | 42 | // TODO 芋艿:暂时没有找到特别合适的地方,先放在这里 |
| 42 | 43 | setJobStoreDriverIfPresent(environment, dbType); |
| 43 | 44 | |
| 45 | + // 初始化 SQL 静态变量 | |
| 46 | + SqlConstants.init(dbType); | |
| 47 | + | |
| 44 | 48 | // 如果非 NONE,则不进行处理 |
| 45 | 49 | IdType idType = getIdType(environment); |
| 46 | 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 | 1 | package cn.iocoder.yudao.framework.mybatis.core.enums; |
| 2 | 2 | |
| 3 | +import com.baomidou.mybatisplus.annotation.DbType; | |
| 4 | + | |
| 3 | 5 | /** |
| 4 | 6 | * SQL相关常量类 |
| 5 | 7 | * |
| 6 | 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 | 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 | 5 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| 4 | 6 | import com.baomidou.mybatisplus.core.toolkit.ArrayUtils; |
| 5 | 7 | import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; |
| ... | ... | @@ -124,4 +126,24 @@ public class QueryWrapperX<T> extends QueryWrapper<T> { |
| 124 | 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 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.apollo.internals.ConfigFrameworkDAO; |
| 4 | 4 | import cn.iocoder.yudao.framework.apollo.internals.dto.ConfigRespDTO; |
| 5 | -import org.springframework.jdbc.core.BeanPropertyRowMapper; | |
| 6 | 5 | import org.springframework.jdbc.core.JdbcTemplate; |
| 7 | 6 | import org.springframework.jdbc.datasource.DriverManagerDataSource; |
| 8 | 7 | |
| 9 | 8 | import javax.sql.DataSource; |
| 10 | -import java.sql.ResultSet; | |
| 11 | 9 | import java.util.Date; |
| 12 | 10 | import java.util.List; |
| 13 | 11 | |
| ... | ... | @@ -26,14 +24,18 @@ public class ConfigDAOImpl implements ConfigFrameworkDAO { |
| 26 | 24 | } |
| 27 | 25 | |
| 28 | 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 | 32 | @Override |
| 35 | 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
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/sms/SmsCodeMapper.java
| 1 | 1 | package cn.iocoder.yudao.module.system.dal.mysql.sms; |
| 2 | 2 | |
| 3 | -import cn.iocoder.yudao.framework.mybatis.core.enums.SqlConstants; | |
| 4 | 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 | 5 | import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsCodeDO; |
| 7 | 6 | import org.apache.ibatis.annotations.Mapper; |
| 8 | 7 | |
| ... | ... | @@ -18,12 +17,12 @@ public interface SmsCodeMapper extends BaseMapperX<SmsCodeDO> { |
| 18 | 17 | * @return 手机验证码 |
| 19 | 18 | */ |
| 20 | 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 | } | ... | ... |