2012-02-09 72 views
2

我爲我的應用程序使用Hibernate 3.5.6。在此應用程序中,我使用hbm.xml文件將POJO映射到數據庫表列。如何在hibernate中僅獲取期望的bean屬性?

在這個應用程序中,我有User bean如下。

public class User { 
// login info 
private long id; 
private String type; 

private String userName; 
private String password; 
private String securityQuestionStr; 
private String securityAnswer; 

// personal info 
private String firstName; 
private String middleName; 
private String lastName; 

/** 
* <b>{@link GenderType} gender</b> 
*/ 
private GenderType gender; 

private Date dateOfBirth; 

// other related info 
/** 
* <b>{@link UserType} userType</b> 
*/ 
private UserType userType; 

// contact info 
private Long mobileNo; 
private Long businessPhoneNo; 
private Long homePhoneNo; 
private Long faxNo; 
private String email; 
private String alternateEmail; 

/** 
* <b>{@link RegistrationStatus} userStatus</b> 
*/ 
private RegistrationStatus userStatus; 

/** 
* <b>{@link Post} posts</b> 
*/ 
private String securityAnswerHash; 
private String passwordHash; 
private String encryptedPassword; 
private String encryptedSecurityAnswer; 
private String nationality; 

private String portal; 
private float version; 
private Date createdDate; 
private User createdUser; 
private String createdIP; 
private Date lastModifiedDate; 
private User lastModifiedUser; 
private String lastModifiedIP; 
private boolean recordStatus; 
private String publicKey; 
private String certificateName; 
private String signPublicKey; 
private String signCertificateName; 
private boolean isEtoken; 

public long getId() { 
    return id; 
} 
public void setId(long id) { 
    this.id = id; 
} 
public String getType() { 
    return type; 
} 
public void setType(String type) { 
    this.type = type; 
} 
public String getUserName() { 
    return userName; 
} 
public void setUserName(String userName) { 
    this.userName = userName; 
} 
public String getPassword() { 
    return password; 
} 
public void setPassword(String password) { 
    this.password = password; 
} 
public String getSecurityQuestionStr() { 
    return securityQuestionStr; 
} 
public void setSecurityQuestionStr(String securityQuestionStr) { 
    this.securityQuestionStr = securityQuestionStr; 
} 
public String getSecurityAnswer() { 
    return securityAnswer; 
} 
public void setSecurityAnswer(String securityAnswer) { 
    this.securityAnswer = securityAnswer; 
} 
public String getFirstName() { 
    return firstName; 
} 
public void setFirstName(String firstName) { 
    this.firstName = firstName; 
} 
public String getMiddleName() { 
    return middleName; 
} 
public void setMiddleName(String middleName) { 
    this.middleName = middleName; 
} 
public String getLastName() { 
    return lastName; 
} 
public void setLastName(String lastName) { 
    this.lastName = lastName; 
} 
public GenderType getGender() { 
    return gender; 
} 
public void setGender(GenderType gender) { 
    this.gender = gender; 
} 
public Date getDateOfBirth() { 
    return dateOfBirth; 
} 
public void setDateOfBirth(Date dateOfBirth) { 
    this.dateOfBirth = dateOfBirth; 
} 
public UserType getUserType() { 
    return userType; 
} 
public void setUserType(UserType userType) { 
    this.userType = userType; 
} 
public Long getMobileNo() { 
    return mobileNo; 
} 
public void setMobileNo(Long mobileNo) { 
    this.mobileNo = mobileNo; 
} 
public Long getBusinessPhoneNo() { 
    return businessPhoneNo; 
} 
public void setBusinessPhoneNo(Long businessPhoneNo) { 
    this.businessPhoneNo = businessPhoneNo; 
} 
public Long getHomePhoneNo() { 
    return homePhoneNo; 
} 
public void setHomePhoneNo(Long homePhoneNo) { 
    this.homePhoneNo = homePhoneNo; 
} 
public Long getFaxNo() { 
    return faxNo; 
} 
public void setFaxNo(Long faxNo) { 
    this.faxNo = faxNo; 
} 
public String getEmail() { 
    return email; 
} 
public void setEmail(String email) { 
    this.email = email; 
} 
public String getAlternateEmail() { 
    return alternateEmail; 
} 
public void setAlternateEmail(String alternateEmail) { 
    this.alternateEmail = alternateEmail; 
} 
public RegistrationStatus getUserStatus() { 
    return userStatus; 
} 
public void setUserStatus(RegistrationStatus userStatus) { 
    this.userStatus = userStatus; 
} 
public String getSecurityAnswerHash() { 
    return securityAnswerHash; 
} 
public void setSecurityAnswerHash(String securityAnswerHash) { 
    this.securityAnswerHash = securityAnswerHash; 
} 
public String getPasswordHash() { 
    return passwordHash; 
} 
public void setPasswordHash(String passwordHash) { 
    this.passwordHash = passwordHash; 
} 
public String getEncryptedPassword() { 
    return encryptedPassword; 
} 
public void setEncryptedPassword(String encryptedPassword) { 
    this.encryptedPassword = encryptedPassword; 
} 
public String getEncryptedSecurityAnswer() { 
    return encryptedSecurityAnswer; 
} 
public void setEncryptedSecurityAnswer(String encryptedSecurityAnswer) { 
    this.encryptedSecurityAnswer = encryptedSecurityAnswer; 
} 
public String getNationality() { 
    return nationality; 
} 
public void setNationality(String nationality) { 
    this.nationality = nationality; 
} 
public String getPortal() { 
    return portal; 
} 
public void setPortal(String portal) { 
    this.portal = portal; 
} 
public float getVersion() { 
    return version; 
} 
public void setVersion(float version) { 
    this.version = version; 
} 
public Date getCreatedDate() { 
    return createdDate; 
} 
public void setCreatedDate(Date createdDate) { 
    this.createdDate = createdDate; 
} 
public User getCreatedUser() { 
    return createdUser; 
} 
public void setCreatedUser(User createdUser) { 
    this.createdUser = createdUser; 
} 
public String getCreatedIP() { 
    return createdIP; 
} 
public void setCreatedIP(String createdIP) { 
    this.createdIP = createdIP; 
} 
public Date getLastModifiedDate() { 
    return lastModifiedDate; 
} 
public void setLastModifiedDate(Date lastModifiedDate) { 
    this.lastModifiedDate = lastModifiedDate; 
} 
public User getLastModifiedUser() { 
    return lastModifiedUser; 
} 
public void setLastModifiedUser(User lastModifiedUser) { 
    this.lastModifiedUser = lastModifiedUser; 
} 
public String getLastModifiedIP() { 
    return lastModifiedIP; 
} 
public void setLastModifiedIP(String lastModifiedIP) { 
    this.lastModifiedIP = lastModifiedIP; 
} 
public boolean isRecordStatus() { 
    return recordStatus; 
} 
public void setRecordStatus(boolean recordStatus) { 
    this.recordStatus = recordStatus; 
} 
public String getPublicKey() { 
    return publicKey; 
} 
public void setPublicKey(String publicKey) { 
    this.publicKey = publicKey; 
} 
public String getCertificateName() { 
    return certificateName; 
} 
public void setCertificateName(String certificateName) { 
    this.certificateName = certificateName; 
} 
public String getSignPublicKey() { 
    return signPublicKey; 
} 
public void setSignPublicKey(String signPublicKey) { 
    this.signPublicKey = signPublicKey; 
} 
public String getSignCertificateName() { 
    return signCertificateName; 
} 
public void setSignCertificateName(String signCertificateName) { 
    this.signCertificateName = signCertificateName; 
} 
public boolean isEtoken() { 
    return isEtoken; 
} 
public void setEtoken(boolean isEtoken) { 
    this.isEtoken = isEtoken; 
} 

}

