EclipseでHibernateを使う方法を学んだけど所々やってることがよくわからない
概要
EclipseでHibernateを使う方法を学んだけど所々やってることがよくわからないので、できる限り用語とか設定の意味を調べながらまとめてみる。
(結果、意味が分からないこと多いしめんどくさいし複雑なSQL相当のことはできなさそうだし、いらないんじゃないかと思う)
目次
- 1. 環境
- 2. Hibernateについて
- 3. プロジェクト設定
- 4. 対象のDB・テーブル
- 5. ソース
- 6. 実行結果
- 7. Hibernateを使ってみて
- 8. (参考)他のO/Rマッパー
- 9. (参考)JPAとかの参考情報
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. プロジェクト作成
-
新規プロジェクト
-
名前を付けて(今回はhibernate_test)、次へ。
-
module-info.javaのチェックを外して完了。
-
プロジェクトを右クリックしてMavenプロジェクトへ変換。
(MySQLドライバとHibernateのインストールをMavenに任せるため)
-
設定はとりあえずそのままで完了。
3.2. MySQLドライバとHibernateをプロジェクトにインストール
-
プロジェクトがMavenプロジェクトに変換されるとpom.xmlが開かれるので
依存関係
タブをクリックして追加
ボタンをクリック。
-
下記情報を入力して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
- MySQL
3.3. Hibernateの設定
-
プロジェクトをJPAプロジェクトに変更する。
プロジェクトを右クリックして構成
→JPAプロジェクトへ変換
。
とりあえずJPA仕様のアプリ作るにはJPAプロジェクトにしなきゃいかんらしい。
-
プロジェクトファセットとやらを設定する画面になる。
- 構成を
基本JPA構成
にする。他にもいくつか構成があって、その構成によってファセットのセットが変わるようだ。 -
基本JPA構成
にした時点でJavaとJPAが選ばれた状態になる。バージョンは環境に合わせて変えた方がいいのかもしれない。 - 次へ
- 構成を
-
この画面では特に何も変えずに次へ。なんの画面なんだよ。
-
JPAファセットとやらを設定する画面になる。いやだからファセットってなんなんだよ。
- プラットフォーム:なんなんプロットフォームって。今の環境だとGeneric2.2しか選択できないからいいけど、Genericの意味もわからんし。
- JPA実装:ひとまずライブラリー構成を無効、にする。調べても全然わからん。
- 接続:なししか選べない。なにと接続するんだよ。
- 永続化クラス管理:注釈付きクラスをpersistence.xmlに記述を選択。永続化クラス管理も意味わからないし注釈付きクラスも意味がわからない。お前は何を言っているんだ?
-
src/META-INFにpersistence.xmlが追加されるので開く。
-
永続化プロバイダーに
org.hibernate.jpa.HibernatePersistenceProvider
と入力する。
永続化プロバイダーってなんだよ。入力する値もどこから現れたんだよ。
-
接続タブに移って下記入力。もちろん永続化ユニットが何かはわからない。なんやねん。
- トランザクション・タイプ:リソース・ローカル(今回はローカルのDBだからなのか?関係無いか。)
- JDBC接続プロパティ ここは普通にJDBC接続するときの情報。
- ドライバー:com.mysql.cj.jdbc.Driver
- URL:jdbc:mysql://localhost/world?useSSL=false&allowPublicKeyRetrieval=true
- ユーザー:DBに接続するユーザー名
- パスワード:パスワードだよ。
-
プロパティタブに移って下記を入力する。便利になる設定なんですって。知らんけど。
- 名前:hibernate.dialect
値:org.hibernate.dialect.MySQL8Dialect
dialectって方言って意味ですって。DBの方言を吸収する設定らしいよ。Postgresql用の値もあるようだ。 - 名前:hibernate.show_sql
値:true
発行したSQLを標準出力に出してくれるんですって。 - 名前:hibernate.format_sql
値:true
表示するSQLを自動で整形してくれるんですって。
- 名前:hibernate.dialect
-
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とかの参考情報
Discussion