我有两个表与多对多关系连接。数据库是在另一台服务器上设置的,当我试图获取有关其中一条记录的信息时,如果这些信息包含第二个表的总计数,我就会看到非常大的性能问题。
第一个豆:
package dbaccess.beans.newsletter;
import java.sql.Timestamp;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Column;
import javax.persistence.Table;
import dbaccess.beans.RegisteredUser;
@Entity
@Table(name="NEWSLETTER_LIST")
public class NewsletterList {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "G1")
@SequenceGenerator(name = "G1", sequenceName = "NEWSLETTER_LIST_SEQ", allocationSize = 1, initialValue= 1)
@Column(name = "LIST_ID", unique = true, nullable = false)
private Long listID;
@Column(name = "LIST_NAME", nullable = false, length = 50)
private String listName;
@ManyToMany(fetch = FetchType.LAZY, cascade = {})
@JoinTable(name = "NEWSLETTERLISTS_USERS", joinColumns = {
@JoinColumn(name = "LIST_ID", nullable = false) },
inverseJoinColumns = { @JoinColumn(name = "USER_ID", nullable = false) })
private Set<RegisteredUser> users = new HashSet<RegisteredUser>(0);
public Long getListID() {
return listID;
}
public void setListID(Long listID) {
this.listID = listID;
}
public Set<RegisteredUser> getUsers() {
return users;
}
public void setUsers(Set<RegisteredUser> users) {
this.users = users;
}
}
第二个豆子:
package dbaccess.beans;
import java.sql.Timestamp;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Column;
import javax.persistence.Table;
import dbaccess.beans.newsletter.NewsletterList;
@Entity
@Table(name="USER")
public class RegisteredUser {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "G1")
@SequenceGenerator(name = "G1", sequenceName = "USER_SEQ", allocationSize = 1, initialValue= 1)
@Column(name = "USER_ID", unique = true, nullable = false)
private Long usrID;
@Column(name = "GIVENNAME", length = 20)
private String usrGivenName;
@Column(name = "FAMILYNAME", length = 20)
private String usrFamilyName;
@ManyToMany(fetch = FetchType.EAGER, mappedBy = "users", cascade = {})
public Set<NewsletterList> newsletterList = new HashSet<NewsletterList>();
public Long getUsrID() {
return usrID;
}
public void setUsrID(Long usrID) {
this.usrID = usrID;
}
public String getUsrGivenName() {
return usrGivenName;
}
public void setUsrGivenName(String usrGivenName) {
this.usrGivenName = usrGivenName;
}
public String getUsrFamilyName() {
return usrFamilyName;
}
public void setUsrFamilyName(String usrFamilyName) {
this.usrFamilyName = usrFamilyName;
}
public Set<NewsletterList> getNewsletterList() {
return newsletterList;
}
public void setNewsletterList(Set<NewsletterList> newsletterList) {
this.newsletterList = newsletterList;
}
@Override
public String toString() {
return "RegisteredUser[usrID=" + usrID + ", usrGivenName=" + usrGivenName + ", usrFamilyName=" + usrFamilyName + "]";
}
}
问题是当我尝试执行这段代码时:
session = dbService.getSessionFactory().openSession();
Criteria c = session.createCriteria(NewsletterList.class);
c.add(Restrictions.eq("listID", listID));
List<NewsletterList> newsletterList = (List<NewsletterList>) c.list();
//below is most expensive
newsletterList.get(0).getUsers().size()
有没有办法改善这种表现? 提前谢谢。
PS当我有约。一个列表中的70个用户,对上述代码的请求大约需要5-6秒!
答案 0 :(得分:2)
newsletterList.get(0).getUsers().size()
使Hibernate加载注册到时事通讯的所有用户,只是为了获得注册用户的数量。
使用临时HQL查询来计算注册用户数:
select count(user.usrID) from RegisteredUser user
inner join user.newsletterList newsLetter
where newsLetter.listID = :listId
请注意,执行上述代码5-6秒的方式太多了。您可能需要检查连接表的连接列上是否有索引。
另请注意,您只需使用session.get(NewsLetter.class, listId)
按ID获取列表。
最后,如果您的ID都被命名为id
,那么一切都会更容易,更易读。
答案 1 :(得分:0)
您可能希望尝试使用Hibernate Criteria API来查询特定简报上的用户数量。它看起来大致如下:
Criteria crit = session.createCriteria(RegisteredUser.class);
crit.setProjection(Projections.rowCount());
crit.add(Restrictions.eq("listID", listID));
return (Long) crit.uniqueResult();
答案 2 :(得分:0)