V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
LoremIpSum
V2EX  ›  程序员

Java 有什么实践或设计模式可以用来减少硬编码?

  •  
  •   LoremIpSum · 2020-05-15 10:48:09 +08:00 · 2727 次点击
    这是一个创建于 1686 天前的主题,其中的信息可能已经有所发展或是发生改变。

    C#:

    _userEventData.Collection().Aggregate()
                    .Match(p => p.CreateTime >= dateTimePeriod.StartTime && p.CreateTime < dateTimePeriod.EndTime)
                    .SortByDescending(p => p.CreateTime)
                    .Group(p => p.UserId, group => new UserDto()
                    {
                        UserId = group.Key,
                        Total = group.Sum(g => g.Value)
                    })
                    .ToListAsync();
    

    Java:

    Aggregation agg = newAggregation(UserEvent.class,
                    match(where("createTime").gte(period.getStartTime()).lte(period.getEndTime())),
                    group("userId").addToSet("userId").as("userId").sum("value").as("total"),
                    sort(Sort.Direction.DESC, "createTime"));
            Flux<UserDto> items = reactiveMongoTemplate.aggregate(agg, "UserEvent",
            UserDto.class);
    

    上面两端代码,实现一模一样的功能,一段是用 c#写的,一段是用 java 写的,用 java 对象的字段名需要硬编码,用 c#则不需要,如果工程中有大量类似于上面这种查询代码,后续很难重构,java 中有没有什么方法,当字段名写错的时候就能够在编译器发现?

    14 条回复    2020-06-03 12:44:09 +08:00
    Jrue0011
        1
    Jrue0011  
       2020-05-15 10:56:35 +08:00
    这个得你用的 Aggregation 支持,然后使用 java8 方法引用

    比如 group("userId"),如果它提供了 group(Function<? super T, ? extends K> func)这样的接口,你就可以写成 group(User::getUserId)或者 group(u -> u.userId)这样的形式
    wysnylc
        2
    wysnylc  
       2020-05-15 11:31:03 +08:00
    @Jrue0011 #1 完美回答
    xizismile
        3
    xizismile  
       2020-05-15 11:39:38 +08:00 via Android
    java 也能写出 c#那样子啊,用流式 api 配合 lambda 表达式
    yalin
        4
    yalin  
       2020-05-15 11:41:31 +08:00
    传说中的微服务配置中心
    aguesuka
        5
    aguesuka  
       2020-05-15 12:01:46 +08:00 via Android
    java.util.Collectors.groupingBy
    aguesuka
        6
    aguesuka  
       2020-05-15 12:24:51 +08:00 via Android
    public interface UserEvent {
    LocalDateTime getCreateTime();

    BigDecimal getValue();

    String getUserId();

    static Map<String, BigDecimal> sumValue(Collection<? extends UserEvent> userEvents, LocalDateTime stateDate, LocalDateTime endDate) {
    return userEvents.stream()
    .filter(userEvent -> !userEvent.getCreateTime().isBefore(stateDate) &&
    !userEvent.getCreateTime().isAfter(endDate))
    .sorted(Comparator.comparing(UserEvent::getCreateTime).reversed())
    .collect(Collectors.toMap(UserEvent::getUserId, UserEvent::getValue, BigDecimal::add));
    }
    }
    用 stream 是这么写。
    不过如果是用这样的形式生成 sql 是做不到的,因为::表达式拿不到方法的元信息
    LoremIpSum
        7
    LoremIpSum  
    OP
       2020-05-15 16:21:26 +08:00
    @Jrue0011 这个是 mongodb 的库,mongodb 貌似没有提供基于 stream api 的聚合查询接口
    kaedea
        8
    kaedea  
       2020-05-15 16:23:13 +08:00 via Android
    CAP 模式了解一下
    LoremIpSum
        9
    LoremIpSum  
    OP
       2020-05-15 16:23:25 +08:00
    想请问下大佬,mongodb 有没有基于 stream api 的聚合查询接口?
    Jrue0011
        10
    Jrue0011  
       2020-05-15 17:18:17 +08:00
    @LoremIpSum 用的应该是 Spring Data Mongodb Reactive ?看官方文档里与 QueryDSL 集成后貌似能实现 IDE 级别的检查,不过需要引入 QueryDSL 的库,需要评估下使用和维护的成本。。。

    spring data mongodb#type-safe query methods
    https://docs.spring.io/spring-data/mongodb/docs/3.0.0.RELEASE/reference/html/#mongodb.reactive.repositories.queries.type-safe

    querydsl#quering mongodb
    http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s07.html
    CoderGeek
        11
    CoderGeek  
       2020-05-15 17:22:47 +08:00
    有些新的 Query 方法类都可以的
    ai277014717
        12
    ai277014717  
       2020-05-15 17:23:18 +08:00
    万能 xml
    Jrue0011
        13
    Jrue0011  
       2020-05-15 17:35:44 +08:00
    @Jrue0011 #10 没用过 mongodb 和 querydsl,不知道 querydsl 支持不支持 mongodb 的聚合。。
    aguesuka
        14
    aguesuka  
       2020-06-03 12:44:09 +08:00 via Android
    @aguesuka 我错了,先定义一个函数接口,继承 Serializlable 接口。然后 wirte 成 SerializedLambda 。这样就能拿到元信息了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5645 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 03:23 · PVG 11:23 · LAX 19:23 · JFK 22:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.