【问题标题】:How to manage several entities with JPA?如何使用 JPA 管理多个实体?
【发布时间】:2019-07-09 20:34:37
【问题描述】:

上下文

我正在尝试创建一个简单的 API 来学习 Spring Boot 和 JPA。信息存储在 H2 数据库中。

我有 2 个实体:missionuser

几个用户被分配到一个任务。并且用户可以被分配到不同的任务。

所以,我的班级Mission 有一个属性private ArrayList<User> users;

目标

我的目标是创建一些请求:

  • (GET 请求)IP/missions/123456/users:获取分配给任务的所有用户123456
  • (PUT 请求)IP/missions/456789:将用户分配给任务456789

所以,绑定了两个实体。

有问题

但我不知道如何存储/绑定与missionuser 相关的信息。好的方法是使用Assignements(id_user, id_mission) 的方案创建一个“关联表”?

感谢您的帮助!

编辑 1:代码

实体任务

@Entity
public class Mission{

    @Id
    private String id;
    private String name;
    private Date start;
    private Date end;
    private ArrayList<User> users;
    private int status;

    public Mission() {
    }

    public Mission(String name, Date start, Date end) {
        this.name = name;
        this.start = start;
        this.end = end;
        this.status = 0;
    }

    // getters and setters
}

实体用户

@Entity
public class User {

    @Id
    private String id;
    private String name;

    public User() {
    }

    public User(String name) {
        this.name = name;
    }

    // getters and setters
}

SQL

我使用 SQL 脚本。目前,脚本如下所示:

INSERT INTO mission (id, name, start, end, status) VALUES ('de7d9052-4961-4b4f-938a-3cd12cbe1f82', 'mission 1', '2019-02-11', '2019-02-13', 0)
INSERT INTO mission (id, name, start, end, status) VALUES ('425e7701-02c6-4de3-9333-a2459eece1c8', 'mission 2', '2019-02-10', '2019-02-15', 0)

编辑 2:新代码(使用 @ManyToMany)

实体

@Entity
public class Mission {

    @Id
    private String missionid;
    private String namemission;
    private Date start;
    private Date end;
    @ManyToMany
    @JoinTable(name = "mission_user",
        joinColumns = @JoinColumn(name = "missionid"),
        inverseJoinColumns = @JoinColumn(name = "userid")
    )
    private Set<User> users = new HashSet<>();
    private int status;

    public Mission() {}

    public Mission(String name, Date start, Date end) {
        this.namemission = name;
        this.start = start;
        this.end = end;
        this.status = 0;
    }
}

@Entity
public class User {

    @Id
    private String iduser;
    private String nomuser;
    @ManyToMany(mappedBy = "users")
    private Set<Mission> missions = new HashSet<>();

    public User() {}

    public User(String nom) {
        this.nomuser = nom;
    }

}

存储库

@RepositoryRestResource(collectionResourceRel = "mission")
public interface MissionResource extends JpaRepository<Mission, String> {
    ...
}

@RepositoryRestResource(collectionResourceRel = "user")
public interface UserResource extends JpaRepository<User, String> {
    ...
}

休息控制器

@RestController
@RequestMapping(value = "/missions", produces = MediaType.APPLICATION_JSON_VALUE)
@ExposesResourceFor(Mission.class)
public class MissionRepresentation {
    private final MissionResource missionResource;
    private final UserResource userResource;

    public MissionRepresentation(MissionResource missionResource, UserResource userResource) {
        this.missionResource = missionResource;
        this.userResource = userResource;
    }

    // mapping
}

【问题讨论】:

  • 关联表有什么难点?
  • 这不难,但我不知道使用关联表是否是使用这些工具解决问题的最佳方法。
  • 嗯,在我看来,它就像一个多对多关联,因此这似乎是正确的方法(对于 rdbms,因为您使用的是 h2 和 jpa 似乎相关;对于 nosql,答案会有所不同)。
  • 是的,我不使用 nosql。因此,您向我确认,使用 JPA 持久化集合/列表的唯一方法是使用关联表?注释或其他东西不允许我们更简单地做到这一点?
  • 向我们展示一个尝试。代码在哪里?

标签: java sql spring set spring-data


【解决方案1】:

正如您所说,最好的方法是实现一个连接表。就像这样:

create table mission_user (
    mission_id int,
    user_id int,
    primary key (mission_id, user_id)
)

然后一个@ManyToMany 使用这个表作为映射或像MissionUser 这样的实体,并将UserMission 作为@OneToMany 映射到它。

【讨论】:

  • 好的,谢谢。所以我必须删除属性ArrayList&lt;User&gt; users?当 URL IP/missions/123456/users 被调用时,我通过mission_user 表上的请求获取与此任务相关的用户?
  • 如果你使用连接表,那么是的,Users 的列表应该替换为MissionUser 的列表。
  • 抱歉,我不明白为什么需要MissionUsers 列表。
  • 如我所说,您也可以使用@JoinTable 代替
  • 最好是运行它:) 它不应该是private Set&lt;Mission&gt; 而不是private Set&lt;Tache&gt; 吗?除此之外似乎还可以
【解决方案2】:

任务类将具有:

@Entity
public class Mission {
...
    @ManyToMany(mappedBy = "missions")
    private List<User> users;
...
}

和用户类将有:

@Entity
public class User {
...

    @ManyToMany(mappedBy = "users")
    private List<Mission> missions;
...
}

这将在您的数据库中创建一个名称类似于:missions_uesrs 的表,并且它仅包含missionId 和 userId 作为列。

【讨论】:

    猜你喜欢
    • 2017-03-22
    • 1970-01-01
    • 2014-07-16
    • 1970-01-01
    • 1970-01-01
    • 2016-02-10
    • 2015-01-22
    • 2012-06-28
    • 2020-01-24
    相关资源
    最近更新 更多