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,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<SmsCodeDO> { | @@ -18,12 +17,12 @@ public interface SmsCodeMapper extends BaseMapperX<SmsCodeDO> { | ||
| 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 | } |