Spring Data JPA は、Java アプリケーション内のさまざまなデータベースにアクセスするための、シンプルで一貫性のある使いやすい方法を提供する人気の Java 永続性フレームワークです。そのシンプルさと強力な機能により、多くの開発者にとって最適なフレームワークとなっています。Spring Data JPA を使用することで、開発者はアプリケーションをより迅速に開発し、コード量を削減し、コードの可読性と保守性を向上させることができます。この記事では、Spring Data JPA の基本概念と使用法を紹介し、その使用法と利点をよりよく理解するのに役立つ完全な例を提供します。
Spring Data JPAとは
Spring Data JPA は、さまざまなリレーショナル データベースのデータに簡単にアクセスできる方法を提供する Spring Framework のサブプロジェクトです。JPA (Java Persistence API) と Spring Framework の強力な機能を組み合わせることでデータベース アクセスの複雑さを簡素化し、アノテーション ベースのリポジトリ モデル、自動クエリ、ページングとソートのサポート、複雑な Check DSL などの多くの機能とツールを提供します。 。
Spring Data JPA の歴史は 2011 年に遡ります。このとき、SpringSource (Spring Framework の開発会社) は、開発者がデータ永続化のための JPA 仕様をより効果的に活用できるようにするために、「Spring Data JPA」と呼ばれるプロジェクトをリリースしました。それ以来、このプロジェクトは広く使用され、認知され、常に開発と改善が行われています。現在、Spring Data JPA は Java 開発者の間で最も人気のある永続化フレームワークの 1 つとなり、さまざまなエンタープライズ レベルのアプリケーションやインターネット アプリケーションで広く使用されています。
入門ケース
データの準備
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `user` (`name`, `email`) VALUES
('刘德华', '[email protected]'),
('张学友', '[email protected]'),
('黎明', '[email protected]'),
('郭富城', '[email protected]'),
('梁朝伟', '[email protected]');
复制代码
依存関係を追加する
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
复制代码
エンティティクラスの作成
import lombok.Data;
import javax.persistence.*;
@Entity
@Table(name = "user")
@Data
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String email;
}
复制代码
JPA アノテーションを使用し@Entity
、@Table
クラスをエンティティ クラスとしてマークし、マップされたテーブル名を指定します。@Id
注釈はエンティティ クラスの一意の識別子をマークし、@GeneratedValue
主キー生成戦略を指定します。同時に、@Column
アノテーションを使用して、エンティティ クラスのフィールド名と、フィールドを空にすることが許可されるかどうかを指定します。
@Column
注釈
このアノテーションは、エンティティ クラスのプロパティおよび Getter メソッドに適用できます。プロパティと Getter メソッドの両方にある場合は、Getter メソッドのアノテーションが優先されます。このアノテーションの各属性の意味は次のとおりです。
- name: オプション。データベース テーブルのフィールド名を指定するために使用されます。デフォルト値は属性名です。
- unique: オプション。フィールドが一意であるかどうかを指定するために使用されます。デフォルト値は false です。
- nullable: オプション。フィールドが null 可能かどうかを指定するために使用されます。デフォルト値は true です。
- insertable: オプション。INSERT 操作の実行時にこのフィールドの値を挿入するかどうかを指定するために使用されます。デフォルト値は true です。
- updatable: オプション。UPDATE 操作の実行時にこのフィールドの値を更新するかどうかを指定するために使用されます。デフォルト値は true です。
- columnDefinition: オプション。VARCHAR(255)、INTEGER など、データベース内のフィールドの実際のタイプを指定するために使用されます。デフォルトでは、属性タイプに基づいて自動的に生成されます。
- table: オプション。フィールドが配置されているテーブルの名前を指定するために使用されます。デフォルト値はメイン テーブルです。
- length: オプション。フィールドの長さの指定に使用されます。これは、フィールド タイプが文字列タイプの場合にのみ有効です。デフォルト値は 255 です。
- precision: オプション。フィールドの精度を指定するために使用されます。これは、フィールド タイプが DECIMAL の場合にのみ有効です。デフォルト値は 0 です。
- スケール: オプション。フィールドの小数点以下の桁数を指定するために使用されます。フィールド タイプが DECIMAL の場合にのみ有効です。デフォルト値は 0 です。
@GeneratedValue
アノテーションは主キー生成戦略を指定します。一般的な主キー生成戦略には次のものがあります。
-
GenerationType.IDENTITY: 主キーはデータベースによって自動的に生成されます (MySQL や PostgreSQL などのリレーショナル データベースに適用されます)。
-
GenerationType.AUTO: JPA は適切な戦略を自動的に選択し、基礎となるデータベースに基づいて主キー生成戦略を自動的に選択します。
-
GenerationType.SEQUENCE: シーケンスを通じて主キーを生成します (Oracle データベースに適用されます)。
-
GenerationType.TABLE: テーブル シミュレーション シーケンスを使用して主キーを生成します。
このうち、GenerationType.IDENTITY は、使用が簡単でパフォーマンスが優れているため、最も一般的に使用される主キー生成戦略です。MySQL、PostgreSQL などのデータベースを使用している場合は、GenerationType.IDENTITY を使用して主キーを生成することをお勧めします。Oracle データベースを使用している場合は、GenerationType.SEQUENCE を使用して主キーを生成することを検討してください。別のデータベースを使用している場合は、特定の状況に基づいて適切な主キー生成戦略を選択できます。
リポジトリの作成
public interface UserRepository extends JpaRepository<User,Long> {
}
复制代码
JpaRepository
追加、削除、変更、クエリなど、多くの一般的な永続化操作を提供するインターフェイスを使用します。このインターフェイスを継承し、エンティティ クラスの種類と主キーの種類を指定するだけで済みます。
2 つのジェネリック、1 つはエンティティ クラス用、もう 1 つは主キー タイプ用
find{By|FirstBy|AllBy}[属性名称][查询关键字][连接符][属性名称][查询关键字]...
By
: メソッドがクエリ メソッドであることを示し、その後にクエリ条件の属性名が続きます。FirstBy
: クエリ結果の最初のレコードを示します。AllBy
: 条件を満たすすべてのレコードをクエリすることを示します。[属性名称]
: クエリ条件の属性名を示します。属性名はエンティティクラスの属性名と一致する必要があります。[查询关键字]
Equals
: 、、、、GreaterThan
などの検索条件を表すキーワードLessThan
。IsNotNull
[连接符]
:などの接続状態を示すコネクタですAnd
。Or
public interface UserRepository extends JpaRepository<User, Long> {
// 查询所有性别为男性的用户
List<User> findByGender(String gender);
// 查询用户名为指定值的用户
User findByUsername(String username);
// 查询用户名和密码都匹配的用户
User findByUsernameAndPassword(String username, String password);
// 查询用户年龄大于等于指定值且性别为指定值的用户
List<User> findByAgeGreaterThanEqualAndGender(int age, String gender);
}
复制代码
さらに、@Query アノテーションを使用して JPQL または SQL クエリ ステートメントをカスタマイズすることもできます。次に例を示します。
@Query("SELECT u FROM User u WHERE u.username = :username")
User findByUsername(@Param("username") String username);
复制代码
この例では、JPQL クエリ ステートメントを使用してユーザー オブジェクトをクエリするカスタム クエリ メソッド findByUsername を定義します。@Query アノテーションがメソッドで使用され、JPQL クエリ ステートメントが値として渡されます。ここで、ユーザー名はプレースホルダーであり、@Param アノテーションは、対応するメソッド パラメーターをマークするために使用されます。
@Query アノテーションでネイティブ SQL クエリを使用することもできます。次に例を示します。
@Query(value = "SELECT * FROM users WHERE username = :username", nativeQuery = true)
User findByUsername(@Param("username") String username);
复制代码
この例では、ネイティブ SQL クエリを使用するカスタム クエリ メソッド findByUsername を定義します。@Query アノテーションで、nativeQuery 属性を true に設定します。これは、ネイティブ SQL クエリを使用することを意味します。ユーザー名はプレースホルダーであり、@Param アノテーションを使用して、対応するメソッド パラメーターをマークします。
ビジネスロジックを書く
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> findAll() {
return userRepository.findAll();
}
public Optional<User> findById(Long id) {
return userRepository.findById(id);
}
public User save(User user) {
return userRepository.save(user);
}
public void deleteById(Long id) {
userRepository.deleteById(id);
}
}
复制代码
コントローラーを書く
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("all")
public List<User> getAllUsers() {
return userService.findAll();
}
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
Optional<User> user = userService.findById(id);
if (user.isPresent()) {
return new ResponseEntity<>(user.get(), HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@PostMapping
public User addUser(@RequestBody User user) {
return userService.save(user);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteById(id);
return ResponseEntity.noContent().build();
}
}
复制代码
結果
設定ファイルの詳しい説明
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: user
password: pass
driver-class-name: com.mysql.jdbc.Driver
jpa:
database-platform: org.hibernate.dialect.MySQL8Dialect
show-sql: true # 是否打印生成的 SQL 语句
hibernate:
ddl-auto: update # 应用启动时,自动更新数据库的表结构
properties:
hibernate:
format_sql: true # 是否格式化打印 SQL 语句
复制代码
hibernate.ddl-auto
hibernate.ddl-auto
アプリケーションの起動時にデータベース スキーマを自動的に作成する方法を制御するために使用される Hibernate 構成プロパティです。
オプションの値には次のものが含まれます。
- validate: Hibernate のすべてのエンティティ クラスがデータベースのテーブル構造と一致するかどうかを確認し、一致しない場合は変更せずに例外をスローします。
- update: Hibernate のエンティティ クラスに従ってデータベース スキーマ (スキーマ) を自動的に更新します。データは削除されず、テーブル構造とデータ型が変更されるだけです。
- create: Hibernate のエンティティ クラスに基づいてデータベース スキーマ (スキーマ) を自動的に作成します。古いテーブルは削除され、新しいテーブルが再作成されますが、テーブル内のデータは削除されません。
- create-drop: Hibernate のエンティティ クラスに基づいてデータベース スキーマ (スキーマ) を自動的に作成し、アプリケーションを閉じるときにすべてのテーブルとデータを削除します。
- none: データベース スキーマ (スキーマ) の自動管理は実行されず、データベース スキーマ (スキーマ) は手動で管理する必要があります。
hibernate.ddl-auto
この属性は、データ損失や不可逆的なテーブル構造の変更を引き起こす可能性があるため、運用環境では使用しないでください。開発およびテスト環境では、開発の反復を高速化し、データベース スキーマの再構築を容易にします。
hibernate.ddl-auto 属性の create または create-drop 値を使用すると、Hibernate がエンティティ クラスに基づいてテーブルを自動的に作成できるようになります。
jpa.データベースプラットフォーム
jpa.database-platform
これは Spring Data JPA のオプションの構成項目であり、アプリケーションの起動時にデータベースを作成または更新するときに正しい SQL ステートメントを生成するために使用するデータベース プラットフォームを指定するために使用されます。この設定項目では、データベース方言クラス名または Hibernate 方言名を指定する必要があります。
デフォルトでは、Spring Data JPA は、データ ソースのメタデータ情報に基づいて使用されるデータベースの種類とバージョンを自動的に検出し、この情報に基づいて適切な方言を自動的に選択します。ただし、自動検出でデータベースの種類やバージョンが正しく識別されない場合や、アプリケーションで特定のデータベース固有の機能を使用する必要がある場合、方言を手動で指定する必要がある場合があります。
jpa.database-platform
の値は通常、次の 3 つのタイプに分類されます。
- Hibernate 方言名 (例
org.hibernate.dialect.MySQL5Dialect
) - データベース方言クラス名 (例
com.mysql.cj.jdbc.Driver
) - Hibernate 方言実装クラス ( など
org.hibernate.dialect.MySQL8Dialect
)
この構成項目を指定しない場合、Spring Data JPA はデータ ソースのメタデータに基づいてデータベースの種類とバージョンを自動的に検出し、適切な方言を選択しようとします。自動検出に失敗すると、アプリケーションの起動に失敗したり、生成された SQL ステートメントが正しく実行されない可能性があります。
アプリケーションが複数のデータ ソースを使用する場合は、データ ソースごとに方言を個別に指定する必要があることに注意してください。これは、 のデータ ソースごとにapplication.yaml
異なる構成項目を追加することで実現できます。jpa.database-platform
Spring Data jpa と他の orm フレームワークとの比較
Spring Data JPA は Spring Framework に基づくデータ アクセス フレームワークであり、JPA 仕様をカプセル化し、JPA の使用を簡素化し、いくつかの一般的なデータ アクセス操作を提供します。
Spring Data JPA と他の ORM フレームワークとの比較は次のとおりです。
- 休止状態
Hibernate は、JPA より多くの機能と柔軟性を提供し、複雑なマッピング関係やクエリをより適切に処理できる人気の ORM フレームワークです。ただし、Hibernate の使用は比較的複雑であり、より多くの設定と詳細を処理する必要があります。比較すると、Spring Data JPA はより簡潔で使いやすく、迅速な開発や小規模なプロジェクトに適しています。
- マイバティス
MyBatis は軽量の ORM フレームワークであり、それに比べて柔軟性が高く、特定のニーズに応じて SQL ステートメントとマッピング関係をカスタマイズできます。ただし、MyBatis を使用するには独自の SQL ステートメントを作成する必要があり、これは比較的面倒で、一部の詳細を自分で処理する必要があります。Spring Data JPAは操作がシンプルで、メソッド名に基づいてSQLを自動生成できるため、より使いやすくなっています。
- ジューク
JOOQ は、保守可能な Java コードを生成できるタイプセーフな SQL 構築とクエリを提供する Java ベースの SQL ビルダーおよび ORM フレームワークです。それに比べて、Spring Data JPA はシンプルで使いやすく、SQL を書く手間が省けますが、型の安全性と保守性に比較的欠けています。
つまり、Spring Data JPA は迅速な開発や小規模プロジェクトに適しており、データ アクセス操作を大幅に簡素化し、コード量を削減できますが、柔軟性や複雑なマッピング関係を処理する能力が比較的不足しています。Hibernate と MyBatis はより柔軟で、より複雑なシナリオを処理できますが、より多くの構成と詳細な処理が必要です。