如何在hibernate中仅获取期望的bean属性?

问题描述:

我为我的应用程序使用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只针对所需的属性(字符串或原始类型)的火灾查询并非所有。

这对我来说看起来像过早的优化,特别是如果您的查询只返回一个用户实例,如在您的实例。

不仅如此,而且它实际上很混乱,因为查询不会返回完整的用户:它返回一个几乎所有字段都设置为空的用户,这可能会破坏类的不变量,并且存在没有办法让调用者知道数据库中的某个字段是否真的为null,或者仅当您的查询选择不加载时才为null。

我会先测量一下,如果加载这些字段确实会导致性能问题,并且只会优化是否存在某个性能问题。我将使用专用的UserDTO,它将只包含查询实际加载的字段。您也可以看看fetch groups,它可以启用属性的延迟加载,但参考手册中提到:

请注意,这主要是一种营销功能;优化行 读取比列读取的优化重要得多。 但是,仅在极端情况下才会加载某个类的某些属性。例如,当传统表具有数百个 列并且数据模型无法改进时。

您可以编写一个实用程序,为您准备此类动态查询。

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