SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine(コードジン) DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

OSSフレームワーク「dataforms.jar」でサンプルプログラムを構築する(1)

テーブルの作成(1)

記事テーブル(article)の作成

テーブルの設計

 今回作成するのは複数のスレッドが作成できる掲示板システムです。まず以下のような記事テーブル(article)を作成します。記事IDはシーケンスで自動生成される主キーで、スレッドを作成した場合「記事ID=スレッドID」のレコードを作成するようにします。スレッド内の記事を登録する場合、すでに存在するスレッドIDを指定して記事を登録します。スレッドIDを指定し記事ID順にArticleTableからレコードを取得すれば、スレッド内の記事一覧ができあがるという仕組みにします。

記事テーブル(article)
カラム名 データ型 備考
article_id bigint not null 記事ID(自動生成される主キー)
thread_id bigint スレッドID(記事ID=スレッドIDの場合スレッドの先頭記事)
title varchar(256) 記事タイトル
auther varchar(64) 著者
contents varchar(4096) 本文
delete_flag char(1) 削除フラグ
create_user_id bigint not null 作成者ID
create_timestamp timestamp not null 作成日時
update_user_id bigint not null 更新者ID
update_timestamp timestamp not null 更新日時

テーブルJavaクラスの作成

 dataforms.jarでは、テーブルの定義もJavaで行います。開発ツールの[テーブルJavaクラス作成]を使うと、テーブルクラスとそれに配置するフィールドクラスを効率よく作成することができます。テーブルJavaクラス作成のページを表示し、[新規作成]ボタンを押下すると、以下のページが表示されます。

テーブルJavaクラスの新規作成ページ
テーブルJavaクラスの新規作成ページ

 まず[機能]のプルダウンで「/bbs」を選択します。すると[パッケージ]に「bbs.dao」という文字列が表示されます。これはテーブルクラスを作成するパッケージになります。通常はこのパッケージを使用しますが、変更することも可能です。[テーブルクラス名]には「ArticleTable」と入力します。通常、テーブルクラス名には「AaaBbbTable」のように「Table」で終わる文字列を指定します。「AaaBbbTable」テーブルクラスを使用してデータベースにテーブルを作成すると「aaa_bbb」というテーブルが作成されます。[上書モード]は「上書きはエラー」のままにしておきます。[主キー自動生成]はチェックしておきます。

 フィールド一覧の[+]ボタンを押下し、フィールドを追加していきます。記事テーブル(article)を作成するには以下のようにフィールドを入力します。

記事テーブル(article)の作成
記事テーブル(article)の作成

 一般的なフィールド定義は、dataforms.jar中に定義されているフィールドクラスから派生した新たなクラスを作成し、そのクラスのインスタンスをテーブルに配置する作業になります。

 フィールドの行を追加すると、[パッケージ]には「bbs.field」がデフォルトで設定されています。フィールドのクラス名は「XxxYyyField」のように「Field」で終わる文字列を指定します。フィールドには常にフィールドIDが設定されます。フィールドIDを指定しない場合クラス名から自動的にデフォルトフィールドIDが設定されます。「XxxYyyField」クラスの場合、「xxxYyy」がデフォルトフィールドIDとなります。また、フィールドIDが「xxxYyy」の場合、対応するデータベーステーブルのカラム名は「xxx_yyy」となります。

 [基本クラスパッケージ]には「dataforms」がデフォルトで設定されています。[基本クラスパッケージ]を変更せず、[基本クラス]にdataforms.jar中のフィールドクラス名を入力すると、jQuery UIのオートコンプリート機能で存在するクラスの一覧が表示されます。一覧から使用したいクラスを選択すると、[基本クラスパッケージ]が適切に設定されます。

 主キーとなるArticleIdFieldクラスはRecordIdFieldから派生しています。主キー自動生成が指定されたテーブルで、主キーがRecordIdFieldから派生したフィールドの場合、レコードの追加時にシーケンスから自動的に生成されます。

 DeleteFlagFieldは、例外的にdataforms.jar中のテーブルクラスを派生せずに直接使用しています。[パッケージ]を「dataforms」に変更し、[クラス]に「Delete」と入力すると、オートコンプリート機能で入力候補が表示されます。一覧から選択すれば簡単に、dataforms.jar中のフィールドクラスを指定することができます。

 DeleteFlagFieldが存在するテーブルでは、問い合わせ実行時に「delete_flag='0'」の条件式が自動的に生成されます(この機能はOFFにすることも可能です)。

 このように入力された情報からテーブルJavaクラスを作成すると、以下のソースファイルが作成されます。

