Procházet zdrojové kódy

新增 BaseMapper#selectOne重载方法,新增 IService#getNonNullOne 和IService#GetNonNullById方法,现在查询一个对象不会返回 null 而是返回一个 Optional对象

Evan Zhai před 2 roky
rodič
revize
32f7708c4e

+ 18 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/mapper/BaseMapper.java

@@ -180,6 +180,24 @@ public interface BaseMapper<T> extends Mapper<T> {
         }
     }
 
+    /**
+     * 根据 entity 条件,查询一条记录,现在会根据{@code throwEx}参数判断是否抛出异常,如果为false就直接返回一条数据
+     * <p>查询一条记录,例如 qw.last("limit 1") 限制取一条记录, 注意:多条数据会报异常</p>
+     *
+     * @param throwEx      boolean 参数,为true如果存在多个结果直接抛出异常
+     * @param queryWrapper 实体对象封装操作类(可以为 null)
+     */
+    default T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper, boolean throwEx) {
+        List<T> list = this.selectList(queryWrapper);
+        if (list.size() == 1) {
+            return list.get(0);
+        } else if (list.size() > 0 && throwEx) {
+            throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size());
+        } else {
+            return list.size() == 0 ? null : list.get(0);
+        }
+    }
+
     /**
      * 根据 Wrapper 条件,判断是否存在记录
      *

+ 31 - 4
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/service/IService.java

@@ -34,10 +34,7 @@ import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.io.Serializable;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
@@ -292,6 +289,16 @@ public interface IService<T> {
         return getBaseMapper().selectById(id);
     }
 
+    /**
+     * 根据 ID 查询,返回一个Option对象
+     *
+     * @param id 主键ID
+     * @return {@link Optional}
+     */
+    default Optional<T> getNonNullById(Serializable id) {
+        return Optional.ofNullable(getBaseMapper().selectById(id));
+    }
+
     /**
      * 查询(根据ID 批量查询)
      *
@@ -320,6 +327,17 @@ public interface IService<T> {
         return getOne(queryWrapper, true);
     }
 
+    /**
+     * 根据 Wrapper,查询一条记录 <br/>
+     * <p>结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")</p>
+     *
+     * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
+     * @return {@link Optional} 返回一个Optional对象
+     */
+    default Optional<T> getNonNullOne(Wrapper<T> queryWrapper) {
+        return getNonNullOne(queryWrapper, true);
+    }
+
     /**
      * 根据 Wrapper,查询一条记录
      *
@@ -328,6 +346,15 @@ public interface IService<T> {
      */
     T getOne(Wrapper<T> queryWrapper, boolean throwEx);
 
