ページ

2015年2月14日土曜日

GAEと戯れる 16 - Polymorphic Model -

Slim3のPolymorphic Modelについて

Polymorphic Modelについてお勉強。
簡単に言えば・・・

A extends B
C extends B

のモデルがあった場合、BでqueryするとA, Cがヒットされ
AでqueryするとAだけがヒットされるという便利そうな仕組み。
プロパティが親子で重複するとエラーになる。

試しに作ってみた

・基底クラス
/**
 * 基底モデルクラス
 *
 * @author slowhand
 */
@Model
public abstract class BaseModel implements Serializable {

    /** デフォルトシリアルID */
    private static final long serialVersionUID = 1L;
   
    @Attribute(primaryKey = true)
    private Key key;

    @Attribute(version = true)
    private Long version;

    ・・・以下略・・・
}

・継承したクラス

@Model(schemaVersion = 1)
public class MemberListModel extends BaseModel {

    private static final long serialVersionUID = 1L;

    /** メンバー名 */    private String name;
   
    /** メールアドレス */
    private String mailAdr;

    ・・・以下略・・・
}

こうするとmetaクラスがBaseModelとMemberListModel用の2つ作成される。





それぞれのMetaクラスのコンストラクタで階層を作成している。
・BaseModelMeta





・MemberListModelMeta




参考URL
http://d.hatena.ne.jp/bufferings/20100121/1264093364

簡単な登録・参照ページを作成してみる。
・member_list.jsp
<%@page pageEncoding="UTF-8" isELIgnored="false" session="false"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@taglib prefix="f" uri="http://www.slim3.org/functions"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>メンバーリスト</title>
</head>
<body>
<p>新規登録</p>
<form method="post" action="/settings/memberList">
<table>
<tr><td>名前</td><td><input type="text" ${f:text("name")}></td></tr>
<tr><td>メールアドレス</td><td><input type="text" ${f:text("mail")}></td></tr>
<tr><td></td><td><input type="submit"></td></tr>
</table>
</form>
<hr>
<table border="1">
<c:forEach var="member" items="${members}">
<tr>
<td>${member.key}</td>
<td>${member.name}</td>
<td>${member.mailAdr}</td>
</tr>
</c:forEach>
</table>
</body>
</html>

・MemberListController
public class MemberListController extends BaseController {

    private static final String RETURN_PATH = "member_list.jsp";
   
    private static final String PROPERTY_NAME = "name";
    private static final String PROPERTY_MAILADR = "mail";
   
    private static final String PROPERTY_MEMBERS = "members";
   
    @Override
    public Navigation run() throws Exception {
        if (isPost()) {
            register();
        }
       
        // メンバー一覧の取得
        List<MemberListModel> memberList = Datastore.query(MemberListModel.class).asList();
        request.setAttribute(PROPERTY_MEMBERS, memberList);
        return forward(RETURN_PATH);
    }
   
    /**
     * メンバー新規登録
     */
    private void register() {
        String name = asString(PROPERTY_NAME);
        String mailAdr = asString(PROPERTY_MAILADR);
       
        MemberListModel memberListModel = new MemberListModel();
        memberListModel.setKey(Datastore.allocateId(MemberListModelMeta.get()));
        memberListModel.setName(name);
        memberListModel.setMailAdr(mailAdr);
        // データストアに新規登録
        Datastore.put(memberListModel);
    }
}

・実行結果























・データストアの中身









Entityは基底クラスのBaseModelしか作成されておらず、
フィールドのslim3.classHierarchyListにサブクラスが設定されている。
query時にはこの項目をwhereに追加し検索する。

※idフィールドを作成し、auto incrementにしようとしたが、
   entityのKeyにIDで採番が可能。
   Entity#setKey(Datastore.allocateId(EntityMeta.get()));
参考URL
http://www.casleyconsulting.co.jp/blog-engineer/gae/【入門編】slim3で始める!gaejでwebアプリケーション開-4/

0 件のコメント:

コメントを投稿