この記事では、Java の最も人気のあるエンタープライズ フレームワークの 1 つについて理解し、Hibernate を使用して最初のアプリケーションを作成します。Hibernate について聞いたことがありませんか? 聞いたことはあっても、使ったことはないのではないでしょうか?それとも始めようとしたが成功しませんでしたか? 3 つのケースすべてにおいて、カットへようこそ :) 皆さんこんにちは!この記事では、Hibernate フレームワークの主な機能について説明し、最初のミニアプリケーションの作成を支援します。このためには次のものが必要です。
次に、Java コードに移りましょう。プロジェクトに必要なパッケージとクラスをすべて作成します。まず、データ モデル (クラス
- Intellij Idea Ultimate Edition; 公式 Web サイト
からダウンロードし、30 日間の試用版をアクティベートします。 - PostgeSQL は、最も人気のある最新のデータベース管理システム (DBMS) の 1 つです。
- Maven (IDEA にすでに組み込まれています);
- 少しの忍耐。
休止状態とは何ですか?
これは、ORM モデルの最も一般的な実装の 1 つです。オブジェクト リレーショナル モデルは、ソフトウェア オブジェクトとデータベース内のレコードの間の関係を記述します。もちろん、Hibernate の機能は非常に多岐にわたりますが、ここでは最も単純な機能に焦点を当てます。私たちの目標は、次のことができる CRUD アプリケーション (作成、読み取り、更新、削除) を作成することです。- ユーザー (ユーザー) を作成し、ID でデータベース内で検索したり、データベース内のデータを更新したり、データベースから削除したりできます。
- 車両オブジェクト (自動) をユーザーに割り当てます。データベースから車を作成、編集、検索、削除します。
- さらに、アプリケーションはデータベースから「孤立した」車を自動的に削除する必要があります。それらの。ユーザーが削除されると、そのユーザーに属するすべての車もデータベースから削除する必要があります。
com.вашНикнейм.javarush
が、これはアプリケーションの動作にはまったく影響しません。artifactId には、任意のプロジェクト名を選択します。バージョンを変更しないままにすることもできます。最後の画面で、以前に入力したデータを確認するだけです。これでプロジェクトが作成できました。あとはコードを書いて動作させるだけです :) まず第一に、データベースで動作するアプリケーションを作成したい場合は、データベースなしでは絶対にできません。ここからPostgreSQL をダウンロードします(バージョン 9 を使用しています)。PostgreSQL にはデフォルトのユーザー「postgres」があり、インストール中にそのユーザーのパスワードを作成する必要があります。パスワードは後で必要になるので忘れないでください。(一般に、アプリケーションでデフォルトのデータベースを使用するのは悪い習慣ですが、痔の量を減らすために、独自のデータベースを作成することで対応します)。コマンドラインや SQL クエリに慣れていない方に朗報です。Intellij IDEA は、データベースを操作するのに非常に適したユーザー インターフェイスを提供します。次のようになります: (IDEA の右側のサイドバー、[データベース] タブにあります) 接続を作成するには、「+」をクリックし、プロバイダー (PostgeSQL) を選択します。フィールドにユーザー、データベース名 (両方とも postgres) を入力し、PostgreSQL のインストール時に設定したパスワードを入力します。必要に応じて、Postgres ドライバーをダウンロードします。これは、この同じページで実行できます。「接続のテスト」をクリックして、データベースへの接続が確立されていることを確認します。「成功」という文字が表示されたら、次に進みます。次に、必要なテーブルを作成しましょう。そのうちの 2 つは、ユーザーと自動車です。users テーブルのパラメータ: id が主キーであることに注意してください。SQL の主キーがわからない場合は、Google で調べてください。これは重要です。autos テーブルの設定: 自動の場合は、外部キーを構成する必要があります。これによりテーブルがリンクされます。彼についてもっと読むことをお勧めします。非常に簡単に言うと、外部テーブル (この場合はユーザー) を指します。車が id=1 のユーザーに属している場合、autos テーブルの user_id フィールドには 1 が設定されます。これが、アプリケーションでユーザーと車を結び付ける方法です。autos テーブルでは、user_id フィールドが外部キーとして機能します。これは、users テーブルの id フィールドを参照します。 したがって、2 つのテーブルを持つデータベースを作成しました。Java コードからそれを管理する方法を理解する必要があります。pom.xml ファイルから始めます。このファイルには、必要なライブラリ (Maven 言語では依存関係と呼ばれます) を含める必要があります。すべてのライブラリは中央の Maven リポジトリに保存されます。pom.xml で指定したものは、プロジェクトで使用できます。pom.xml は次のようになります。 ご覧のとおり、複雑なことは何もありません。追加した依存関係は、PostgreSQL と Hibernate を使用するための 2 つだけです。
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 not specify Column name if it matches the name of the column 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 not specify Column name if it matches the name of the column 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 のセッターが存在せず、コンストラクターでも ID を指定しないことです。しかし、このクラスは依然としていくつかの点User
で際立っています。彼は車のリストを持っています!@OneToMany 注釈がリストの上に表示されます。これは、ユーザー クラスの 1 つのオブジェクトが複数のマシンに対応できることを意味します。「mappedBY」設定は、クラスのユーザー フィールドを指しますAuto
。このようにして、マシンとユーザーは相互に接続されます。orphanRemoval 設定は、英語から「孤児を削除する」と非常によく翻訳されます。データベースからユーザーを削除すると、そのユーザーに関連付けられているすべての車も削除されます。次に、クラス内にAuto
@ManyToOne 注釈 (多くの Auto が 1 人の User に対応できる) と @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("Exception!" + e);
}
}
return sessionFactory;
}
}
このクラスでは、新しい構成オブジェクト Configuration を作成し、それにエンティティとして認識されるクラス (User
および )を渡しますAuto
。方法に注意してくださいconfiguration.getProperties()
。他にどのようなプロパティがありますか? どこ?プロパティは、hibernate の動作方法に関するパラメータであり、特別なファイル hibernate.cfg.xml で指定されます。 Hibernate.cfg.xml はここで読み取られます:new Configuration().configure();
ご覧のとおり、これには特別なものは何もありません - データベースに接続するためのパラメーターと特別なパラメーター show_sql です。これは、休止状態がデータベースに対して実行するすべての SQL クエリがコンソールに出力されるようにするために必要です。こうすることで、Hibernate がその瞬間に何を行っているかを正確に確認でき、「魔法」のような影響を取り除くことができます。次にクラスが必要ですUserDAO
。(良い意味で、インターフェイスを介してプログラムする必要があります。インターフェイスを作成しUserDAO
、それを個別に実装しますUserDAOImpl
が、コードの量を減らすためにこれは省略します。実際のプロジェクトではこれを行わないでください。) DAO(データ アクセス オブジェクト)は、最も一般的なデザイン パターンの 1 つである「データ アクセス」です。その意味は単純です。データへのアクセスのみを担当し、他には何も担当しないレイヤーをアプリケーション内に作成することです。データベースからデータを取得し、データを更新し、データを削除するだけです。DAO については、仕事で常に使用することになるので、詳しく読んでください。私たちのクラスでは何ができるでしょうかUserDao
?実際には、他の 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 を直接作成してそのメソッドを .html で呼び出すことはしません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("Masha",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("Masha",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("Sasha");
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("Masha",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("Sasha");
userService.updateUser(user);
userService.deleteUser(user);
}
}
そして、テーブルは完全に空です (コンソールに注目してください。Hibernate が実行したすべてのクエリがそこに表示されます)。アプリケーションを試して、そのすべての機能を試すことができます。たとえば、マシンを使用してユーザーを作成し、それをデータベースに保存し、どのような ID が割り当てられているかを確認し、main()
この ID によってデータベースからユーザーを「プル」し、コンソールにマシンのリストを表示するメソッドを使用してみてください。 。もちろん、ここで確認したのは Hibernate の機能のほんの一部だけです。その機能は非常に幅広く、長い間 Java 開発の業界標準の 1 つとなってきました。詳しく学びたい場合は、以前の記事でレビューした『Java Persistence API and Hibernate』という書籍をお勧めします。この記事が読者にとって役に立てば幸いです。ご質問がございましたら、コメント欄で質問してください。喜んでお答えします :) また、コンテストで作者を「いいね」してサポートすることも忘れないでください。あるいは、さらに良いことに - 「とても気に入っています」 :) 勉強頑張ってください!
GO TO FULL VERSION