R e i - D r e a m
for Laravel
Guest
login

最終投稿日:2026年08月09日

DAO(データ・アクセス・オブジェクト)

エンティティ作成

エンティティとは一言でいうと『テーブル構造(および1行のデータ)』です。
アノテーションを使い、JAVAとテーブル構造をマッピングしたものとなります。
一般的にパッケージ『entity』で管理するので、あらかじめ作成しておきましょう。
それでは以下手順でエンティティを作成してみましょう。
・「プロジェクト名」> 右クリック >「JPAツール」>「テーブルからエンティティを生成..」
・『テーブル選択』画面がPOPしますので、[接続]アイコンをクリックします。
・すると唯一作成した『users』が表示されるのでチェックし「次へ」押下
・更に「次へ」押下
・『デフォルトのカスタマイズ』画面となるので以下を設定します。
    ・パッケージ:entity
・『完了』押下
『persistence.xml』を確認してみましょう。
以下テーブル情報が追加されているのが確認できると思います。
    <class>entity.User</class>
※JAVAの命名規則として単数形になるっぽいです
次に先ほど作成した『entity』を確認しましょう。
『User.java』が自動的に作成されていますね。
ポイント

クラス名がエラーになっている場合。
まずその状態でビルドが通るか確認して下さい。
仮にビルドが通らない場合はガチのエラーですので、設定を見直しましょう。
  ※データソース名の大文字小文字等

ビルドが通る場合は、エクリプスの不具合ですので、以下の方法でチェックを無効にします。
・プロジェクト > 右クリック > プロパティ
・左メニュー > JPA > エラー/警告
・「プロジェクト固有の設定を可能にする」にチェックを入れる
・「永続化単位」のアコーディオンを展開する
・「persistence.xml ファイルにリストされているが注釈されていないクラス」を警告にする
・「適用」「適用して閉じる」押下

注意!!

テーブルに『AUTO_INCREMENT』属性がある場合、エンティティには反映されません。
色々と不具合の温床となるので、以下の様にアノテーションを付与しましょう。

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

DAOを作成し、DBアクセスする

DAO(データ・アクセス・オブジェクト)とは、名前の通りデータベースにアクセスする為のオブジェクトを指します。
MVCフレームワークにおける『モデル』の要的存在となり、データベース操作を担当します。
一般的に使われるパッケージ名は、そのまま『dao』です。
まずは共通の基底クラスを作成します。
ファイル名名を『dao/BaseDao.java』で作成します。
BaseDao.java

package dao;

import java.io.Serializable;
import java.util.List;
import java.util.Optional;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;

public abstract class BaseDao<T, ID> implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @PersistenceContext(unitName = "myMysqlUnit")
    protected EntityManager em;
    
    private final Class<T> entityClass;
    
    public BaseDao(Class<T> entityClass) {
        this.entityClass = entityClass;
    }
    // 保存
    public void create(T entity) {
        em.persist(entity);
    }
    // 主キーによる検索
    public Optional<T> findById(ID id) {
        return Optional.ofNullable(em.find(entityClass, id));
    }
    // 全件検索
    public List<T> findAll() {
        String jpql = "SELECT e FROM " + entityClass.getSimpleName() + " e";
        return em.createQuery(jpql, entityClass).getResultList();
    }
    // 更新
    public T update(T entity) {
        return em.merge(entity);
    }
    // 削除
    public void delete(T entity) {
        em.remove(em.contains(entity) ? entity : em.merge(entity));
    }
    // IDによる削除
    public void deleteById(ID id) {
        findById(id).ifPresent(this::delete);
    }
}

ポイント

クラス『EntityManager』がDBを制御する実態となります。
『@PersistenceContext(unitName = "myMysqlUnit")』に注目して下さい。
《myMysqlUnit》は『persistence.xml』で設定した名前となり、このマッピングにより最終的なWildflyが管理するデータソースと連携できます。

因みにpersistence.xmlのユニット名は複数登録する事が可能です。 今回の様に1つしか設定してない場合は『@PersistenceContext』のみで、ユニット名を省略できます。

次にテーブル単位のDAOを作成します。
先ほど作成した『User』クラスのDAOを作成するので、ファイル名は当然『UserDao.jva』となります。
作成したら以下の様に修正します。
UserDao.java

package dao;

import java.util.List;
import entity.User;
import jakarta.enterprise.context.Dependent;

@Dependent
public class UserDao extends BaseDao<User, Integer> {
    private static final long serialVersionUID = 1L;
    public UserDao() {
        super(User.class);
    }
    // 独自の検索クエリ
    public List<User> findByName(String name) {
        return em.createQuery(
                "SELECT u FROM User u WHERE u.name = :name", User.class)
                .setParameter("name", name).getResultList();
    }
}

ポイント

継承する『BaseDao』に連携するジェネリクスの2つ目は『Integer』としています。
これは1つ目の『User』クラスの主キーの型を指定する必要があります。

それでは、DBにアクセスしてみましょう。
『SampleBean.java』のコンストラクタを以下の様に修正します。
SampleBean.java

@Inject
private UserDao dao;
~ 省略 ~
@Override

protected void initialize() {
    dto.setName("");
    dto.setMemo("");

    List<User> users = dao.findByName("hoge太郎");
    System.out.println("----------------------------");
    for (User user : users) {
        String hoge = user.getName();
        System.out.println(hoge);
    }
    System.out.println("----------------------------");
}

ビルドしてアクセスしてみましょう。
エクリプスのコンソールに注目です。
...。
コンソール

21:46:17,608 INFO [stdout] (default task-1) ----------------------------

21:46:17,821 INFO [stdout] (default task-1) ----------------------------

う~ん、実感がわきませんね。
それもそのハズ。テーブルにデータがありません。
では手動で以下の情報を登録してみましょう。
insert into users (mail, pass, name) values ('hoge@hoge.com', 'hoge0000', 'hoge太郎');
insert into users (mail, pass, name) values ('foo@hoge.com', 'foo0000', 'foo太郎');
再度ブラウザでアクセス(GET遷移)してみて下さい。
今度は『hoge太郎』とコンソールに表示されるハズです。

DAO具象クラスについて

基本的には親クラスである『BaseDao』が《CRUD》の面倒は見てくれます。
  ※ C=Create、R=Read(select)、U=Update、D=Delete
でも個別のDAOでは何かと複雑なSQLを作成する要件が発生しがちですよね。
常に思ってる事なのですが、様々なフレームワークにはSQLを扱う『仕組み』が用意されています。
でもそれって、複雑なSQLだと無力ですよね(JOIN..EXISTS..など)。
何が言いたいかと言うと、
  『結局平文が一番強い!』です。
先ほど作成した『UserDao』の、関数「findByName」を覚えていますか?
その中の以下文字列
    "SELECT u FROM User u WHERE u.name = :name"
これ平文じゃありませんよ。
テーブル名は『users』でしたね。上記はクラス名です!
平文のSQLで記述する場合は以下の様に修正する必要があります。
UserDao.java

@SuppressWarnings("unchecked")
public List<User> findByName(String name) {
    final String sql = "SELECT * FROM users WHERE name = :name";
    return em.createNativeQuery(sql, User.class).setParameter("name", name).getResultList();
}

平文にした事で『本当にUserクラスの値を返却するの?』と疑われて警告がでます。
かなりウザいので『@SuppressWarnings("unchecked")』を付与して警告を非表示にしています。
ログインしてコメントを残そう!!


きっぷる