就像以前强调过的,在finally
子句中关闭连接是很重要的,这样每个连接都会被正确的返回连接池。
为使你的应用程序更加健壮(robust),你可以实现org.zkoss.zk.ui.event.EventThreadCleanup
接口来关闭任何处在等待之际的连接和语句(any pending connections and statements),以防你的一些应用程序代码忘记了在finally
子句中关闭它们。
但是,关闭处在等待之际的连接和语句实际上依赖于你使用的服务器。你需要参考服务器的文档来得知如何编写关闭代码。
[提示]: 在许多情况下,并不需要(且并不容易)提供这样的方法,因为多数连接池的实现可以循环一个连接若调用了连接池的finalized
方法(because most implementation of connection pooling be recycled a connection if its finalized method is called)。
除了在事件监听器中访问数据库,使用EL表达式访问数据库填充一个属性也是很常见的。在下面的例子中,我们从数据库取出数据,并使用EL表达式将它们用listbox
展示出来。
<zscript>
import my.CustomerManager;
customers = new CustomerManager().findAll(); //load from database
</zscript>
<listbox id="personList" width="800px" rows="5">
<listhead>
<listheader label="Name"/>
<listheader label="Surname"/>
<listheader label="Due Amount"/>
</listhead>
<listitem value="${each.id}" forEach="${customers}">
<listcell label="${each.name}"/>
<listcell label="${each.surname}"/>
<listcell label="${each.due}"/>
</listitem>
</listbox>
有几种方式来实现findAll
方法。
最简单的方式是在findAll
方法内获取所有的数据,将它们拷贝到一个列表,然后关闭连接。
public class CustomerManager {
public List findAll() throws Exception {
DataSource ds = (DataSource)new InitialContext()
.lookup("java:comp/env/jdbc/MyDB");
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
List results = new LinkedList();
try {
conn = ds.getConnection();
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT id, name, surname FROM customers");
while (rs.next()) {
long id = rs.getInt("id");
String name = rs.getString("name");
String surname = rs.getString("surname");
results.add(new Customer(id, name, surname));
}
return results;
} finally {
if (rs != null) try { rs.close(); } catch (SQLException ex) [}
if (stmt != null) try { stmt.close(); } catch (SQLException ex) [}
if (conn != null) try { conn.close(); } catch (SQLException ex) [}
}
}
}
你可以使用init
指令来加载数据,以代替在试图中混合使用Java代码。
<?init class="my.AllCustomerFinder" arg0="customers"?>
<listbox id="personList" width="800px" rows="5">
<listhead>
<listheader label="Name"/>
<listheader label="Surname"/>
<listheader label="Due Amount"/>
</listhead>
<listitem value="${each.id}" forEach="${customers}">
<listcell label="${each.name}"/>
<listcell label="${each.surname}"/>
<listcell label="${each.due}"/>
</listitem>
</listbox>
然后,使用org.zkoss.zk.ui.util.Initiator
接口实现my.CustomerFindAll
类。
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.util.Initiator;
public class AllCustomerFinder implements Initiator {
public void doInit(Page page, Object[] args) {
try {
page.setVariable((String)args[0], new CustomerManager().findAll());
//Use setVariable to pass the result back to the page
} catch (Exception ex) {
throw UiException.Aide.wrap(ex);
}
}
public void doCatch(Throwable ex) { //ignore
}
public void doFinally() { //ignore
}