簡體   English   中英

使用Hibernate表示表關系是一個好主意嗎?

[英]Is it a good idea to use Hibernate for representing table relations?

我正在嘗試使用hibernate從Java連接到mysql數據庫。 我試圖了解是否真的值得使用休眠之類的ORM來建立關系。 特別是帶有注釋的特殊關系對我來說似乎很煩人。 因此,對於一個友誼表,我想通過使用用戶表中的外鍵來查看特定用戶的友誼請求。

在休眠類的幫助器表中也包含一個表示主表的字段。 因此,與其保持簡單的int關系,不如將User類作為主要字段。 如果您需要訪問用戶對象,但在某些情況下只需要外鍵ID,則這可能很有用。

我將為兩個表(Users和UserFriendRequests)編寫的示例代碼放入其中。 這是代表以下兩個表的最佳方法嗎? 我覺得這對於代表這樣的基本表來說是太過分了。 我寧願只使用Hibernate進行連接並單獨表示表並手動處理關系。 您會推薦這種方法嗎? 如果您可以分享有關最佳做法的想法和文件,我們將不勝感激。

用戶表具有以下列

  • userId主要,自動遞增
  • facebookId唯一
  • 用戶名
  • createdAt日期
  • lastLogin日期
  • lastNotifiedAt日期

UserFriendRequests表具有以下列:

  • 用戶表中userId的firstUser外鍵
  • 用戶表中userId的secondUser外鍵
  • PrimaryKey(firstUser,secondUser)

用戶表的表示

@Entity
@Table(name = "Users", catalog = "example_schema", uniqueConstraints = {
@UniqueConstraint(columnNames = "userId"),
@UniqueConstraint(columnNames = "facebookId")})
public class User implements Serializable {

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "userId", unique = true, nullable = false)
private int userId;
@Column(name = "facebookId", unique = true, nullable = false)
private String facebookId;
@Column(name = "userName", nullable = false)
private String userName;
@Column(name = "createdAt", nullable = false)
@Temporal(javax.persistence.TemporalType.DATE)
private Date createdAt;
@Column(name = "lastLogin")
@Temporal(javax.persistence.TemporalType.DATE)
private Date lastLogin;
@Column(name = "lastNotifiedAt")
@Temporal(javax.persistence.TemporalType.DATE)
private Date lastNotifiedAt;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "id.firstUser") // I would prefer to fill these relations manually
private List<UserFriendRequest> userFriendRequests = Lists.newArrayList();
@Transient
private boolean newUser;

public User() {
    this.createdAt = new Date();
    this.newUser = false;
}

public User(int userId) {
    this();
    this.userId = userId;
}

public User(String facebookId, String userName) {
    this();
    this.facebookId = facebookId;
    this.userName = userName;
}

public User(int userId, String facebookId, String userName) {
    this(facebookId, userName);
    this.userId = userId;
}

public int getUserId() {
    return userId;
}

public void setUserId(int userId) {
    this.userId = userId;
}

public String getFacebookId() {
    return facebookId;
}

public void setFacebookId(String facebookId) {
    this.facebookId = facebookId;
}

public boolean isNewUser() {
    return newUser;
}

public void setNewUser(boolean newUser) {
    this.newUser = newUser;
}

public String getUserName() {
    return userName;
}

public void setUserName(String userName) {
    this.userName = userName;
}

public Date getCreatedAt() {
    return createdAt;
}

public void setCreatedAt(Date createdAt) {
    this.createdAt = createdAt;
}

public Date getLastLogin() {
    return lastLogin;
}

public void setLastLogin(Date lastLogin) {
    this.lastLogin = lastLogin;
}

public Date getLastNotifiedAt() {
    return lastNotifiedAt;
}

public void setLastNotifiedAt(Date lastNotifiedAt) {
    this.lastNotifiedAt = lastNotifiedAt;
}

public List<UserFriendRequest> getUserFriendRequests() {
    return userFriendRequests;
}

