数据持久化模式和使用Springboot/hibernate处理关系

j13ufse2  于 2023-03-29  发布在  Spring
关注(0)|答案(2)|浏览(148)

我正在尝试使用springboot来理解持久化和数据检索。

用户可以拥有多个权限(或权限,用于授权)

一个用户可以有一个UserProfile(用户名、生日等),用于存储用户的不同信息
典型的springboot CRUD示例会建议为每个实体创建实体和存储库,并在实体上使用**@OneToOne**,@OneToMany等关系,但这种方法不是混合了RepositoryAggregate模式,这会导致非常难以维护的代码吗?
在一个实际的springboot应用程序中,以一种简单且可维护的方式管理持久性的最佳实践/模式是什么?

编辑

链接到这篇文章,它明确指出,混合存储库/聚合方法可能会导致难以维护代码:Spring boot: How to persist one-to-many relation separately using Repository
另外,根据我的个人经验,我看到了Springboot应用程序管理实体而不使用关系注解(@Onetone、OnetoMany...等)的例子,这类似于Repository模式。
我对关系注解的主要问题是,它们往往很棘手,需要更多的样板代码来使它们工作,并避免诸如N+1查询,无限序列化递归和双向关系等问题。你对此有什么想法,现在有没有更直接的方法来管理Springboot应用程序中的持久化?

l2osamch

l2osamch1#

这里有一个你可以创建的示例设计;
第一个User实体;

@Entity
@Data
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, unique = true)
    private String email;

    @Column(nullable = false)
    private String password;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private Set<UserProfile> userProfiles = new HashSet<>();

    @ManyToMany
    @JoinTable(name = "user_authority",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "authority_id"))
    private Set<Authority> authorities = new HashSet<>();

}

UserProfile实体;

@Entity
@Data
public class UserProfile {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String username;

    @Column(nullable = false)
    private LocalDate birthdate;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;
}

最后一个实体是Authority;

@Entity
@Data
public class Authority {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, unique = true)
    private String name;

    @ManyToMany(mappedBy = "authorities")
    private Set<User> users = new HashSet<>();
}

然后,您可以从这些实体创建存储库类和服务层。OneToManyUserUserProfile之间的关系,其中UserProfile中的user字段用作外键,以及UserAuthority之间的ManyToMany关系。使用名为user_authority的连接表管理User中profiles字段上的关系. CascadeType.ALL,以确保删除用户时,所有关联的UserProfiles也将被删除。

e4yzc0pl

e4yzc0pl2#

通常在Sping Boot 中,您会为每个实体创建存储库,并且实体通过JPA注解连接。这会创建相当干净的架构-您可以从给定的存储库中获取数据以获得具体的实体。
当然,这些实体可以有关系,你可以用join立即获取它们,你可以用FetchType.LAZY以一种惰性的方式获取它们,你可以合并几个仓库的调用来获得所需的数据,然后简单的实体可以变成这样的聚合。

相关问题