我正在使用Jboss。
我有一堆复选框,我是通过生产者(@Named, @SessionScoped
)生成的,数据来自mysql数据库(使用hibernate)。当我单击复选框时,我会根据单击的复选框打印出(p:growl
)一条消息(带p:ajax
)。这一切都有效。但每次单击一个checkbock,我都可以看到hibernate执行了许多不需要的查询。实际上,单击复选框时不应执行SINGLE查询,因为我调用的方法仅将profile
作为参数并从其字段发布消息。
以下是相关代码:
jsf-part:
<p:growl id="checkMessages" />
<p:dataTable var="_profile" value="#{profileProducer.getProfilesByFormAndName('test','test')}" >
<p:column>
<p:selectBooleanCheckbox value="#{orderController.checkedProfiles[_profile]}">
<p:ajax update="@([id$=checkMessages])" listener="#{profileProducer.profileCheck(_profile)}" />
</p:selectBooleanCheckbox>
</p:column>
</p:dataTable>
配置文件控制器:
@Named
@SessionScoped
public class ProfileController implements Serializable {
private List<Profile> temporaryCheckedProfileList = new ArrayList<Profile>();
public void profileCheck(Profile profile) {
System.out.println(profile);
String message = profile.getMessage();
if (message == null || message.equals(""))
return;
if (!temporaryCheckedProfileList.contains(profile)) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(message));
temporaryCheckedProfileList.add(profile);
} else {
temporaryCheckedProfileList.remove(profile);
}
}
}
profileProducer:
@RequestScoped
@Named
public class ProfileProducer {
@Inject
private ProfileRepository profileRepository;
@Inject
private GroupRepository groupRepository;
public List<Profile> getProfilesByFormAndName(@New String formName,@New String groupName) {
return profileRepository.getProfilesByGroup(groupRepository.getGroupByFormAndName(formName, groupName));
}
}
这些是我第一次打开网站时执行的查询(这是正确和预期的行为):
Hibernate: select * from group group0_ inner join form form1_ on group0_.form_id=form1_.id where group0_.name=? and form1_.name=? limit ?
Hibernate: select * from profile profile0_ inner join group_profile groupprofi1_ on profile0_.id=groupprofi1_.profile_id inner join group group2_ on groupprofi1_.group_id=group2_.id where group2_.id=1 order by groupprofi1_.sort_nr asc
但是当我点击一个复选框时,我发现上面的两个查询都执行多次 - 对于某些复选框,它执行15次,其他25次执行...等等...
我做错了什么?
答案 0 :(得分:0)
我改变了我的profileProducer:
private Map<String, List<Profile>> cachedProfiles = new HashMap<String, List<Profile>>();
public List<Profile> getProfilesByFormAndName(String formName, String groupName) {
String key = formName + groupName;
if (!cachedProfiles.containsKey(key)) {
List<Profile> profiles = profileRepository.getProfilesByGroup(groupRepository.getGroupByFormAndName(formName, groupName));
cachedProfiles.put(key, profiles);
}
return cachedProfiles.get(key);
}
显然现在它不会查询数据库的eveytime - 但我仍然不明白为什么它甚至会执行该方法。
我使用完全错误的bean和/或注释吗?
非常欢迎任何指责/投入。
编辑: 看起来我编写了“解决方法”(缓存,如balusc其他人自己提到的那样)。
EDIT2:
最后我最终按照balus的推荐做了。
我在@PostConstruct
方法中获取所有数据并将它们放在一个映射中(以groupName + formName作为键),在我的getter方法中我只读出它们。