public void setUserFriendRequests(List<UserFriendRequest> userFriendRequests) {
    this.userFriendRequests = userFriendRequests;
}

@Override
public int hashCode() {
    int hash = 7;
    hash = 53 * hash + this.userId;
    return hash;
}

@Override
public boolean equals(Object obj) {
    if (obj == null) {
        return false;
    }
    if (getClass() != obj.getClass()) {
        return false;
    }
    final User other = (User) obj;
    if (this.userId != other.userId) {
        return false;
    }
    return true;
}

@Override
public String toString() {
    return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
}

UserFriendRequests表的表示形式

@Entity
@Table(name = "UserFriendRequests", catalog = "example_schema")
public class UserFriendRequest implements Serializable {

@Embeddable
public static class UserFriendRequestKey implements Serializable {

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "firstUser", nullable = false)
    //Instead of user class I would prefer to keep only the int field. If I would need the user object I would handle it myself.
    private User firstUser;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "secondUser", nullable = false)
    private User secondUser;

    public UserFriendRequestKey() {
    }

    public UserFriendRequestKey(User firstUser, User secondUser) {
        this.firstUser = firstUser;
        this.secondUser = secondUser;
    }

    public User getFirstUser() {
        return firstUser;
    }

    public void setFirstUser(User firstUser) {
        this.firstUser = firstUser;
    }

    public User getSecondUser() {
        return secondUser;
    }

    public void setSecondUser(User secondUser) {
        this.secondUser = secondUser;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 89 * hash + Objects.hashCode(this.firstUser);
        hash = 89 * hash + Objects.hashCode(this.secondUser);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final UserFriendRequestKey other = (UserFriendRequestKey) obj;
        if (!Objects.equals(this.firstUser, other.firstUser)) {
            return false;
        }
        if (!Objects.equals(this.secondUser, other.secondUser)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
    }
}

@Id
private UserFriendRequestKey id;
@Column(name = "requestedAt", nullable = false)
@Temporal(javax.persistence.TemporalType.DATE)
private Date requestedAt;

public UserFriendRequest() {
}

public UserFriendRequest(UserFriendRequestKey id) {
    this.id = id;
    this.requestedAt = new Date();
}

public UserFriendRequestKey getId() {
    return id;
}

public void setId(UserFriendRequestKey id) {
    this.id = id;
}

public Date getRequestedAt() {
    return requestedAt;
}

public void setRequestedAt(Date requestedAt) {
    this.requestedAt = requestedAt;
}

@Override
public String toString() {
    return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
}

Hibernate具有陡峭的學習曲線,但也具有以下優點:

  1. 由於“臟檢查”,插入/更新更容易。 服務到位后,您可以輕松添加新字段,而無需更改服務中的行。 您只需要添加新列並填充這些列,Hibernate就會處理持久性部分。
  2. Hibernate可以樂觀地鎖定並發控制,因此可以解決“丟失更新”問題。
  3. 集成測試更加容易,因為您可以為內存數據庫(HSQLDB,H2,Derby)自動生成架構
  4. 它具有緩存插件支持(通過第三方2級緩存提供程序),某些提供程序允許您同時擁有“事務性”和“群集”高速緩存。
  5. 它具有內置的AUDIT支持(Envers)

因此,這不是一個“默認”持久性解決方案,因為有成千上萬用PHP編寫的Web應用程序在沒有ORM框架的情況下已在生產中成功運行。

我認為,對於緩存,審計,並發可靠性為強制性非功能性要求的企業應用程序,Hibernate具有更大的意義。

Hibernate用於對象關系映射。您編寫HQL查詢,如果您使用的是hibernate。我們以不同的方式使用了hibernate。讓我告訴您如何做。

使用hibernate插件,您可以為數據庫中存在的每個表生成pojo類,因此無需從身邊編寫pojo類以及許多與xml相關的文件。您的項目上必須需要一個persisten.xml文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM