对象关系映射

Object relational mapping

我是 ORM 的新手,任何人都可以提出一个想法来克服以下情况。

我有一个聊天 Class 如下

@Entity
public class Chat {     

    @Id
    @GeneratedValue
    @Column(name="Id")
    private int id; 

    @ManyToOne
    private User userSent;

    @ManyToOne
    private User userRecieve;

    private Date time;

    @Column(name="message", length=50)
    private String message;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
    public Date getTime() {
        return time;
    }

    public void setTime(Date time) {
        this.time = time;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

用户class如下

@Entity
public class User {

    @Id
    @GeneratedValue
    private Integer id;

    private String name;

    private String email;

    private String password;


    @OneToMany
    private List<Chat> chats;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
    public List<Chat> getChats() {
        return chats;
    }

    public void setChats(List<Chat> chats) {
        this.chats = chats;
    }
}

我的问题是一个用户有很多聊天,聊天有 2 种不同类型的用户作为接收者和发件人,但他们都属于一个特定的聊天。

我的问题是如何声明它如何赋予关系。提前致谢

无法使用 JPA 表达双向 双对多 关系(其中两个 two 是不同的字段)一个简单的方法。

解决此问题的最简单方法是通过从 User 中删除 chats 字段使关系成为单向关系。然后在你的 repository/DAO for Chat 中你提供了一个函数 findByUser 和一个像

这样的查询
SELECT Chat c WHERE c.userSent = :user OR c.userReceive = :user

通过这种方式,您仍然可以获取给定用户的聊天记录,而不是通过 User 实体本身。


另一个解决方案是使关系 多对多 并向关系添加 属性 以指示用户参与聊天的类型。您必须创建一个中间实体,例如

@Entity
public class ChatParticipation {
  public static enum Type {
    SENDER,
    RECEIVER
  }

  private Chat chat;
  private User user;
  private Type type;
}

并修改其他实体的getters

@Entity
public class Chat {
  @OneToMany
  private Set<ChatParticipation> participations;

  public User getSender() {
    return participations.stream()
      .filter(p -> p.getType() == ChatParticipation.Type.SENDER)
      .map(ChatParticipation::getUser)
      .findFirst().get();
  }

  public User getReceiver() {
    return participations.stream()
      .filter(p -> p.getType() == ChatParticipation.Type.RECEIVER)
      .map(ChatParticipation::getUser)
      .findFirst().get();
  }
}

@Entity
public class User {
  @OneToMany
  private Set<ChatParticipation> participations;

  public Set<Chat> getChats() {
    return participations.stream()
      .map(ChatParticipation::getChat)
      .collect(Collectors.toSet());
  }
}

您可能应该缓存 getter 结果。另外,你必须想出一个解决方案。