V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
laaaaaa
V2EX  ›  Java

咨询一个关于 springboot 集成 mybatis-plus 的查询返回问题?

  •  
  •   laaaaaa · 2023-12-26 16:11:39 +08:00 · 2059 次点击
    这是一个创建于 367 天前的主题,其中的信息可能已经有所发展或是发生改变。

    环境

    jdk8, spirngboot ,mysql,mybatis ,mybatis-plus
    

    问题

    例如:mysql 一张表,a,b,c,d,e,f,g 这几个字段,然后有一个实体类 demoEntity 跟数据库表对应
    
    需求: 我现在一个接口,我只需要 a,b,c 三个字段就足够了,然后我返回给前端,也只想返回这三个,如果不用 mybatis-plus 我可以把 a b c 封装成一个 vo ,mapper 里直接返回 vo , 如果用 Mybatis-plus , 可以先用实体类接到数据,然后再 set 给 vo ,这太鸡肋了,还有就是 封装一下 mp ,让他能够兼容 vo 返回,也可以; 但是我现在又有一个接口 只需要 d,e,f,g 这四个字段,那么我就得在封装个 vo,这时候 之前封装的 mp 返回的 vo 就不能用了,就得在建一个 server 类 在去继承另个 vo ;
    
    解决:我能想的就是 用一个 vo ,但是接口返回可能会存在冗余字段,不想存在,就得手写 sql 查,完全用不到了 mp ,我想问问大家怎么解决这种问题
    

    问题 2

    例如 我同样一个 sql:
    
    select * from user where rid in (1,2,3,4....); rid 可能有上万个,但 rid 不是主键;
    
    然后我用 mp 手写一个批量查方法
    
    LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
    lambdaQueryWrapper.in(User::getRid, Arrays.stream(new Integer[]{1, 2, 3, 4, ....}));
    
    userMapper.list(lambdaQueryWrapper);
    
    我执行下来发现,打印的 sql 是一样的,但是 mp 的查询时间就很快; 这是为啥;
    
    大家在去批量差一个表里的非主键字段的时候 会用什么方法提高效率,mysql 用 in 应该不会走索引吧
    

    问题 3

    spring cloud 项目,例如有 A B 两个服务,每个服务有自己的库;
    
    需求: 我现在 A 服务里一个接口,我需要关联查 B 服务的数据,并且合并以后分页 按照 B 库里的时间字段倒序 返回,这类大家会怎么做;
    
    我百度搜了很多方法,用远程调用,拿到数据在合并,或者用 mq 解耦,或者数据仓库, 是能解决,我想问问大家都是在用什么方法?
    
    20 条回复    2023-12-27 15:11:32 +08:00
    JYii
        1
    JYii  
       2023-12-26 16:25:31 +08:00
    1.orm 框架层统一返回数据库对应的 model ,想转成什么 o 请在其他层去做
    2.输出 sql 相同的话,请考虑其他因素,将 sql 单独执行试试。in 是否走索引,要看字段是否上索引、字段区分度,以及不要超出 sql 限制
    3.服务拆分后,需要联合查询,要么上 es 等中间件;要么把服务合并,以证明两个服务的紧密程度和当初拆分的人是个 sb
    chendy
        2
    chendy  
       2023-12-26 16:27:38 +08:00
    问题 1:
    a. 不管,除非是很大的字段否则就返回,爱用不用
    b. service 以下不动,controller 层加类 配合 mapstruct 之类 复制
    c. service 以下不动,controller 做个方法,反射+字段名返回需要字段的 map

    问题 2:确认一下 SQL 到底是否一样,走不走索引建议自己 explain 以下

    问题 3:
    a. 把服务 A 服务 B 捏一起
    b. 服务 A 直接访问服务 B 的数据库
    c. 服务 A 定时把服务 B 的数据库同步到自己的数据库
    laaaaaa
        3
    laaaaaa  
    OP
       2023-12-26 16:30:36 +08:00
    @JYii 1. 返回数据库对应的 model ,我在往 0 要的去 set ,这不是浪费资源?
    3. 举个场景吧: 一个 A 服务,存放用户信息, 一个 B 服务,存放用户的测量数据, 测量数据来源是硬件,接口秒级请求,按照现在,A 服务 一个实例, 主库,B 服务 5 个实力,3 个从库, 现在查询一条测量数据 就需要带着用户信息返回, 如果按照你的思路不应该拆的话 该如何改进一下
    chendy
        4
    chendy  
       2023-12-26 16:48:28 +08:00
    @laaaaaa 在 B 服务里存用户数据,然后直接查 B
    wangxin3
        5
    wangxin3  
       2023-12-26 16:52:04 +08:00
    问题 1:我也是不管,除非敏感字段,否则全部返回
    问题 2:考虑下 mybatis 的一二级缓存。in 在数据少的情况下也是走索引的,具体场景具体分析。
    问题 3:考虑谁是主数据,一般用主数据做分页,left join 的数据再根据主数据的 id 集合去查,然后拿到数据组装完在排序。
    m2276699
        6
    m2276699  
       2023-12-26 16:52:04 +08:00
    mp 本来就有查询指定字段的方法
    wangxin3
        7
    wangxin3  
       2023-12-26 16:56:45 +08:00
    @wangxin3 补充下问题 1:可以用 mp 自带的查询指定字段的 api+json 序列化过滤 null 值完成你想要的效果。
    nerkeler
        8
    nerkeler  
       2023-12-26 17:01:13 +08:00
    问题 1 JsonIgnore 忽略掉 最方便,多个返回公用一个的话只能复制一份 ,或者抽一个公共的继承下来,单独处理
    menmen995
        9
    menmen995  
       2023-12-26 18:00:49 +08:00
    问题 1 ,graphql
    nice2cu
        10
    nice2cu  
       2023-12-26 19:40:59 +08:00
    问题 2 对于 in 大集合 需要分段分批次去拿的 最好不要 in 大集合一下去查
    nice2cu
        11
    nice2cu  
       2023-12-26 19:42:43 +08:00
    问题 1 mybatis 的话 可以把 查询列当 参数传进去的 想要啥就自己穿哪些列,不传就*, plus 没咋用过,看下可不可类似
    nice2cu
        12
    nice2cu  
       2023-12-26 19:45:40 +08:00
    问题 3 没看懂 都不同库了 只能内存排序吧。
    godleon
        13
    godleon  
       2023-12-26 20:24:19 +08:00
    @menmen995 有上过生产吗,好用吗
    chippai
        14
    chippai  
       2023-12-26 20:28:48 +08:00
    问题 1:new LambdaQueryWrapper<DemoEntity>().select(DemoEntity::getA,DemoEntity::getB, DemoEntity::getC).eq(DemoEntity::getId, id));
    问题 2:in 走不走索引,取决 in 的字段是不是索引,有需求加索引就行了。
    siweipancc
        15
    siweipancc  
       2023-12-26 21:47:00 +08:00 via iPhone
    前段定制,后端查询集合,jackson 忽略 null 值。不建议用这个,除非你有流量限制。
    以及,plus 是支持的,看下 api
    changdy
        16
    changdy  
       2023-12-26 22:33:58 +08:00
    1 ,这个看你自己
    2 ,有些信息没理解, mysql in 可以走索引
    3 ,数据量小随便折腾,数据量大 走数仓. 任何时候都不应该 非预期的大数据 join
    ps:严格一点 你这个理解程度我觉得不适合做微服务..
    laaaaaa
        17
    laaaaaa  
    OP
       2023-12-27 09:06:09 +08:00
    @siweipancc 确实流量限制原因,才想到这个特别是针对 app 端的时候,流量更得能少就少
    RedBeanIce
        18
    RedBeanIce  
       2023-12-27 09:53:45 +08:00
    等你再多写一点代码,,你会发现
    问题 1 简直是屎山。
    问题 2 没仔细关注。
    问题 3 ,没有看清楚问题。。上面的回复应该有一些解决办法。
    litchinn
        19
    litchinn  
       2023-12-27 10:12:59 +08:00
    1. mapstruct 转换,如果请求量大到影响业务,应该专门优化,一般来说这是少数接口
    2. 分批次
    3. 我这是拿到数据后再合并,具体方案得看业务
    menmen995
        20
    menmen995  
       2023-12-27 15:11:32 +08:00
    @godleon 可以用,就是有特定风格的语法
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2019 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 00:30 · PVG 08:30 · LAX 16:30 · JFK 19:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.