🤔

EclipseでHibernateを使う方法を学んだけど所々やってることがよくわからない

2022/02/05に公開約10,600字

概要

EclipseでHibernateを使う方法を学んだけど所々やってることがよくわからないので、できる限り用語とか設定の意味を調べながらまとめてみる。
(結果、意味が分からないこと多いしめんどくさいし複雑なSQL相当のことはできなさそうだし、いらないんじゃないかと思う)

目次

1. 環境

  • Windows10 Home 20H2
  • Eclipse 2020-12(4.18.0) ※Pleiades All in One
    • Maven Integration for Eclipse 1.19.0
  • MySQL 8.0.23 (ローカル環境)
  • Hibernate 5.4.28

※MavenやMySQLについての詳細はこの記事では触れない。

2. Hibernateについて

  • JavaでDBと接続する時、楽に実装できるようにするためのO/Rマッピングという種類のフレームワークがある(→ORマッパーと呼ばれてたりする)
  • そのO/RマッピングをJavaのAPI仕様としてまとめたものがJPA(Java Persistence API)。
  • JPAは仕様を定義しているだけ。それを実装したものの1つがHibernate。

3. プロジェクト設定

3.1. プロジェクト作成

  1. 新規プロジェクト

  2. 名前を付けて(今回はhibernate_test)、次へ。

  3. module-info.javaのチェックを外して完了。

  4. プロジェクトを右クリックしてMavenプロジェクトへ変換。
    (MySQLドライバとHibernateのインストールをMavenに任せるため)

  5. 設定はとりあえずそのままで完了。

3.2. MySQLドライバとHibernateをプロジェクトにインストール

  1. プロジェクトがMavenプロジェクトに変換されるとpom.xmlが開かれるので依存関係タブをクリックして追加ボタンをクリック。

  2. 下記情報を入力してpom.xmlを保存。(MySQLとHibernateをインストールする。)

    • MySQL
      • グループId:mysql
      • アーティファクトId:mysql-connector-java
      • バージョン:8.0.23
    • Hibernate
      • グループId:org.hibernate
      • アーティファクトId:hibernate-core
      • バージョン:5.4.28.Final

3.3. Hibernateの設定

  1. プロジェクトをJPAプロジェクトに変更する。
    プロジェクトを右クリックして構成JPAプロジェクトへ変換
    とりあえずJPA仕様のアプリ作るにはJPAプロジェクトにしなきゃいかんらしい。

  2. プロジェクトファセットとやらを設定する画面になる。

    • 構成を基本JPA構成にする。他にもいくつか構成があって、その構成によってファセットのセットが変わるようだ。
    • 基本JPA構成にした時点でJavaとJPAが選ばれた状態になる。バージョンは環境に合わせて変えた方がいいのかもしれない。
    • 次へ
  1. この画面では特に何も変えずに次へ。なんの画面なんだよ。

  2. JPAファセットとやらを設定する画面になる。いやだからファセットってなんなんだよ。

    • プラットフォーム:なんなんプロットフォームって。今の環境だとGeneric2.2しか選択できないからいいけど、Genericの意味もわからんし。
    • JPA実装:ひとまずライブラリー構成を無効、にする。調べても全然わからん。
    • 接続:なししか選べない。なにと接続するんだよ。
    • 永続化クラス管理:注釈付きクラスをpersistence.xmlに記述を選択。永続化クラス管理も意味わからないし注釈付きクラスも意味がわからない。お前は何を言っているんだ?

  3. src/META-INFにpersistence.xmlが追加されるので開く。

  4. 永続化プロバイダーにorg.hibernate.jpa.HibernatePersistenceProviderと入力する。
    永続化プロバイダーってなんだよ。入力する値もどこから現れたんだよ。

  5. 接続タブに移って下記入力。もちろん永続化ユニットが何かはわからない。なんやねん。

    • トランザクション・タイプ:リソース・ローカル(今回はローカルのDBだからなのか?関係無いか。)
    • JDBC接続プロパティ ここは普通にJDBC接続するときの情報。
      • ドライバー:com.mysql.cj.jdbc.Driver
      • URL:jdbc:mysql://localhost/world?useSSL=false&allowPublicKeyRetrieval=true
      • ユーザー:DBに接続するユーザー名
      • パスワード:パスワードだよ。

  6. プロパティタブに移って下記を入力する。便利になる設定なんですって。知らんけど。

    • 名前:hibernate.dialect
      値:org.hibernate.dialect.MySQL8Dialect
      dialectって方言って意味ですって。DBの方言を吸収する設定らしいよ。Postgresql用の値もあるようだ。
    • 名前:hibernate.show_sql
      値:true
      発行したSQLを標準出力に出してくれるんですって。
    • 名前:hibernate.format_sql
      値:true
      表示するSQLを自動で整形してくれるんですって。

  7. persistence.xmlを保存する。なんかこの時ソースタブを開いて保存するとユーザー名とパスワード消えた、バグか?
    なので接続タブとか開いた状態で保存した方がいいかも。

