dromara / easy-query

java/kotlin high performance lightweight solution for jdbc query,support oltp and olap query,一款java下面支持强类型、轻量级、高性能的ORM,致力于解决jdbc查询,拥有对象模型筛选、隐式子查询、隐式join
http://www.easy-query.com
Apache License 2.0
477 stars 48 forks source link

能否新增返回值对 Optional 封装的支持 #223

Closed bengbengbalabalabeng closed 1 month ago

bengbengbalabalabeng commented 1 month ago

模块:sql-core 涉及代码:EasyCollectionUtilAbstractClientQueryable 及其上游定义了 *OrNull() 方法的接口 新增:返回值对 Optional 类型封装的支持,在一些特定环境下用户业务逻辑使用 Optional.ofNullable().map().orElse() 链式操作会更简洁优雅些。

public class EasyCollectionUtil {
    // ignore other
    public static <TSource> TSource firstOrNull(Collection<TSource> source) {
        // ignore
    }

    // Optional support
    public static <TSource> Optional<TSource> firstOptional(Collection<TSource> source) {
        if (source == null || source.isEmpty()) {
            return Optional.empty();
        }
        return (source instanceof RandomAccess)
                ? Optional.ofNullable(((List<TSource>) source).get(0))
                : Optional.ofNullable(source.iterator().next());
    }
}

只是存在 *OrNull() 方法的上游接口确实不少,最终是否采纳烦请作者定夺。 😊

xuejmnet commented 1 month ago

@bengbengbalabalabeng 您的建议非常棒,easy-query其实为了性能其实很早就注意到了这一点包括直接提供用户迭代的方法

        Optional<Topic> topic = easyEntityQuery.queryable(Topic.class)
                .where(t -> {
                    t.id().eq("1");
                }).streamBy(s -> s.findFirst());
        boolean present = topic.isPresent();
        System.out.println(present);
        Topic topic1 = topic.orElse(null);

        List<Topic> topics = easyEntityQuery.queryable(Topic.class)
                .where(t -> {
                    t.id().eq("1");
                }).streamBy(s -> s.collect(Collectors.toList()));

        Map<String, Topic> mapWithMap = easyEntityQuery.queryable(Topic.class)
                .where(t -> {
                    t.id().eq("1");
                }).streamBy(s -> s.collect(Collectors.toMap(o -> o.getId(), o -> o, (k1, k2) -> k2)));

image

xuejmnet commented 1 month ago

毕竟直接提供迭代只需要O(n)而返回list后再迭代需要O(2n)所以eq已经提供了streamBy方法并且支持jdbc的fetchSize等处理当然具体需要看具体的jdbc驱动

xuejmnet commented 1 month ago

至于我提供的firstOrNull、firstNotNull、singleOrNull、singleNotNull、findOrNull、findNotNull是出于让用户可以直观地了解到api返回的结果和行为,比如我之前再用mybatis-plus的时候会对toOne很困惑,其实他是singleOrNull或者singleNotNull就是去获取一条并且是断言至多一条,当然也有受到微软的efcore的一点影响(我之前是搞c#的)因为c#那边的linq默认是firstOrDefault和first(默认没有就抛错我变成了firstNotNull)只是我再次基础上进行了api的名称的"增强"并不一定是最优解不过目前来讲使用者的反馈其实也还行

bengbengbalabalabeng commented 1 month ago

@xuejmnet 好的,多谢讲解,之前确实没有注意到有 streamBy api 已提供支持。