+    /**
+     * 根据 Wrapper,查询一条记录
+     *
+     * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
+     * @param throwEx      有多个 result 是否抛出异常
+     * @return {@link Optional} 返回一个Optional对象
+     */
+    Optional<T> getNonNullOne(Wrapper<T> queryWrapper, boolean throwEx);
+
     /**
      * 根据 Wrapper,查询一条记录
      *

+ 9 - 0
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/service/impl/ServiceImpl.java

@@ -35,6 +35,7 @@ import java.io.Serializable;
 import java.util.Collection;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -204,6 +205,14 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
         return SqlHelper.getObject(log, baseMapper.selectList(queryWrapper));
     }
 
+    @Override
+    public Optional<T> getNonNullOne(Wrapper<T> queryWrapper, boolean throwEx) {
+        if (throwEx) {
+            return Optional.ofNullable(baseMapper.selectOne(queryWrapper));
+        }
+        return Optional.ofNullable(SqlHelper.getObject(log, baseMapper.selectList(queryWrapper)));
+    }
+
     @Override
     public Map<String, Object> getMap(Wrapper<T> queryWrapper) {
         return SqlHelper.getObject(log, baseMapper.selectMaps(queryWrapper));

+ 21 - 1
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/H2UserMapperTest.java

@@ -210,8 +210,28 @@ class H2UserMapperTest extends BaseTest {
     }
 
     @Test
-    void testCountLong(){
+    void testCountLong() {
         Long count = userMapper.selectCountLong();
         System.out.println(count);
     }
+
+    @Test
+    void testSelectOne() {
+        // 新增两条数据,测试selectOne方法
+        H2User h2User = new H2User();
+        h2User.setTestId(1L);
+        h2User.setName("测试1");
+
+        H2User h2User2 = new H2User();
+        h2User2.setTestId(2L);
+        h2User2.setName("测试1");
+
+        userMapper.insert(h2User);
+        userMapper.insert(h2User2);
+
+        LambdaQueryWrapper<H2User> wrapper = new LambdaQueryWrapper<>();
+//        H2User user = userMapper.selectOne(wrapper.eq(H2User::getName, "测试1"), false);
+        H2User user = userMapper.selectOne(wrapper.eq(H2User::getName, "测试1"), true);
+        log(user.toString());
+    }
 }

+ 52 - 27
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/H2UserTest.java

@@ -15,32 +15,6 @@
  */
 package com.baomidou.mybatisplus.test.h2;
 
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.util.AbstractList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.ibatis.plugin.Interceptor;
-import org.apache.ibatis.session.Configuration;
-import org.apache.ibatis.session.SqlSessionFactory;
-import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.MethodOrderer;
-import org.junit.jupiter.api.Order;
-import org.junit.jupiter.api.RepeatedTest;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestMethodOrder;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.dao.DataAccessException;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-import org.springframework.transaction.annotation.Transactional;
-
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -57,9 +31,23 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.test.h2.entity.H2User;
 import com.baomidou.mybatisplus.test.h2.enums.AgeEnum;
 import com.baomidou.mybatisplus.test.h2.service.IH2UserService;
-
 import net.sf.jsqlparser.parser.CCJSqlParserUtil;
 import net.sf.jsqlparser.statement.select.Select;
+import org.apache.ibatis.plugin.Interceptor;
+import org.apache.ibatis.session.Configuration;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory;
+import org.junit.jupiter.api.*;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataAccessException;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.*;
 
 /**
  * Mybatis Plus H2 Junit Test
@@ -656,4 +644,41 @@ class H2UserTest extends BaseTest {
         Assertions.assertTrue("Tomcat".equals(h2User.getName()));
     }
 
+    @Test
+    @Order(26)
+    void testServiceGetNullById() {
+        H2User user = new H2User(1L, "Evan");
+        userService.save(user);
+        Optional<H2User> optional = userService.getNonNullById(1L);
+        optional.ifPresent(u -> log(u.toString()));
+    }
+
+    @Test
+    @Order(27)
+    void testServiceGetNonNullOne() {
+        H2User user = new H2User(1L, "David");
+        userService.save(user);
+        Optional<H2User> optional = userService.getNonNullOne(
+            new LambdaQueryWrapper<H2User>().eq(H2User::getName, "David"));
+        optional.ifPresent(u -> log(u.toString()));
+    }
+
+    @Test
+    @Order(28)
+    void testServiceGetNonNullOneThrowEx() {
+        H2User user1 = new H2User(1L, "test1");
+        H2User user2 = new H2User(2L, "test1");
+        List<H2User> h2Users = Arrays.asList(user1, user2);
+        userService.saveBatch(h2Users);
+//        Optional<H2User> optional = userService.getNonNullOne(
+//            new LambdaQueryWrapper<H2User>().eq(H2User::getName, "test1"), true);
+        Optional<H2User> optional1 = userService.getNonNullOne(
+            new LambdaQueryWrapper<H2User>().eq(H2User::getName, "test1"), false);
+        Optional<H2User> optional2 = userService.getNonNullOne(
+            new LambdaQueryWrapper<H2User>().eq(H2User::getName, "test"), false);
+
+//        optional.ifPresent(u -> log(u.toString()));
+        optional1.ifPresent(u -> log(u.toString()));
+        optional2.ifPresent(u -> log(u.toString()));
+    }
 }