我有以下xhtml文档:
<h:body>
<ui:composition template="templates/layout.xhtml">
<ui:define name="content">
<c:if test="#{sessionBean.userCode > 0}">
<h:form id="findStudentForm">
<p:outputPanel id="resultsPanel">
<c:if test="#{studentsBean.student != null}">
<h2><h:outputText value="#{studentsBean.student.fullName}"/></h2>
<h3>Personal data</h3>
. . .
<p align="center">
<p:commandButton value="Search students" update="@form">
<f:setPropertyActionListener value="#{null}"
target="#{studentsBean.student}"/>
</p:commandButton>
</p>
</c:if>
<c:if test="#{studentsBean.student == null}">
<h2>Student search</h2>
. . .
<p align="justify">
First name
<h:inputText value="#{studentsBean.pattern}"/>
<p:commandButton value="Поиск" update="resultsPanel"/>
</p>
<p:dataTable id="resultsTable" var="student"
value="#{studentsBean.studentsList}"
widgetVar="studentsTable" emptyMessage="No records found">
. . .
</p:column>
<p:column headerText="Actions">
<p:commandButton value="Details" update="@form">
<f:setPropertyActionListener value="#{student}"
target="#{studentsBean.student}"/>
</p:commandButton>
</p:column>
</p:dataTable>
</c:if>
</p:outputPanel>
</h:form>
</c:if>
<c:if test="#{sessionBean.userCode == 0}">
<ui:include src="templates/include/error.xhtml"/>
</c:if>
</ui:define>
</ui:composition>
</h:body>
我还有以下Managed Bean(StudentsBean): 。 。
@Named(value = "studentsBean")
@RequestScoped
public class StudentsBean {
@Inject
SessionBean session;
private Student student = null;
private String pattern = "";
private String groupName = "";
@Inject
private StudentInterface studentProvider;
. . .
public String getPattern() {
return pattern;
}
public void setPattern(String pattern) {
this.pattern = pattern;
}
public List<Student> getStudentsList() {
List<Student> result = new ArrayList<Student>();
if (studentProvider != null) {
try {
result = studentProvider.findStudents(pattern);
} catch (StudentException e) {
session.printError(e.getMessage());
}
}
return result;
}
. . .
最后,我有一个班级StudentsProvider:
public class StudentProvider implements StudentInterface {
private Connection connection = null;
. . .
@Override
public List<Student> findStudents(String pattern) throws StudentException {
List<Student> result = new ArrayList<Student>();
String addon = "";
if (pattern.trim().isEmpty()) {
addon = "TOP 10 ";
}
try {
PreparedStatement statement = connection.prepareStatement(
"SELECT " + addon + "st_pcode, gr_Name, st_FullName "
+ "FROM students, groups WHERE (st_grcode = gr_pcode) AND (st_FullName LIKE ?) "
+ "ORDER BY gr_Name, st_FullName;", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
statement.setString(1, pattern + "%");
ResultSet rs = statement.executeQuery();
while (rs.next()) {
result.add(getStudent(rs.getString("st_pcode")));
}
rs.close();
statement.close();
} catch (Exception e) {
throw new StudentException("Error reading list: " + e.getMessage());
}
return result;
}
public StudentProvider() throws StudentException {
try {
ConnectionProvider provider = new ConnectionProvider();
connection = provider.getConnection();
} catch (ConnectionException e) {
throw new StudentException("Connect error: " + e.getMessage());
}
}
@Override
public void finalize() throws Throwable {
connection.close();
super.finalize();
}
}
如果变量“pattern”为空字符串,则PreparedStatement返回10个“第一”记录。但如果“模式”有内容 - PreparedStatement会找到一些记录。在调试期间,似乎PreparedStatement运行良好并返回结果集,但在“sultsTable”中没有显示任何记录。另外,我发现,在更新流程方法时
studentProvider.findStudent(pattern)
多次打电话。我认为,这个方法调用的数量取决于“resultsTable”中的记录数。
在注射之前,使用硬链接对象一切正常。怎么了?
顺便说一下,我无法理解一件事。说,我有一个按钮<p:commandButton value="Details" update="@form">
<f:setPropertyActionListener value="#{student}"
target="#{studentsBean.student}"/>
</p:commandButton>
在“resultsTable”的每条记录中(有关详细信息,请参阅之前的xhtml列表)。我发现,这个按钮有时不起作用。 如果resultsTable在开头为空 - 按钮不起作用,但如果resultsTable不为空 - 按钮工作。那么如何让按钮始终有效?
答案 0 :(得分:2)
更好的方法是(只是草图):
// an action method in your backing bean.
// This will call your search method and set the values behid your dataTable
public void searchStudents(String pattern) {
setStudentsList(findStudent(pattern));
}
通话结束后更新您的dataTable:
<p:commandButton update="resultsTable" action=#{studentProvider.findStudent(pattern)}"
回答你的第二个问题:Why JSF calls getters multiple times,这意味着将你的业务逻辑方法放入getter(没有延迟加载)似乎是一个坏主意(另一个相关问题:JSF calling setter & getter multiple times)。