データの取得

今回はJPA2.0によるデータの取得です。

【前提条件】

[環境]
[その他]
  • JPAの設定が完了している*1

【概要】

今回はテーブルからPKをキーにデータを取得というサンプルです。

JPA2.0によるエンティティの設定と
エンティティの取得を行います。

取得したデータはJSFを使用して表示させます。

【サンプルコード】

[テーブル]

ユーザデータ「userdata」というテーブルを作成します。

CREATE TABLE userdata
(
    user_id character varying(10) NOT NULL,
    name character varying(60),
    last_update timestamp with time zone NOT NULL DEFAULT now(),
    CONSTRAINT user_primary_key PRIMARY KEY (user_id)
)

PKとして文字列型のユーザIDを持ちます。
その他の項目として
■ユーザ名(文字列)
■最終更新日(Timestamp:デフォルト値 システム日付)
を持ちます。

データは↓のようなデータを登録しておきます。

[Entity]

テーブルに対応するエンティティのクラスを作成します。

package jp.glory.persistence.entity;

import java.sql.Timestamp;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "userdata")
public class UserData {

    @Id
    @Column(name = "user_id")
    private String userId = null;

    private String name = null;

    @Column(name = "last_update")
    private Timestamp lastUpdate = null;

    // アクセサメソッドは省略
}

エンティティのクラスはjavax.persistence.Entityアノテーションを使います。

javax.persistence.Tableアノテーションによりテーブルの設定を行います。
サンプルでは対応するテーブルのテーブル名が「userdata」なので、
name属性に「userdata」を指定します。

Tableアノテーションをつけなかった場合、
デフォルトの設定でテーブル名はクラス名の大文字となります。
サンプルでは「USERDATA」となるので、Tableアノテーションをつけなくても動きます。

カラムの設定はjavax.persistence.Columnアノテーションを使います。
サンプルではname属性のみを指定しいてます。
name属性は対応するカラムのカラム名を指定します。
Tableアノテーションと同様にColumnアノテーションをつけなかった場合、
デフォルトでプロパティ名の大文字となります。

PKとなるカラムにはjavax.persistence.Idアノテーションをつけます。

カラムに対応する型についてですが、
JSRの仕様書*2に書いてあります。
詳細は「To view the specification for evaluation, click here」の
「download」ボタンの先にある「persistence-2_0-final-spec.pdf」を参照してください。

「2.2 Persistent Fields and Properties」に対応する型が書かれています。
(24ページあたり)

プリミディブ、文字列、任意精度数値、日付、バイナリ(バイト配列)は
サポートしているようです。

[persistence.xml]

persistence.xmlの設定です。

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
    xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

    <persistence-unit name="blog" transaction-type="JTA">
        <jta-data-source>jdbc/blog</jta-data-source>
        <class>jp.glory.persistence.entity.UserData</class>
    </persistence-unit>
</persistence>

前回の設定からclassタグを追加しています。

classタグにはエンティティクラスを指定します。
classタグを指定せずにエンティティクラスを使用すると
実行時に↓のようなメッセージが表示されます。
(読みやすいように途中で改行しています)

java.lang.IllegalArgumentException: Unknown entity bean class:
    class jp.glory.persistence.entity.UserData,
    please verify that this class has been marked with the @Entity annotation.
[データ取得]

エンティティクラスのデータを取得する処理です。

package jp.glory.ui;

import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import jp.glory.persistence.entity.UserData;

@ManagedBean(name = "userListPage")
@RequestScoped
public class UserListPage {

    private List<UserData> userList = null;

    public UserListPage() {

        EntityManagerFactory factory = Persistence.createEntityManagerFactory("blog");
        EntityManager manager = factory.createEntityManager();

        userList = new ArrayList<>();
        userList.add(manager.find(UserData.class, "USER-0001"));
        userList.add(manager.find(UserData.class, "USER-0002"));
        userList.add(manager.find(UserData.class, "USER-0003"));
    }

    // アクセサメソッドは省略
}

エンティティの操作を行うためのベースとなるクラスが
javax.persistence.EntityManagerクラスです。

EntityManagerクラスのオブジェクトを取得するためには
javax.persistence.EntityManagerFactoryクラスを使用します。

EntityManagerFactoryクラスのオブジェクトは
javax.persistence.Persistence#createEntityManagerFactoryメソッドを使用して取得します。
createEntityManagerFactoryメソッドには
persistence.xmlで定義したpersistence-unitの名称(name属性で指定したもの)を指定します。

サンプルでは「blog」という名前で定義したので、
「blog」をパラメータとして渡しています。

EntityManagerFactory#createEntityManageメソッドを使用して、
EntityManagerクラスのオブジェクトを取得します。

ここまででエンティティを使用する準備が整います。

PKによるデータの取得はEntityManager#findメソッドを使用します。
findメソッドはオーバーロードされているので、いくつかパターンがあります。

サンプルでは基本となるエンティティクラスの指定とPKの値を指定しています。

[ページ]

サンプルの画面表示コードです。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html">
    <f:view>
        <h:dataTable value="#{userListPage.userList}" var="user">
            <h:column>
                <f:facet name="header">
                    ユーザID
                </f:facet>
                <h:outputText value="#{user.userId}" />
            </h:column>
            <h:column>
                <f:facet name="header">
                    ユーザ名
                </f:facet>
                <h:outputText value="#{user.name}" />
            </h:column>
            <h:column>
                <f:facet name="header">
                    最終更新日
                </f:facet>
                <h:outputText value="#{user.lastUpdate}" >
                    <f:convertDateTime pattern="yyyy/MM/dd HH:mm:ss.SSS" timeZone="JST"/>
                </h:outputText>
            </h:column>
        </h:dataTable>
    </f:view>
</html>

【実行】

ページにアクセスします。

データが取得できました。