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

关于 mybatis 和通用 mapper 的一些疑问

  •  1
     
  •   jinx930621 · 2019-03-21 13:25:14 +08:00 · 5548 次点击
    这是一个创建于 2108 天前的主题,其中的信息可能已经有所发展或是发生改变。

    小弟接触 mybatis 等东西没多久,最近在看一些通用的 mapper,比如 通用 Mapper和 mybatis-plus,有几个问题想请教各位大佬:

    1. 在查询列表和查询详情时返回值是有区别的,需要写两个 entity 来对应吗?
    2. 比如查询文章时,文章作者在库中保存的是用户 Id,是用 join 来联表查还是单表查询获得到用户 id,再去单表查用户更好呢?如果用 join,那又要去手写 sql 了,这些通用 mapper 意义又不大了。

    还没有看过 jpa,听说是个更好的选择?

    11 条回复    2019-03-22 21:49:40 +08:00
    lhx2008
        1
    lhx2008  
       2019-03-21 13:27:36 +08:00 via Android
    通用 mapper 一般是不支持自动 join 的,一般都是自己写,如果懒得写,用 jpa 吧
    yinzhili
        2
    yinzhili  
       2019-03-21 16:41:18 +08:00
    通用 mapper 解决的是单表的增删改查问题。不过通用 mapper 依然支持普通的 xml 映射语句,不冲突。
    第一个问题很简单:查询列表的时候返回值是 List<T>,查询详情返回值是 T
    JPA 也解决不了多表 join 的问题,最终还是要回到手写 SQL 语句的路上
    yahz
        3
    yahz  
       2019-03-21 16:45:55 +08:00
    复杂查询手写吧,避免不了。通用 mapper 是节省重复工作的,复杂查询一般不是重复性的。
    TommyLemon
        4
    TommyLemon  
       2019-03-21 16:49:00 +08:00   ❤️ 1
    TommyLemon
        5
    TommyLemon  
       2019-03-21 16:53:49 +08:00
    可以用 APIJSON 的自动化 JOIN,后端不用写一行代码,前端传一个 join 键值对就好。

    例子:
    前端传入一个 JSON
    ```js
    {
    "[]": {
    "count": 10, // LIMIT 10
    "join": "</User/id@", // Comment LEFT JOIN User
    "Comment": {
    "content~": "a", // content REGEXP 'a'
    "@group": "momentId", //GROUP BY momentId
    "@order": "date+" //ORDER BY date ASC
    },
    "User": {
    "@column":"id,name", // SELECT id,name
    "id@": "/Comment/userId" // ON User.id = Comment.userId
    }
    }
    }
    ```
    APIJSONORM 自动生成
    ```sql
    SELECT `Comment`.*, `User`.`id`, `User`.`name` FROM `sys`.`Comment` AS `Comment` WHERE `Comment`.`content` REGEXP 'a'
    LEFT JOIN (SELECT `id`, `name` FROM `sys`.`apijson_user`) AS `User` ON `User`.`id` = `Comment`.`userId`
    GROUP BY `Comment`.`momentId` ORDER BY `Comment`.`date` ASC LIMIT 10 OFFSET 0
    ```

    说明:
    ④ "join":"&/Table0/key0@,</Table1/key1@"
    多表连接方式:
    "<" - LEFT JOIN
    ">" - RIGHT JOIN
    "&" - INNER JOIN
    "|" - FULL JOIN
    "!" - OUTTER JOIN
    "@" - APP JOIN
    其中 @ APP JOIN 为应用层连表,会从已查出的主表里取得所有副表 key@ 关联的主表内的 refKey 作为一个数组 refKeys: [value0, value1...],然后把原来副表 count 次查询 key=$refKey 的 SQL 用 key IN($refKeys) 的方式合并为一条 SQL 来优化性能;
    其它 JOIN 都是 SQL JOIN,具体功能和 MySQL,PostgreSQL 等数据库的 JOIN 一一对应,
    "ViceTable":{ "key@:".../MainTable/refKey" }
    会对应生成
    MainTable ... JOIN ViceTable ON ViceTable.key=MainTable.refKey。


    已有 5.3K Star, 并已入选 码云最有价值项目,GitHub 右上角点 Star 支持下吧^_^
    https://github.com/TommyLemon/APIJSON
    anyele
        6
    anyele  
       2019-03-21 18:46:23 +08:00 via Android   ❤️ 1
    @TommyLemon 真的可怕,老哥又来了,现在是直接发图片
    jinx930621
        7
    jinx930621  
    OP
       2019-03-21 18:51:44 +08:00
    @yinzhili
    @yahz 结合部分业务之后感觉单表操作好像并没有那么多,引入通用 mapper 的的意义没有之前想的那么大了。

    @TommyLemon 这个看起来好厉害!之前听说过 GraphQL,但又好像不一样。
    TommyLemon
        8
    TommyLemon  
       2019-03-21 23:24:55 +08:00
    @jinx930621 GraphQL 可做不到这些,全都要手写的,除了过滤字段,而且只能在网络层面自动过滤,做不到像 APIJSON 一样直接在数据库层面自动过滤。
    APIJSON 与 GraphQL 全方位对比
    https://juejin.im/post/5ae80edd51882567277433cf
    TommyLemon
        9
    TommyLemon  
       2019-03-21 23:28:38 +08:00
    @anyele 你看下 #7 的回复,人家就需要扩展思路,甚至能解决问题( APIJSON 是能达到楼主想要省去大量代码的效果的)的方案,就因为你们自己的情绪还不让人合法合规地发言了?
    TommyLemon
        10
    TommyLemon  
       2019-03-21 23:31:06 +08:00
    如果有什么疑问,可以看下这个帖子,评论里的各种问题都一一解答了。

    自动化 ORM 库 APIJSON 3.4.9 发布,已 5K Star 入选码云最具价值项目
    https://www.v2ex.com/t/544424
    mmdsun
        11
    mmdsun  
       2019-03-22 21:49:40 +08:00 via Android
    同问。如果需要两表连表查询,SQL 写在 a 表 mapper 里面还是 b 表 mapper 里面?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   950 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 20:52 · PVG 04:52 · LAX 12:52 · JFK 15:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.