Full Ajax な CRUD アプリケーション その3

前回は画面のモックアップを作成しました。今回は実際にデータベースから取得したデータを表示するよう実装していきます。

データベースのセットアップ

まず最初はデータベースのセットアップを行います。データベースにはデフォルトでEMPテーブルとDEPTテーブルの二つが存在しています。これは必要ないので削除して下さい。

このサンプルで利用する社員テーブルのDDL文を以下に示します。

テーブル名EMPLOYEEのDDL
create table EMPLOYEE (
	ID integer generated by default as identity,
	NAME varchar(255),
	JOB_TYPE varchar(30),
	SALARY integer,
	DEPARTMENT varchar(255)
)

DbLauncherを利用してH2データベースを立ち上げて上記DDL文を実行してください。その後は以下のテストデータを挿入してください。

テストデータ
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー01', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー02', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー03', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー04', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー05', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー06', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー07', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー08', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー09', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー10', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー11', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー12', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー13', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー14', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー15', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー16', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー17', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー18', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー19', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー20', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー21', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー22', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー23', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー24', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー25', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー26', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー27', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー28', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー29', '開発', 200000, '開発部');
insert into EMPLOYEE (NAME, JOB_TYPE, SALARY, DEPARTMENT) values ('テストユーザー30', '開発', 200000, '開発部');

S2JDBC-Genで各クラスの自動生成

ajax-app/s2jdbc-gen-build.xmlをAnt Buildで実行します。ビルドファイルを右クリックし「Run as」>「Ant Build...」を選択します。ターゲット一覧が表示されますのでその中から「gen-entity」のみを選択し実行します。実行が完了するとEmployee、EmployeeNames、EmployeeCondition、EmployeeService、AbstractService、EmployeeTestの五つ六つクラスが作成されます。

サーバーサイドのデータ一覧取得実装

EmployeeServiceにJSONデータを出力するメソッドfind()を作成します。ソースを以下に示します。

EmployeeService.java
package webapplication.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import webapplication.dto.PagerConditionDto;
import webapplication.entity.Employee;
import webapplication.entity.EmployeeNames;

/**
 * {@link Employee}のサービスクラスです。
 * 
 * @author tom
 */
public class EmployeeService extends AbstractService<Employee> implements EmployeeNames {

    /**
     * 識別子でエンティティを検索します。
     * 
     * @param id
     *            識別子
     * @return エンティティ
     */
    public Employee findById(Integer id) {
        return select().id(id).getSingleResult();
    }

    /**
     * JSONIC RESTモードで使用。エンティティ一覧を検索します。
     * 
     * @param conditionDto
     * 			ページング条件
     * @return	JSONの為のMapオブジェクト
     */
	public Map<String, Object> find(PagerConditionDto conditionDto) {
		long count = 
			jdbcManager
				.from(Employee.class)
					.getCount();
		List<Employee> list = 			
			jdbcManager
				.from(Employee.class)
					.orderBy(id)
					.offset(conditionDto.start)
					.limit(conditionDto.limit)
					.getResultList();
		Map<String, Object> m = new HashMap<String, Object>();
		m.put("totalProperty", count);
		m.put("root", list);
		return m;
	}

}
PagerConditionDto.java
package webapplication.dto;

public class PagerConditionDto {

	public int start;

	public int limit;

}

ブラウザからhttp://localhost:8080/ajax-app/employee/employee.jsonへアクセスしJSONデータが取得出来るのを確認して下さい。この機能はJSONICサーブレットで実現しています。このサーブレットSeasar2コンポーネントを容易に扱う事が出来て、JSONへの変換も非常に簡単に出来る仕組みになっています。

グリッドのデータソースを実装

Ext.data.Storeを定義しサーバーサイドからデータを取得します。

storeのソース
	var fields = [ 'id', 'name', 'jobType', 'salary', 'department' ];

	var store = new Ext.data.Store({
		proxy: new Ext.data.HttpProxy({
			url: './employee.json',
			method: 'GET'
		}),
		reader: new Ext.data.JsonReader({
		    root: 'root',
		    totalProperty: 'totalProperty',
			fields: fields
		})
	});

	store.load({params:{start:0, limit:pageSize}});
employee.js - storeを定義
Ext.onReady(function(){

	// MODEL, CONTROL

	var fields = [ 'id', 'name', 'jobType', 'salary', 'department' ];

	var store = new Ext.data.Store({
		proxy: new Ext.data.HttpProxy({
			url: './employee.json',
			method: 'GET'
		}),
		reader: new Ext.data.JsonReader({
		    root: 'root',
		    totalProperty: 'totalProperty',
			fields: fields
		})
	});

	// VIEW

	var colModel = new Ext.grid.ColumnModel([
		{header: "Id", width: 75, sortable: true, dataIndex: 'id'},
		{id:'name', header: "氏名", width: 160, sortable: true, dataIndex: 'name'},
		{header: "職種", width: 75, sortable: true, dataIndex: 'jobType'},
		{header: "給与", width: 75, sortable: true, dataIndex: 'salary'},
		{header: "部署", width: 85, sortable: true, dataIndex: 'department'}
	]);

	var addAction = new Ext.Action({
		text: '追加',
		iconCls: 'addIcon'
	});

	var editAction = new Ext.Action({
		text: '編集',
		iconCls: 'editIcon'
	});

	var deleteAction = new Ext.Action({
		text: '削除',
		iconCls: 'deleteIcon'
	});

	var findAction = new Ext.Action({
		text: '検索',
		iconCls: 'findIcon'
	});

	var tbar = [
		addAction,
		'-',
		editAction,
		deleteAction,
		'-',
		findAction
	];

	var pageSize = 20;

	var bbar = new Ext.PagingToolbar({
		id: 'pagingToolbar',
		pageSize: pageSize,
		store: store,
		displayInfo: true,
		displayMsg: '社員の一覧 {2} 件中 {0} - {1} 件目',
		emptyMsg: "社員の一覧はありません"
	});

	var grid = new Ext.grid.GridPanel({
		title:'社員管理',
		stripeRows: true,
		autoExpandColumn: 'name',
		height:523,
		width:600,
		store: store,
		colModel: colModel,
		tbar: tbar,
		bbar: bbar
	});

	// INIT
	
	grid.render('grid-employee');

	store.load({params:{start:0, limit:pageSize}});

});

ブラウザからhttp://localhost:8080/ajax-app/employee/index.htmlを開くとデータが読み込まれて表示されているのが確認できます。

今回は以上です。サーバーサイドの作成が簡単に出来るのをわかって頂けると思います。

次回はデータの追加、編集、削除機能を実装します。