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

Spring 如何使实体中的关联项只序列化部分字段?

  •  
  •   ginakira ·
    Ginakira · 2023-02-26 15:50:10 +08:00 · 1290 次点击
    这是一个创建于 396 天前的主题,其中的信息可能已经有所发展或是发生改变。

    刚接触 SpringBoot 不久,想请教 V 友们一个问题:

    @Entity
    public class Task {
      // Other fields...
    
      @CreatedBy
      @ManyToOne
      @JoinColumn(name = "created_by", referencedColumnName = "id")
      private Integer createdBy;
    }
    
    @Entity
    public class User {
      private Integer id;
      private String nickname;
      
      // Don't want to show only in Task
      private String email;
      // ...
    }
    
    

    实体 Task 多对一关联了实体 User ,除了添加@JsonIgnore的方式,如何让 Task 作为 ResponseBody 序列化时忽略 User 中的某些字段?

    不想使用@JsonIgnore注解的原因是还想在其他的接口中返回 User 的全部字段,还望 V 友们不吝赐教。

    10 条回复    2023-11-02 18:03:02 +08:00
    wenbinwu
        1
    wenbinwu  
       2023-02-26 16:06:36 +08:00   ❤️ 1
    弄两个 User class?
    ginakira
        2
    ginakira  
    OP
       2023-02-26 16:20:32 +08:00
    @wenbinwu 正常通过 Repository 查询部分字段可以用 Projection 解决,但这种在关联字段里的就不知道怎么弄了……如果用两个 User class 的话该如何映射到真正的 User 表呢
    arjen
        3
    arjen  
       2023-02-26 16:22:18 +08:00   ❤️ 1
    SQL 写 JOIN ,然后弄个 DTO 对象
    thinkershare
        4
    thinkershare  
       2023-02-26 16:24:38 +08:00   ❤️ 1
    本来就不应该将你的实体暴露给最终用户,肯定是给不同的接口按照不同使用需求添加 Dto 哈。
    然后找个 Mapper 实现自动映射,如果有必要甚至可用上 GraphQL 或者其它 BFF 层。
    在高级一点,将查询和命令分离,上 CQRS.
    lybcyd
        5
    lybcyd  
       2023-02-26 18:10:25 +08:00 via Android   ❤️ 1
    根据你的需要,额外定义 DTO ,只包含你想返回的字段,然后把查询出来的数据拼装进去,而不是直接返回实体类。
    ginakira
        6
    ginakira  
    OP
       2023-02-26 19:43:48 +08:00
    mmdsun
        7
    mmdsun  
       2023-02-26 21:08:55 +08:00   ❤️ 2
    "不想使用 @JsonIgnore 注解的原因是还想在其他的接口中返回 User 的全部字段"

    这个需求你可以用 @JsonView ,把这个注解加到字段上

    @JsonView(SimpleView.class)
    private String username;

    @JsonView(DetailView.class)
    private String password;

    SimpleView 、DetailView.class 其实就是一个空接口,可有有继承的关系。
    比如 intreface DetailView extends SimpleView {}

    然后再你控制器上加上你这个接口, 这样你可以精确控制 哪些接口显示哪些字段了
    @GetMapping
    @JsonView(UserProfile.PublicView.class)
    ginakira
        8
    ginakira  
    OP
       2023-02-26 22:31:54 +08:00
    @mmdsun 感谢!!!
    cryboy007
        9
    cryboy007  
       147 天前
    @mmdsun 如果包装类如 PageInfo 这种,怎么使用
    mmdsun
        10
    mmdsun  
       147 天前
    @cryboy007
    PageInfo 是分页框架提供的不能改源码?那你自己新建一个类继承一下就好。
    另外你 PageInfo 里面装的内容比如放了 Apple 类数据也是要加 @JsonView 注解的。

    @Data
    @JsonView(PageView.PageViewAll.class)
    public class PageInfoWithJsonView<T> extends PageInfo <T> {


    public interface PageViewAll {

    }
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   953 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 21:13 · PVG 05:13 · LAX 14:13 · JFK 17:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.