この記事では、Java の最も人気のあるエンタープライズ フレームワークの 1 つについて理解し、最初の Hibernate アプリケーションを作成します。Hibernate について聞いたことがありませんか? それとも聞いたことはあるけど使ったことはないのでしょうか?それとも、使おうとして失敗したのでしょうか?3 つのケースすべてにおいて - カットの下へようこそ :) 皆さん、こんにちは!この記事では、Hibernate フレームワークの主な機能について説明し、初めてのミニアプリケーションを作成するのに役立ちます。このためには、次のものが必要です。
- IntelliJ IDEA Ultimate Edition公式 Web サイト
からダウンロードし、30 日間の試用版をアクティベートします。 - PostgreSQL - 最も人気のある最新のデータベース管理システム (DBMS) の 1 つ
- Maven (IDEA に接続済み)
- 少しの忍耐。
休止状態とは何ですか?
これは、最も一般的なオブジェクト リレーショナル マッピング (ORM) 実装の 1 つです。オブジェクト リレーショナル マッピングは、ソフトウェア オブジェクトとデータベース レコードの間の関係を定義します。もちろん、Hibernate には非常に幅広い機能がありますが、ここでは最も単純な機能に焦点を当てます。私たちの目標は、次のことができる CRUD (作成、読み取り、更新、削除) アプリケーションを作成することです。- ユーザー (ユーザー) を作成し、ID でデータベース内で検索し、データベース内のデータを更新し、データベースから削除します。
- 車のオブジェクト (自動) をユーザーに割り当てます。データベースから車を作成、更新、検索、削除します。
- さらに、アプリケーションは「所有者のいない」車をデータベースから自動的に削除する必要があります。つまり、ユーザーが削除されると、そのユーザーに属するすべての車もデータベースから削除する必要があります。
com.yourNickname.codegym
。これはアプリケーションには影響しません。artifactId には、任意のプロジェクト名を選択します。バージョンは変更しないままにすることができます。 最後の画面では、以前に入力したデータを確認するだけです。そこで、プロジェクトを作成しました。あとはコードを書いて動作させるだけです :) まず最初に: データベースで動作するアプリケーションを作成したい場合は、データベースなしでは絶対にできません。ここから PostgreSQL をダウンロードします(バージョン 9 を使用しています)。PostgreSQL にはデフォルトのユーザー「postgres」があり、インストール時にそのパスワードを考える必要があります。パスワードを忘れないでください。後で必要になります! (一般に、アプリケーションでデフォルトのデータベースを使用するのは悪い習慣ですが、独自のデータベースを作成することで潰瘍の原因の数を減らすためにそうします)。コマンドラインや SQL クエリに詳しくない方に朗報です。IntelliJ IDEA は、データベースを操作するための完全に適切なユーザー インターフェイスを提供します。 (IDEA の右ペインの [データベース] タブにあります)。接続を作成するには、「+」をクリックしてデータ ソース (PostgeSQL) を選択します。ユーザーとデータベース (両方とも「postgres」) のフィールドに入力し、PostgreSQL のインストール時に設定したパスワードを入力します。必要に応じて、Postgres ドライバーをダウンロードします。これは同じページで行うことができます。「接続のテスト」をクリックして、データベース接続が確立されていることを確認します。「成功」と表示されたら、次に進みます。次に、必要なテーブルを作成します。ユーザーと自動車の合計 2 つが存在します。users テーブルのパラメータ: id が主キーであることに注意してください。SQL の主キーがわからない場合は、Google で調べてください。これは重要。autos テーブルの設定: autos テーブルの場合は、外部キーを構成する必要があります。これはテーブルをリンクするのに役立ちます。詳しく読むことをお勧めします。簡単に言うと、外部テーブル (この場合はユーザー) を参照します。車が ID = 1 のユーザーに属している場合、自動車の user_id フィールドは 1 になります。これが、アプリケーションでユーザーと車を関連付ける方法です。autos テーブルでは、user_id フィールドが外部キーとして機能します。これは、users テーブルの id フィールドを参照します。 したがって、2 つのテーブルを持つデータベースを作成しました。残るのは、Java コードからそれを管理する方法を理解することです。pom.xml ファイルから始めます。このファイルには、必要なライブラリ (Maven では依存関係と呼ばれます) を含める必要があります。すべてのライブラリは中央の Maven リポジトリに保存されます。pom.xml で指定したライブラリは、プロジェクトで使用できます。pom.xml は次のようになります。 ご覧のとおり、複雑なことは何もありません。追加した依存関係は、PostgreSQL と Hibernate を使用するための 2 つだけです。次に、Java コードに移りましょう。プロジェクトに必要なパッケージとクラスをすべて作成します。まず、データ モデル、User
とAuto
クラスが必要です。
package models;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table (name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "name")
private String name;
// You can omit the Column attribute if the name property matches the column name in the table
private int age;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Auto> autos;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
autos = new ArrayList<>();
}
public void addAuto(Auto auto) {
auto.setUser(this);
autos.add(auto);
}
public void removeAuto(Auto auto) {
autos.remove(auto);
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<Auto> getAutos() {
return autos;
}
public void setAutos(List<Auto> autos) {
this.autos = autos;
}
@Override
public String toString() {
return "models.User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
package models;
import javax.persistence.*;
@Entity
@Table(name = "autos")
public class Auto {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column (name = "model")
private String model;
// You can omit the Column attribute if the name property matches the column name in the table
private String color;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
public Auto() {
}
public Auto(String model, String color) {
this.model = model;
this.color = color;
}
public int getId() {
return id;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return color + " " + model;
}
}
ご覧のとおり、クラスには不明瞭な注釈が多数含まれています。それらを掘り下げてみましょう。私たちにとって、主なアノテーションは @Entity です。ウィキペディアでそれについて読んで、すべてを暗記してください。これが基礎中の基礎です。このアノテーションにより、Java クラスのオブジェクトをデータベースにマッピングできるようになります。クラスがエンティティになるには、次の要件を満たす必要があります。
public
空のコンストラクター (またはprotected
)が必要です。- インターフェイスやネストすることはできません。
enum
- フィールド/プロパティを持つことはできず、フィールド/プロパティ
final
を持つこともできませんfinal
- 少なくとも 1 つの @Id フィールドが必要です。
- 空ではないコンストラクターを含めることができます
- 受け継ぐことも受け継がれることもできる
- 他のメソッドを持ち、インターフェイスを実装することもできます。
User
クラスは users テーブルと非常によく似ています。id
、name
、およびage
田畑。その上にある注釈については特に説明する必要はありません。@Id がフィールドがこのクラスのオブジェクトの識別子であることを示していることは明らかです。クラスの上の @Table 注釈は、オブジェクトが書き込まれるテーブルの名前を示します。age フィールドの上のコメントに注意してください。クラス内のフィールドの名前がテーブルの名前と同じ場合は、@Column アノテーションを省略しても機能します。中括弧内(「strategy = GenerationType.IDENTITY」)については、ID を生成するための戦略がいくつかあります。Google で検索することもできますが、このアプリケーションの場合は、わざわざ検索する必要はありません。重要なことは、オブジェクトの id の値が自動的に生成されることです。したがって、id のセッターは存在せず、コンストラクターにも設定しません。しかし、User
クラスは目立ちます。車種リストあります! @OneToMany アノテーションがリストの上にハングします。これは、複数の車が User クラスの同じオブジェクトに対応できることを意味します。「mappedBy」要素は、クラスのユーザー フィールドを参照しますAuto
。このように、クルマとユーザーは密接な関係にあります。orphanRemoval 要素は、関係がなくなったエンティティに削除操作を適用するかどうかを示します。データベースからユーザーを削除すると、そのユーザーに関連付けられているすべての車も削除されます。順番に、Auto
クラスでは、@ManyToOne アノテーション (1 人のユーザーが複数の Auto に対応できる) と @JoinColumn アノテーションを持つ user フィールドが表示されます。これは、autos テーブルのどの列が users テーブル (つまり、前に説明した外部キー) を参照するために使用されるかを示します。データ モデルを作成したら、データベース内のデータを使用して操作を実行するようにプログラムを学習させます。HibernateSessionFactoryUtil ユーティリティ クラスから始めましょう。ジョブは 1 つだけです。それは、アプリケーションがデータベースと連携するためのセッション ファクトリを作成することです (ファクトリ デザイン パターンをよろしくお願いします!)。それ以外のことをする方法がわかりません。
package utils;
import models.Auto;
import models.User;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class HibernateSessionFactoryUtil {
private static SessionFactory sessionFactory;
private HibernateSessionFactoryUtil() {}
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
try {
Configuration configuration = new Configuration().configure();
configuration.addAnnotatedClass(User.class);
configuration.addAnnotatedClass(Auto.class);
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(builder.build());
} catch (Exception e) {
System.out.println("Исключение!" + e);
}
}
return sessionFactory;
}
}
このクラスでは、新しい Configuration オブジェクトを作成し、それにエンティティとして扱う必要があるクラス (User
および )を渡しますAuto
。方法に注目してくださいconfiguration.getProperties()
。他にはどんな物件があるのでしょうか?彼らはどこから来たのか?プロパティは、特別な hibernate.cfg.xml ファイルに示される休止状態設定です。 Hibernate.cfg.xml はここで読み取られます:new Configuration().configure();
ご覧のとおり、これには特に特別なことはありません。データベースに接続するためのパラメーターと show_sql パラメーターが含まれています。これは、Hibernate によって実行されるすべての SQL クエリをコンソールに表示するために必要です。こうすることで、特定の瞬間に Hibernate が何を行っているかを正確に確認できるようになり、「魔法」のような感覚が排除されます。次に必要なのは、UserDAO
クラス。ベスト プラクティスは、インターフェイスを介してプログラムすることです。別のUserDAO
インターフェイスとUserDAOImpl
実装を作成しますが、コードの量を減らすためにこれは省略します。実際のプロジェクトではこれを行わないでください。DAO (データ アクセス オブジェクト) 設計パターンは、最も一般的なパターンの 1 つです。アイデアはシンプルです。データへのアクセスのみを担当し、それ以外は何も行わないアプリケーション層を作成します。データベースからデータを取得し、データを更新し、データを削除するだけです。DAO についてもっと勉強してください。作業ではデータ アクセス オブジェクトを常に使用することになります。私たちのクラスでは何がUserDao
できるでしょうか?すべての DAO と同様、DAO はデータのみを操作できます。ID でユーザーを検索し、そのデータを更新、削除し、データベースからすべてのユーザーのリストを取得し、データベースに新しいユーザーを保存します。これがその機能のすべてです。
package dao;
import models.Auto;
import models.User;
import org.hibernate.Session;
import org.hibernate.Transaction;
import utils.HibernateSessionFactoryUtil;
import java.util.List;
public class UserDao {
public User findById(int id) {
return HibernateSessionFactoryUtil.getSessionFactory().openSession().get(User.class, id);
}
public void save(User user) {
Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
Transaction tx1 = session.beginTransaction();
session.save(user);
tx1.commit();
session.close();
}
public void update(User user) {
Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
Transaction tx1 = session.beginTransaction();
session.update(user);
tx1.commit();
session.close();
}
public void delete(User user) {
Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
Transaction tx1 = session.beginTransaction();
session.delete(user);
tx1.commit();
session.close();
}
public Auto findAutoById(int id) {
return HibernateSessionFactoryUtil.getSessionFactory().openSession().get(Auto.class, id);
}
public List<User> findAll() {
List<User> users = (List<User>) HibernateSessionFactoryUtil.getSessionFactory().openSession().createQuery("From User").list();
return users;
}
}
UserDao
のメソッドは互いに似ています。ほとんどの場合、セッションファクトリを使用してセッション オブジェクト (データベース接続セッション) を取得し、このセッション内で単一のトランザクションを作成し、必要なデータ操作を実行して、トランザクションの結果をデータベースに保存して、セッションを閉じます。ご覧のとおり、メソッド自体は非常に簡単です。DAO はアプリケーションの「心臓部」です。ただし、DAO を直接作成してmain()
メソッド内でそのメソッドを呼び出すことはしません。すべてのロジックがクラスに移動されますUserService
。
package services;
import dao.UserDao;
import models.Auto;
import models.User;
import java.util.List;
public class UserService {
private UserDao usersDao = new UserDao();
public UserService() {
}
public User findUser(int id) {
return usersDao.findById(id);
}
public void saveUser(User user) {
usersDao.save(user);
}
public void deleteUser(User user) {
usersDao.delete(user);
}
public void updateUser(User user) {
usersDao.update(user);
}
public List<User> findAllUsers() {
return usersDao.findAll();
}
public Auto findAutoById(int id) {
return usersDao.findAutoById(id);
}
}
サービスは、ビジネス ロジックの実行を担当するアプリケーション データ層です。プログラムが何らかのビジネス ロジックを実行する必要がある場合、サービスを通じて実行されます。サービスにUserDao
は、そのメソッド内に DAO メソッドが含まれており、呼び出されます。ここでは関数を重複しているように見えるかもしれませんが (DAO オブジェクトからメソッドを呼び出すだけではだめなのでしょうか?)、多くのオブジェクトと複雑なロジックを使用すると、アプリケーションを階層化することで大きな利点が得られます (そうすることは良い習慣です。これは将来覚えておいてください) 「アプリケーション層」について読んでください)。私たちのサービスのロジックは単純ですが、実際のプロジェクトのサービス メソッドには 1 行以上のコードが含まれています :) これで、アプリケーションを実行するために必要なものがすべて揃いました。このmain()
メソッドでは、ユーザーとその車を作成し、一方を他方に関連付けてデータベースに保存しましょう。
import models.Auto;
import models.User;
import services.UserService;
import java.sql.SQLException;
public class Main {
public static void main(String[] args) throws SQLException {
UserService userService = new UserService();
User user = new User ("Jenny", 26);
userService.saveUser(user);
Auto ferrari = new Auto("Ferrari", "red");
ferrari.setUser(user);
user.addAuto(ferrari);
Auto ford = new Auto("Ford", "black");
ford.setUser(user);
user.addAuto(ford);
userService.updateUser(user);
}
}
ご覧のとおり、users テーブルには独自のレコードがあり、autos テーブルには独自のレコードがあります。 ユーザーの名前を変更してみましょう。users テーブルをクリアしてコードを実行する
import models.Auto;
import models.User;
import services.UserService;
import java.sql.SQLException;
public class Main {
public static void main(String[] args) throws SQLException {
UserService userService = new UserService();
User user = new User ("Jenny", 26);
userService.saveUser(user);
Auto ferrari = new Auto("Ferrari", "red");
user.addAuto(ferrari);
Auto ford = new Auto("Ford", "black");
ford.setUser(user);
user.addAuto(ford);
userService.updateUser(user);
user.setName ("Benny");
userService.updateUser(user);
}
}
できます! ユーザーを削除したらどうなりますか? users テーブルをクリアし (autos は自動的にクリアします)、コードを実行します。
import models.Auto;
import models.User;
import services.UserService;
import java.sql.SQLException;
public class Main {
public static void main(String[] args) throws SQLException {
UserService userService = new UserService();
User user = new User ("Jenny", 26);
userService.saveUser(user);
Auto ferrari = new Auto("Ferrari", "red");
user.addAuto(ferrari);
Auto ford = new Auto("Ford", "black");
ford.setUser(user);
user.addAuto(ford);
userService.updateUser(user);
user.setName ("Benny");
userService.updateUser(user);
userService.deleteUser(user);
}
}
そして、テーブルは完全に空です (コンソールに注目してください。Hibernate によって実行されたすべてのリクエストがそこに表示されます)。アプリケーションを試して、そのすべての機能を試すことができます。たとえば、車を持つユーザーを作成してデータベースに保存し、ユーザーに割り当てられた ID を確認して、この ID をmain()
データベースからユーザーを取得し、その車のリストをコンソールに表示するメソッド。もちろん、ここでは Hibernate の機能のほんの一部しか見ていません。その機能は非常に幅広く、長い間 Java 開発の標準業界ツールとして使用されてきました。詳しく勉強したい場合は、「Java Persistence API and Hibernate」という書籍をお勧めします。前回の記事でレビューしました。この記事が読者のお役に立てば幸いです。質問がある場合は、コメントで質問してください。喜んでお答えします :) また、「いいね!」を投稿してコンテストの作者をサポートすることも忘れないでください。あるいはさらに良いのは、「気に入っています」 :) 勉強頑張ってください!
GO TO FULL VERSION