作成されたソースファイル一覧
パッケージ クラス 備考
bbs.dao ArticleTable.java 記事テーブルクラス
ArticleTableRelation.java 記事テーブルと他のテーブルとの関係を定義するクラス
bbs.field ArticleIdField.java 記事IDフィールドクラス
ThreadIdField.java スレッドIDフィールドクラス
TitleField.java 記事IDフィールドクラス
AutherField.java 著者フィールドクラス
ContentsField.java 本文フィールドクラス

 生成された「ArticleTable.java」の内容は以下のようになります。

生成されたArticleTable.java
package bbs.dao;

    ・・・ 中略   ・・・

/**
 * 記事テーブルクラス。
 *
 */
public class ArticleTable extends Table {
    /**
     * コンストラクタ。
     */
    public ArticleTable() {
        this.setAutoIncrementId(true);
        this.setComment("記事テーブル");
        this.addField(new ArticleIdField()); //記事ID
        this.addField(new ThreadIdField()); //スレッドID
        this.addField(new TitleField()); //記事タイトル
        this.addField(new AutherField()); //著者
        this.addField(new ContentsField()); //本文
        this.addField(new DeleteFlagField()); //削除フラグ

        this.addUpdateInfoFields();
    }

    @Override
    public String getJoinCondition(final Table joinTable, final String alias) {
        ArticleTableRelation r = new ArticleTableRelation(this);
        return r.getJoinCondition(joinTable, alias);
    }

    /**
     * Entity操作クラスです。
     */
    public static class Entity extends dataforms.dao.Entity {
        /** 記事IDのフィールドID。*/
        public static final String ID_ARTICLE_ID = "articleId";

        ・・・ 中略   ・・・

        /** 削除フラグのフィールドID。*/
        public static final String ID_DELETE_FLAG = "deleteFlag";

        /**
         * コンストラクタ。
         */
        public Entity() {

        }
        /**
         * コンストラクタ。
         * @param map 操作対象マップ。
         */
        public Entity(final Map<String, Object> map) {
            super(map);
        }
        /**
         * 記事IDを取得します。
         * @return 記事ID。
         */
        public java.lang.Long getArticleId() {
            return (java.lang.Long) this.getMap().get(Entity.ID_ARTICLE_ID);
        }

        /**
         * 記事IDを設定します。
         * @param articleId 記事ID。
         */
        public void setArticleId(final java.lang.Long articleId) {
            this.getMap().put(Entity.ID_ARTICLE_ID, articleId);
        }


        ・・・ 中略 ・・・

    }
    /**
     * 記事IDフィールドを取得します。
     * @return 記事IDフィールド。
     */
    public ArticleIdField getArticleIdField() {
        return (ArticleIdField) this.getField(Entity.ID_ARTICLE_ID);
    }

    /**
     * スレッドIDフィールドを取得します。
     * @return スレッドIDフィールド。
     */
    public ThreadIdField getThreadIdField() {
        return (ThreadIdField) this.getField(Entity.ID_THREAD_ID);
    }


        ・・・ 中略 ・・・

}

 ArticleTableのコンストラクタで、各フィールドを配置しています。コンストラクタの最後にある「this.addUpdateInfoFields();」で作成者ID、作成日時、更新者ID、更新日時の定番フィールドが配置されます。作成日時はCreateTimestampFieldクラス、更新日時はUpdateTimestampFieldクラスのフィールドが配置され、テーブルに対するInsertやUpdateの際、適切にタイムスタンプが設定されるようになります。また、これらのフィールドが不要であれば削除しても問題ありません。

 基本的にデータベース中のデータは、マップ(Map<String, Object>)の形式でやり取りします。マップを直接使用すると、文字列でフィールドIDを指定するため、そのフィールドIDやデータ型のキャストを間違える可能性が高くなります。そのため、Entityというインナークラスに、フィールドIDの定数やテーブルに対応したマップを操作するためのメソッドを用意しました。マップの操作にEntityクラスを使用すると、EclipseのJavaエディターの入力補助機能が効くので、IDの間違いやデータのキャストミスを回避することができます。

 ArticleTableのgetJoinConditionというメソッドではArticleTableRelationクラスのgetJoinConditionメソッドを呼び出しています。このメソッドで、他のテーブルとJOINする際の条件式を作成します。ArticleTableとその他のテーブル間の関係は、ArticleTableRelationクラスで定義します。「ArticleTableRelation.java」は基本的にテキストエディターで、結合条件を記述していきます。「ArticleTableRelation.java」に記述した後で、[テーブルJavaクラス作成]でテーブルクラスを呼び出し、テーブルの構造を修正することができます。その際ArticleTable.javaは更新しますが、ArticleTableRelation.javaの更新は行わないようになっています。「XxxTable.java」はテキストエディターでの編集も可能ですが、基本的に[テーブルJavaクラス作成]で編集するソースだと思ってください。

 生成されたフィールドクラスの例として、「ContentsField.java」を以下に示します。

