Commit 2dc8071faa763f835c9b67e87bf570af38bd000f

Authored by YunaiV
1 parent 36165e72

【功能优化】全局:增加 selectFirstOne 方法,解决容易出现并发场景下的查询

yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
... ... @@ -92,10 +92,36 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> {
92 92  
93 93 default T selectOne(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2,
94 94 SFunction<T, ?> field3, Object value3) {
95   - return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2)
96   - .eq(field3, value3));
  95 + return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2).eq(field3, value3));
97 96 }
98 97  
  98 + /**
  99 + * 获取满足条件的第 1 条记录
  100 + *
  101 + * 目的:解决并发场景下,插入多条记录后,使用 selectOne 会报错的问题
  102 + *
  103 + * @param field 字段名
  104 + * @param value 字段值
  105 + * @return 实体
  106 + */
  107 + default T selectFirstOne(SFunction<T, ?> field, Object value) {
  108 + // 如果明确使用 MySQL 等场景,可以考虑使用 LIMIT 1 进行优化
  109 + List<T> list = selectList(new LambdaQueryWrapper<T>().eq(field, value));
  110 + return CollUtil.getFirst(list);
  111 + }
  112 +
  113 + default T selectFirstOne(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2) {
  114 + List<T> list = selectList(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2));
  115 + return CollUtil.getFirst(list);
  116 + }
  117 +
  118 + default T selectFirstOne(SFunction<T,?> field1, Object value1, SFunction<T,?> field2, Object value2,
  119 + SFunction<T,?> field3, Object value3) {
  120 + List<T> list = selectList(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2).eq(field3, value3));
  121 + return CollUtil.getFirst(list);
  122 + }
  123 +
  124 +
99 125 default Long selectCount() {
100 126 return selectCount(new QueryWrapper<>());
101 127 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/history/ProductBrowseHistoryMapper.java
... ... @@ -21,9 +21,8 @@ import java.util.Collection;
21 21 public interface ProductBrowseHistoryMapper extends BaseMapperX<ProductBrowseHistoryDO> {
22 22  
23 23 default ProductBrowseHistoryDO selectByUserIdAndSpuId(Long userId, Long spuId) {
24   - return selectOne(new LambdaQueryWrapperX<ProductBrowseHistoryDO>()
25   - .eq(ProductBrowseHistoryDO::getUserId, userId)
26   - .eq(ProductBrowseHistoryDO::getSpuId, spuId));
  24 + return selectFirstOne(ProductBrowseHistoryDO::getUserId, userId,
  25 + ProductBrowseHistoryDO::getSpuId, spuId);
27 26 }
28 27  
29 28 default PageResult<ProductBrowseHistoryDO> selectPage(ProductBrowseHistoryPageReqVO reqVO) {
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialUserMapper.java
... ... @@ -5,23 +5,20 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 6 import cn.iocoder.yudao.module.system.controller.admin.socail.vo.user.SocialUserPageReqVO;
7 7 import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO;
8   -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
9 8 import org.apache.ibatis.annotations.Mapper;
10 9  
11 10 @Mapper
12 11 public interface SocialUserMapper extends BaseMapperX<SocialUserDO> {
13 12  
14 13 default SocialUserDO selectByTypeAndCodeAnState(Integer type, String code, String state) {
15   - return selectOne(new LambdaQueryWrapper<SocialUserDO>()
16   - .eq(SocialUserDO::getType, type)
17   - .eq(SocialUserDO::getCode, code)
18   - .eq(SocialUserDO::getState, state));
  14 + return selectOne(SocialUserDO::getType, type,
  15 + SocialUserDO::getCode, code,
  16 + SocialUserDO::getState, state);
19 17 }
20 18  
21 19 default SocialUserDO selectByTypeAndOpenid(Integer type, String openid) {
22   - return selectOne(new LambdaQueryWrapper<SocialUserDO>()
23   - .eq(SocialUserDO::getType, type)
24   - .eq(SocialUserDO::getOpenid, openid));
  20 + return selectFirstOne(SocialUserDO::getType, type,
  21 + SocialUserDO::getOpenid, openid);
25 22 }
26 23  
27 24 default PageResult<SocialUserDO> selectPage(SocialUserPageReqVO reqVO) {
... ...