4. 対象のDB・テーブル

こんな感じのDB・テーブルからデータを取ってくる。
(MySQLの公式サイトで配布されているworldというサンプルDBのcityテーブル)

5. ソース

5.1. DTOクラス

JPAのアノテーションを付けて記述するそうな。これでももうめんどくさい。

アノテーション 説明 指定先 必須
@Entity クラスがEntityクラスであることを指定 クラス 必須
@Table テーブル名を指定 クラス クラス名とテーブル名が同じであれば省略可能
@Id 主キーのフィールドに指定 フィールド 必須
@Column テーブルのカラム名を指定 フィールド クラスのフィールド名とテーブルのカラム名が同じであれば省略可能
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="city")
public class City {
    // プロパティ
    @Id
    @Column(name = "ID")
    private Integer id;

    @Column(name = "Name")
    private String name;

    @Column(name = "CountryCode")
    private String countryCode;

    @Column(name = "District")
    private String district;

    @Column(name = "Population")
    private int population;

    {各プロパティのGetter/Setter}

}

尚、「クラス “entity.City” は管理されていますが、persistence.xml ファイルにリストされていません」というエラーが出る。

またpersistence.xmlを開いて、管理クラスにCityクラスを追加しなきゃいけないらしい。知らんがな。

5.2. DAOクラス

とりあえずここはおまじない的に書くらしい。
PERSISTENCE_UNIT_NAMEはpersistence.xmlの一般タブに書いてある名前だそうな。

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class DBUtil {
    private static final String PERSISTENCE_UNIT_NAME = "hibernate_test";
    private static EntityManagerFactory emf;

    public static EntityManager createEntityManager() {
        return getEntityManagerFactory().createEntityManager();
    }

    private static EntityManagerFactory getEntityManagerFactory() {
        if(emf == null) {
            emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
        }

        return emf;
    }
}

5.3. mainクラス

もはや説明書くのめんどくさい。

import javax.persistence.EntityManager;

import entity.City;
import util.DBUtil;

public class HibernateTest {

    public static void main(String[] args) {
        // EntityManagerのオブジェクトを生成
        EntityManager em = DBUtil.createEntityManager();

        // 1件取得して名前を表示する
        City city = em.find(City.class, 1);
        System.out.println(city.getName());

        // EntityManagerの利用を終了する
        em.close();
    }
}

6. 実行結果

なんかログが出て、em.find(City.class,1で指定した通りのid=1のデータが返ってくる。

INFO: HHH000204: Processing PersistenceUnitInfo [name: hibernate_test] 
INFO: HHH000412: Hibernate ORM core version 5.4.28.Final 
INFO: HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
INFO: HHH10001005: using driver [com.mysql.cj.jdbc.Driver] at URL [jdbc:mysql://localhost/world?useSSL=false&allowPublicKeyRetrieval=true]
INFO: HHH10001001: Connection properties: {password=****, user=root}
INFO: HHH10001003: Autocommit mode: false
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
Hibernate: 
    select
        city0_.ID as id1_0_0_,
        city0_.CountryCode as countryc2_0_0_,
        city0_.District as district3_0_0_,
        city0_.Name as name4_0_0_,
        city0_.Population as populati5_0_0_ 
    from
        city city0_ 
    where
        city0_.ID=?
Kabul

7. Hibernateを使ってみて

  • 機能としては置いといて、言葉が意味不明なことが多くて気になって仕方ない。
  • ひとまず学んだ通りにはできるが、なんでその値を入力するのかとかわかってないから応用がきかない。
  • ちゃんと使うならJPAの仕様書を読んだ方がいいそうな。
  • あんまり便利さ感じない。

8. (参考)他のO/Rマッパー

Hibernate以外にもO/Rマッパーはある。

  • MyBatis
  • Doma
  • Spring JDBC
  • EclipseLink
  • JOOQ
  • DBFlute

9. (参考)JPAとかの参考情報

https://terasolunaorg.github.io/guideline/5.5.1.RELEASE/ja/ArchitectureInDetail/DataAccessDetail/DataAccessJpa.html

https://software.fujitsu.com/jp/manual/manualfiles/M090096/B1WD1461/02Z200/B1461-00-04-01-01.html

https://atmarkit.itmedia.co.jp/fdb/rensai/javapersis01/javapersis01_2.html

https://www.slideshare.net/masatoshitada7/java-or-jsug

https://gist.github.com/momotar/7518092d8e49761bb558#file-jpa-md

https://segakuin.com/java/jpa/annotation.html

https://blog1.mammb.com/entry/20090830/1251606823

Discussion

ログインするとコメントできます