現在,當我想獲取來自DATABSE用戶,我用標準或得到或負擔方法。 但是,當我看到由hibernate生成的查詢時,查詢長度太高。這是因爲我在User bean中有38個屬性。由於所有屬性都是String類型和基元類型(沒有任何屬性是Has類型的 - 另一個豆類)

但我的實際所需的ID只爲10-12或可能只有20個屬性在一個時間。我不希望休眠獲取每個屬性獲取用戶bean。

爲此,我已經看到了HQL在其中我只能給我只想獲取構造函數的屬性數量。 象下面這樣:

Query query = session 
      .createQuery("select new User(id, userName) from User where id=?"); 
    query.setParameter(0, 1l); 

它只會火查詢來獲取ID和用戶名,以便查詢長度很短,並且還我,我唯一需要的屬性。

但是每次使用不同類型的屬性都需要編寫查詢非常困難,它也需要在POJO類中需要相同的簽名構造函數。 當User類中的某些集合和其他bean同時也想要同時獲取時,將會更加困難。

所以我想知道是否有任何其他方法來限制hibernate只針對所需的屬性(字符串或原始類型)的火災查詢並非所有。

回答

1

這對我來說看起來像過早的優化,特別是如果您的查詢只返回一個用戶實例,如在您的實例。

不僅如此,而且它實際上很混亂,因爲查詢不會返回完整的用戶:它返回一個幾乎所有字段都設置爲空的用戶,這可能會破壞類的不變量,並且存在沒有辦法讓調用者知道數據庫中的某個字段是否真的爲null,或者僅當您的查詢選擇不加載時才爲null。

我會先測量一下,如果加載這些字段確實會導致性能問題,並且只會優化是否存在某個性能問題。我將使用專用的UserDTO,它將只包含查詢實際加載的字段。您也可以看看fetch groups,它可以啓用屬性的延遲加載,但參考手冊中提到:

請注意,這主要是一種營銷功能;優化行 讀取比列讀取的優化重要得多。 但是,僅在極端情況下才會加載某個類的某些屬性。例如,當傳統表具有數百個 列並且數據模型無法改進時。

1

您可以編寫一個實用程序,爲您準備此類動態查詢。

DataBaseUtil.createPropertySpecificQuery(Clazz entity, String[] properties, String[] conditionParams, String[] conditionOperators){} write a logic to build query. 

當您在POJO中關聯集合時,您可以添加使用連接的邏輯。

我發現它有用,希望這種過度DTO,因爲它們減少很多管理它們轉換的頭痛,變更等

+0

嘿Bhavesh感謝reply.I會試試這個。 – 2012-02-10 09:23:37