2008年3月11日火曜日

ZK: jdbcManager Seasar変数(3)

jdbcManagerを使いながらデザインとロジックを分離したいときは
こんな感じでいけそうです。

listboxのモデルにEmpWindowのプロパティemps、selectedItemにselectedをセットします。


...
<window id="win" title="Emplyee list" use="zkseasar.view.EmpWindow">
<listbox id="lb" model="@{win.emps}" selectedItem="@{win.selected}">



EmpWindow.java

public class EmpWindow extends Window {
private JdbcManager jdbcManager;
private List<Emp> emps;
private Emp selected;

public EmpWindow(){
DelegatingVariableResolver variableResolver = new DelegatingVariableResolver();
jdbcManager = (JdbcManager)variableResolver.resolveVariable("jdbcManager");

emps = jdbcManager.from(Emp.class)
.where("sal between ? and ?", 2000, 3000)
.orderBy("sal").getResultList();
}

public List<Emp> getEmps(){
return emps;
}

public void setSelected(Emp emp){
selected = emp;
}

public Emp getSelected(){
return selected;
}


/*
* listboxにempを追加する
* http://sourceforge.net/forum/message.php?msg_id=4752395
*/
public void addEmp(Emp emp){
Listbox lb = ((Listbox) getFellow("lb"));
((ListModelList) lb.getModel()).add(emp);
}
}


ZKをSeasarと組み合わせるとデータベースアクセスはjdbcManagerの使いかただけ知っていればいいみたいですね。

ZK: jdbcManager Seasar変数(2)

可変長引数を持つメソッドはzscriptでは使用できないようです。


<zscript>
import zkseasar.entity.Emp;
emps = jdbcManager.from(Emp.class)
.where("sal >= ?", 2000)
.orderBy("sal")
.getResultList();
</zscript>

上記のスクリプトを実行すると次のエラーメッセージを吐いてしまいます。

致命的: サーブレット zkLoader のServlet.service()が例外を投げました
org.zkoss.zk.ui.UiException: Sourced file: inline evaluation of: ``import zkseasar.entity.Emp;
emps = jdbcManager.from(Emp.class) . . . '' :
Error in method invocation: Method where( java.lang.String, int ) not found in class'org.seasar.extension.jdbc.query.AutoSelectImpl' :

検索条件を指定するときはSQL文字列ではなくSimpleWhereが使えます。

<zscript >
import zkseasar.entity.Emp;
import org.seasar.extension.jdbc.where.SimpleWhere;
emps = jdbcManager.from(Emp.class)
.where(new SimpleWhere()
.ge("sal", 2000)
)
.orderBy("sal")
.getResultList();
</zscript>


Rubyからは可変長引数を持つJavaメソッドでも呼び出せるか試してみました。

<zscript language="ruby">
import 'zkseasar.entity.Emp'
emps = $jdbcManager.from(Java::ZkseasarEntity::Emp:Class).
where("sal >= ?", 2000).
orderBy("sal").
getResultList()

emps.each{|emp| print emp.deptId, "\t", emp.empName, "\t", emp.sal, "\n"}
</zscript>

やはりダメですね。

致命的: サーブレット zkLoader のServlet.service()が例外を投げました
:1: no where with arguments matching [class java.lang.String, class java.lang.Long]
on object JavaUtilities (NameError)
...internal jruby stack elided...

ZK: jdbcManager Seasar変数

DelegatingVariableResolverでZKから直接jdbcManagerが使えるんですね。

emp.zul


<?xml version="1.0" encoding="UTF-8"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
<?variable-resolver class="org.zkoss.zkplus.seasar.DelegatingVariableResolver"?>
<zk xmlns="http://www.zkoss.org/2005/zul" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul/zul.xsd ">
<zscript >
import zkseasar.entity.Emp;
emps = jdbcManager.from(Emp.class)
.orderBy("sal")
.getResultList();
</zscript>
<window title="Emplyee list" >
<listbox model="@{emps}">
<listhead>
<listheader label="id"/>
<listheader label="Emp no"/>
<listheader label="Emp name"/>
<listheader label="Hiredate"/>
<listheader label="Sal"/>
<listheader label="Dept id"/>
<listheader label="Version no"/>
</listhead>
<listitem self="@{each=emp}">
<listcell label="@{emp.id}"/>
<listcell label="@{emp.empNo}"/>
<listcell label="@{emp.empName}"/>
<listcell label="@{emp.hiredate}"/>
<listcell label="@{emp.sal}"/>
<listcell label="@{emp.deptId}"/>
<listcell label="@{emp.versionNo}"/>
</listitem>
</listbox>
</window>
</zk>

これは楽ちん!!



java.util.Date および java.util.Calendar 型のプロパティには時制を指定する必要があるそうです。
EmpクラスのhiredateプロパティはDate型なので@Temporalを使い時制にTemporalType.DATEを指定します。

Emp.java

public class Emp {
..
@Temporal(TemporalType.DATE)
@Column(name = "HIREDATE")
public Date hiredate;
..