如何在休眠中仅获取bean所需的属性?

发布于 2025-01-03 12:25:37 字数 7791 浏览 2 评论 0原文

我在我的应用程序中使用 Hibernate 3.5.6。在此应用程序中,我使用 hbm.xml 文件将 POJO 映射到数据库表列。

在此应用程序中,我有如下 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;
}

现在

,当我想从数据库中获取 User 时,我使用了 Criteria 或 get 或 load 方法。 但是当我看到hibernate生成的查询时,查询长度太高了。这是因为我在User bean中有38个属性。因为所有属性都是String和基元类型(没有任何属性是Has-类型)另一个 bean 类)

但我实际需要的 id 仅适用于 10-12 个,或者一次可能只有 20 个属性。我不希望 hibernate 获取 fetch User bean 上的每个属性。

为此,我看到了 HQL,其中我只能在构造函数中给出我只想获取的属性数量。 如下所示:

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

它只会触发查询来获取 id 和 UserName,因此查询长度很短,而且我只获得了我需要的属性。

但是每次都需要不同类型的属性来编写查询是非常困难的,并且还需要在 POJO 类中需要相同签名的构造函数。 当User类中的一些集合和其他bean也想同时获取时会更加困难。

所以我想知道是否有其他方法可以限制 hibernate 仅针对所需属性(字符串或基本类型)而不是所有属性触发查询。

I am using Hibernate 3.5.6 for my application.In this application I am using hbm.xml files to map my POJO to database table columns.

In this application I have User bean as below.

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;
}

}

Now when I want to fetch User from databse, I have used criteria or get or load method.
But when I saw the query which is generated by hibernate, the query length is too high.This is because I have 38 property in User bean.As all property are of type of String and primitives (no any of property is type of Has-A another bean class)

But my actual required id only for 10-12 or may be only 20 properties at a time.I don't want hibernate to fetch every property on fetch User bean.

For this I have seen HQL In which I can give only number of property in constructor which I want to fetch only.
Like below:

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

It will fire query only to fetch id and UserName so the query length is short and also I got properties which I required only.

But it is very difficult to write query every time with different type of properties required and it also need to required same signature constructor in POJO class.
It will be more difficult when some collections and other beans in User class and also want to fetch at the same time.

So I want to know is there any other ways to restrict hibernate to fire query only for required properties (string or primitive types) not for all.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

痴骨ら 2025-01-10 12:25:37

对我来说,这看起来像是过早的优化,特别是如果您的查询仅返回一个用户实例(如您的实例中所示)。

不仅如此,它实际上非常令人困惑,因为查询不会返回完整的 User:它返回的 User 几乎所有字段都设置为 null,这可能会破坏类的不变量,并且没有办法调用者知道数据库中的某个字段是否确实为空,或者它是否只是因为您的查询选择不加载它而为空。

我会首先衡量加载这些字段是否真的会导致性能问题,并且仅在存在问题的情况下进行优化。我将使用专用的 UserDTO,它仅包含查询实际加载的字段。您还可以查看获取组< /a>,它启用属性的延迟加载,但正如参考手册所述:

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

This looks like premature optimization to me, especially if your query only returns one User instance as in your instance.

Not only that, but it's actually very confusing, because the query doesn't return a complete User: it returns a User with nearly all the fields set to null, which might break the invariants of the class, and there is no way for the caller to know if some field is really null in database or if it's null only because your query chose not to load it.

I would first measure if loading these fields really cause a performance problem, and only optimize if and where there is one. And I would use a dedicated UserDTO which would only contain the fields actually loaded by the query. You might also look at fetch groups, which enable lazy-loading of properties, but as the reference manual says:

Please note that this is mostly a marketing feature; optimizing row
reads is much more important than optimization of column reads.
However, only loading some properties of a class could be useful in
extreme cases. For example, when legacy tables have hundreds of
columns and the data model cannot be improved.

风追烟花雨 2025-01-10 12:25:37

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

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

当您的 POJO 中有关联的集合时,您可以添加使用连接的逻辑。

我发现它很有用,并且比 DTO 更喜欢它,因为它们减少了管理转换、更改等方面的麻烦。

You can write an Utility that will prepare such dynamic query for you.

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

When you have associated collection in your POJO you can add logic that make use of joins.

I found it useful and would prefer this over DTO as they reduce lot of headache of managing them for conversion, change etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文