Java 一对多的数据怎样获取 可以提高性能 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
samples
V2EX    Java

Java 一对多的数据怎样获取 可以提高性能

  •  2
     
  •   samples 2018 年 8 月 31 日 3339 次点击
    这是一个创建于 2699 天前的主题,其中的信息可能已经有所发展或是发生改变。

    假设有两个对象 A,B 且是 1 对多的关系

    class A {

    int id; List<B> bs; 

    }

    class B {

    int a_id; String name; 

    }

    现在需要获取 A 的列表。

    1. 先获取 A 的列表,然后遍历通过 a_d 获取对应的 B 的列表,再 set 进 A,这样多次 io 较慢

    2. 用 sql join 将全部数据从数据库中取出,在内存中运算筛选封装。

    问下大佬们有没有更好的做法?先谢为敬

    8 条回复    2018-09-03 17:57:36 +08:00
    Eugene1024
        1
    Eugene1024  
       2018 年 8 月 31 日
    直接
    class C

    {
    int a_id;
    int b_id;
    String name;
    }
    前端显示 C,a_id 相同的合并,我的理解
    vjnjc
        2
    vjnjc  
       2018 年 8 月 31 日 via Android
    看你业务,假如不同 aid 对应的 blist 有交集的话,做一个 b 对象的缓存。就是已经读取过的 b 都还存在内存 cache 里,Hashmap ( id,b ) bcache=new Hashmap...
    mmdsun
        3
    mmdsun  
       2018 年 8 月 31 日 via Android
    mybatis collection 处理一对多配置好就直接查出来了 sql join。大表不方便连表可以用第一种。
    talen666
        4
    talen666  
       2018 年 8 月 31 日
    同意楼上 mybatis collection。
    TommyLemon
        5
    TommyLemon  
       2018 年 8 月 31 日
    JOIN 直接就解决了,只取需要的而不是全部数据,为啥还要在内存中(我的理解是应用层,而不是数据库引擎)筛选?
    ```sql
    SELECT A.*, B.* FROM A INNER JOIN B ON A.id = B.a_id WHERE {A 和 B 里面字段的条件}
    ```

    封装是肯定要在应用层搞定的,遍历 ResultSet 再封装 A,B 即可,A 很可能会有重复,所以最好用
    ```java
    Map<a_id, A> aMap = new LinkedHashMap<>();
    ```
    这样的结构,每次
    ```java
    A a = aMap.get(a_id);
    if (a == null) {
    a = new A();
    aMap.put(a_id, A);
    }
    a.setId(a_id);
    ...

    List<B> bs = a.getBs();
    if (bs == null) {
    bs = new ArrayList<>();
    a.setBs(bs);
    }

    B b = new B();
    b.setA_id(a_id);
    ...
    bs.add(b);
    ```

    如果你懒得封装,其实可以用 APIJSON 的自动化 API 帮你搞定:
    请求
    ```Javascript
    {
    "Moment": {},
    "Comment[]": { //把数组里面每项的 Comment 对象提取出来
    "Comment": {
    "momentId@": "Moment/id" // 引用赋值:Comment.momentId = Moment.id
    }
    }
    }
    ```
    返回:
    ```Javascript
    {
    "Moment": {
    "id": 12,
    "userId": 70793,
    "date": "2017-02-08 16:06:11.0",
    "content": "1111534034",
    "praiseUserIdList": [
    70793,
    93793
    ],
    "pictureList": [
    "http://static.oschina.net/uploads/img/201604/22172508_eGDi.jpg"
    ]
    },
    "Comment[]": [
    {
    "id": 162,
    "toId": 0,
    "userId": 93793,
    "momentId": 12,
    "date": "2017-03-06 13:03:45.0",
    "content": "This is a Content...-162"
    },
    {
    "id": 164,
    "toId": 0,
    "userId": 93793,
    "momentId": 12,
    "date": "2017-03-06 13:03:45.0",
    "content": "This is a Content...-164"
    },
    {
    "id": 172,
    "userId": 82001,
    "momentId": 12,
    "date": "2017-03-25 20:22:58.0",
    "content": "OK"
    }
    ],
    "code": 200,
    "msg": "success"
    }
    ```

    APIJSON 自动将前端传的 JSON 参数转为 SQL 语句执行并返回结果,
    期间自动校验权限、结构、内容,自动防 SQL 注入。

    通过自动化 API,前端可以定制任何数据、任何结构!
    大部分 HTTP 请求后端再也不用写接口了,更不用写文档了!
    前端再也不用和后端沟通接口或文档问题了!再也不会被文档各种错误坑了!
    后端再也不用为了兼容旧接口写新版接口和文档了!再也不会被前端随时随地没完没了地烦了!

    在线解析
    自动生成文档,清晰可读永远最新
    自动生成请求代码,支持 Android 和 iOS
    自动生成 JavaBean 文件,一键下载
    自动管理与测试接口用例,一键共享
    自动校验与格式化 JSON,支持高亮和收展

    对于前端
    不用再向后端催接口、求文档
    数据和结构完全定制,要啥有啥
    看请求知结果,所求即所得
    可一次获取任何数据、任何结构
    能去除重复数据,节省流量提高速度

    对于后端
    提供通用接口,大部分 API 不用再写
    自动生成文档,不用再编写和维护
    自动校验权限、自动管理版本、自动防 SQL 注入
    开放 API 无需划分版本,始终保持兼容
    支持增删改查、模糊搜索、正则匹配、远程函数等

    后端接口和文档自动化,前端(客户端) 定制返回 JSON 的数据和结构!
    创作不易,GitHub 右上角点 Star 支持下吧,谢谢^_^
    github.com/TommyLemon/APIJSON
    TommyLemon
        6
    TommyLemon  
       2018 年 8 月 31 日
    @TommyLemon 纯手打,有个错误,
    Map<a_id, A> aMap = new LinkedHashMap<>();
    要改成
    Map<Integer, A> aMap = new LinkedHashMap<>();
    TommyLemon
        7
    TommyLemon  
       2018 年 8 月 31 日
    @TommyLemon INNER JOIN 可实现多表条件组合,如果只是根据 A 取 B,应该改用 LEFT JOIN
    samples
        8
    samples  
    OP
       2018 年 9 月 3 日
    @Eugene1024 这样就是前端处理了,业务原因需要后端做处理。

    @TommyLemon 和第二种方法思路是一样的,APIJSON 我去看看学习下,谢谢喽
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     934 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 21:16 PVG 05:16 LAX 13:16 JFK 16:16
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86