生成されたContentsField.java
package bbs.field;

import dataforms.field.sqltype.VarcharField;
import dataforms.validator.MaxLengthValidator;


/**
 * ContentsFieldフィールドクラス。
 *
 */
public class ContentsField extends VarcharField {
    /**
     * フィールド長。
     */
    private static final int LENGTH = 4096;

    /**
     * フィールドコメント。
     */
    private static final String COMMENT = "本文";
    /**
     * コンストラクタ。
     */
    public ContentsField() {
        super(null, LENGTH);
        this.setComment(COMMENT);
    }
    /**
     * コンストラクタ。
     * @param id フィールドID。
     */
    public ContentsField(final String id) {
        super(id, LENGTH);
        this.setComment(COMMENT);
    }

    @Override
    protected void onBind() {
        super.onBind();
        this.addValidator(new MaxLengthValidator(this.getLength()));

    }
}

 フィールドクラスにはデフォルトコンストラクタとフィールドIDを引数に持つ2種類のコンストラクタが生成されています。デフォルトコンストラクタContentsField()を使用した場合、そのフィールドのIDは「contents」となります。[テーブルJavaクラス作成]のフィールドID欄は、同じクラスのフィールドを複数回配置する場合に使用します。フィールドIDに「contents2」と指定された場合、テーブルクラスコンストラクタにはthis.addField(new ContentsField("contents2"));の行が追加され、フィールドID指定のコンストラクタが呼ばれます。

 onBindメソッドはフィールドクラスのインスタンスをフォームに配置したタイミングで呼ばれます。この処理では、フォームの入力時に入力された最大文字数をチェックするためのバリデータを登録しています。バリデータはフォームでのみ動作し、テーブルに配置するフィールドでは不要なので、onBindで追加するようになっています。

開発ツールでのソース生成後の操作について

 開発ツールで各種ソースファイルを生成すると、ワークスペースの指定フォルダに「*.java」ファイルが作成されます。[テーブルJavaクラス作成]等は既存のテーブルクラスを検索し、それを再編集することができます。ただし、これらのツールはコンパイルされた「*.class」ファイルが検索対象です。そのため開発ツールで各種ソースを生成したら、すぐにビルド+デプロイし、Webアプリケーションに「*.class」を認識させる必要があります。Eclipse+Tomcat 8の環境では、クリーンビルドし、オートデプロイさせればOKです。

データベースのテーブル作成

 「ArticleTable.java」で定義した記事テーブルをデータベース上に作成するには開発ツールの[テーブル管理]を使用します。[テーブル管理]の[機能]プルダウンで「/bbs」を選択し検索すると、以下のように一覧にArticleTableが表示されます。背景が赤く表示されているのはデータベース上に対応するテーブルが存在しないことを意味しています。

テーブル管理
テーブル管理

 このテーブルをチェックし[初期化]ボタンを押下すると、以下のSQLが実行され、テーブルが作成されます。このSQLは接続しているデータベースシステムに適したものになります。今回はApache Derbyに接続しているので、Apache Derby用のSQLになります。

記事テーブル作成用SQL(Apache Derby用)
create table article (
article_id bigint not null
,thread_id bigint
,title varchar(256)
,auther varchar(64)
,contents varchar(4096)
,delete_flag char(1) default '0'
,create_user_id bigint not null
,create_timestamp timestamp not null
,update_user_id bigint not null
,update_timestamp timestamp not null
,primary key(article_id)
);

次のページ
テーブルの作成(2)

この記事は参考になりましたか?

特集記事連載記事一覧

もっと読む

この記事の著者

高柳 正彦(タカヤナギ マサヒコ)

経験年数30年を超えた、システムエンジニアです。一応管理職のはずですが、未だにコードを書いています。この仕事を長々とやっていると、それなりにノウハウがたまってきます。そのノウハウをまとめたものができないかと思い、独自のフレームワークを作り始めました。そのフレームワークもそれなりに使えるようになってき...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/10018 2017/05/15 14:00

おすすめ

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー