Moa*_*did 4 sql spring hibernate jpa spring-data
我有三张桌子,我想加入它们,这让我发疯。
表:任务 项目 用户
它们之间都具有多对多关系:就像项目有多个用户,反之亦然,任务有多个用户,反之亦然,项目和用户也是如此。
我正在尝试找到一种在 JPA 和 Hibernate 中实现这一点的方法,我有 2 个选择: ** 1 ** 像这样加入 3 个实体:
项目:
@ManyToMany(fetch = FetchType.EAGER,
cascade =
{
CascadeType.DETACH,
CascadeType.MERGE,
CascadeType.REFRESH,
CascadeType.PERSIST
},
targetEntity = User.class)
@JoinTable(name = "Collaborators",
joinColumns = @JoinColumn(name = "ProjectFk", referencedColumnName = "id", updatable=false, nullable=false),
inverseJoinColumns = @JoinColumn(name = "UserFk", referencedColumnName = "id", updatable=false, nullable=false))
private Set<User> users = new HashSet<>();
Run Code Online (Sandbox Code Playgroud)
用户:
@ManyToMany(fetch = FetchType.EAGER,
cascade =
{
CascadeType.DETACH,
CascadeType.MERGE,
CascadeType.REFRESH,
CascadeType.PERSIST
},
targetEntity = Project.class)
@JoinTable(name = "Collaborators",
joinColumns = @JoinColumn(name = "UserFk", referencedColumnName = "id", updatable=false, nullable=false),
inverseJoinColumns = @JoinColumn(name = "ProjectFk", referencedColumnName = "id", updatable=false, nullable=false))
private Set<Project> projects = new HashSet<>();
Run Code Online (Sandbox Code Playgroud)
任务:
@ManyToMany(fetch = FetchType.EAGER,
cascade =
{
CascadeType.DETACH,
CascadeType.MERGE,
CascadeType.REFRESH,
CascadeType.PERSIST
},
targetEntity = User.class)
@JoinTable(name = "Collaborators",
joinColumns = @JoinColumn(name = "TaskFk", referencedColumnName = "id", updatable=false, nullable=false),
inverseJoinColumns = @JoinColumn(name = "ProjectFk", referencedColumnName = "id", updatable=false, nullable=false))
@MapKeyJoinColumn(name = "User_id")
@ElementCollection
private Map<Project, User> projectUserMap = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)
但这里似乎不起作用
2:创建第四个实体并将其命名为Collaborator,然后尝试找到实现此 SQL 查询的方法:
select * from (
select user.id, Project.id, Task.id
inner join Project on user.join_key = Project.join_key
inner join Task on task.join_key = = Project.join_key
) collaborator
Run Code Online (Sandbox Code Playgroud)
任何帮助将不胜感激。谢谢。
应该像下面这样实现:
项目类
@Entity
public class Project extends ABaseEntity{
private Set<User> users = new HashSet<>();
@ManyToMany
@JoinTable(name = "Collaborators",
joinColumns = @JoinColumn(name = "Project_ID", referencedColumnName = "id", updatable=false, nullable=false),
inverseJoinColumns = @JoinColumn(name = "User_ID", referencedColumnName = "id", updatable=false, nullable=false))
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
}
Run Code Online (Sandbox Code Playgroud)
用户等级
@Entity
@Table(name = "EMA_USER")
public class User extends ABaseEntity {
private Set<Project> projects = new HashSet<>();
@ManyToMany(fetch = FetchType.EAGER,
cascade = CascadeType.ALL,
targetEntity = Project.class)
@JoinTable(name = "Collaborators",
joinColumns = @JoinColumn(name = "User_ID", referencedColumnName = "id", updatable = false, nullable = false),
inverseJoinColumns = @JoinColumn(name = "Project_ID", referencedColumnName = "id", updatable = false, nullable = false))
public Set<Project> getProjects() {
return projects;
}
public void setProjects(Set<Project> projects) {
this.projects = projects;
}
}
Run Code Online (Sandbox Code Playgroud)
任务类
@Entity
public class Task extends ABaseEntity{
private Map<Project, User> projectUserMap = new HashMap<>();
@ManyToMany(
fetch = FetchType.EAGER,
cascade = CascadeType.ALL
)
@JoinTable(
name = "Collaborators",
joinColumns = @JoinColumn(name = "Task_ID", referencedColumnName = "id", updatable = false, nullable = false),
inverseJoinColumns = @JoinColumn(name = "User_ID", referencedColumnName = "id", updatable = false, nullable = false)
)
@MapKeyJoinColumn(name = "Project_Id")
public Map<Project, User> getProjectUserMap() {
return projectUserMap;
}
public void setProjectUserMap(Map<Project, User> projectUserMap) {
this.projectUserMap = projectUserMap;
}
}
Run Code Online (Sandbox Code Playgroud)
您的任务类别有什么问题:
@MapKeyJoinColumn(name = "User_id")
Run Code Online (Sandbox Code Playgroud)
@MapKeyJoinColumn 用于映射键的列,这里是 Project 实体。
@ElementCollection
Run Code Online (Sandbox Code Playgroud)
如果映射的值为@Embeddable,则使用
@JoinTable
Run Code Online (Sandbox Code Playgroud)
定义实体类与Map值中定义的实体之间的关系(这里是任务和用户之间的关系)。
targetEntity = User.class
Run Code Online (Sandbox Code Playgroud)
所有 targetEntity 都是多余的,因为您使用了具有定义的泛型类型的集合。
而且,你不必像这样配置3个类。据我了解,您只需要一个包含这三个类之间关系的表。因此,只需定义一个名为 Collaboration 的实体,如下所示:
@Entity
public class Collaboration{
@ManyToOne
private User user;
@ManyToOne
private Task task;
@ManyToOne
private Project project;
}
Run Code Online (Sandbox Code Playgroud)
通过分离的 Collaboration 实体,您可以找到给定 User 的所有协作。
如果没有这个实体,您可以编写一个查询来查找与给定用户相关的所有任务,然后当然可以自己用 java 代码收集项目和任务。查询将类似于
'Select t from Task t join projectUserMap m where m = :user '
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18106 次 |
| 最近记录: |