[Spring Boot] Spring Boot の単純なクエリ

前回の記事では、データの追加、削除、変更、クエリなどの機能を実装するための Spring Boot プロジェクトへの JPA フレームワークの統合について紹介しました。Spring Data JPA の使用は非常に簡単で、JpaRepository を継承するだけで、データ アクセス層や SQL ステートメントを必要とせずに完全なデータ操作メソッドを実装できます。これらの機能と利点に加えて、JPA には非常に強力なデータクエリ機能もあります。以前は、複雑なクエリには多くのクエリ条件を結合する必要がありましたが、JPA にはそれを解決するための非常に便利で洗練された方法があります。次に、Spring Data JPA の威力を体験するために、JPA のクエリ機能について説明します。

1. 事前生成方法

JpaRepository インターフェースは、exists()、save()、findAll()、delete() およびその他のメソッドなど、データベースにアクセスするためのすべての主要なインターフェースを実装していることを以前に紹介しました。JpaRepository クラスを継承し、親クラスに事前に生成されたすべてのメソッドを含む UserRepository クラスを作成します。

これらのメソッドの呼び出しも非常に簡単で、上記の JpaRepository 親クラスが持つメソッドはすべて宣言なしで直接呼び出すことができます。サンプルコードは次のとおりです。

userRespository.existsByld((long) 1);
userRespository.save(user);
userRespository.findById((long) 1);
userRespository.findAll();
userRespository.delete(user);
userRespository.deleteById((long) 1);

2. 単純なクエリをカスタマイズする

JPAは、JpaRepositoryインタフェースによって提供される基本機能を直接使用することに加えて、エンティティの特定の属性に基づいたデータベース操作もサポートしています。Spring Data JPAは、そのメソッド名に基づいてSQLを自動的に生成できます。サポートされているキーワードには、find、query、get、 read、count、delete など、主な構文は findByXX、queryByXX、getByXX、readByXX、countByXX などです。この機能を利用するには、定義されたリポジトリに対応するメソッド名を追加するだけでよく、特別な実装は必要ありません。使用すると、Spring Data JPA がメソッド名に基づいて SQL ステートメントを自動的に生成します。

2.1 属性クエリ

エンティティの name 属性に基づいてユーザー情報をクエリする場合は、インターフェイス宣言を UserRepository に直接追加するだけです。

User findByUserName(String userName);

上記の例からわかるように、findByUserName メソッドを実装せずに UserRepository インターフェースで宣言することができ、対応する実装メソッドとその SQL 文が JPA によって自動的に生成されます。

2.2 結合クエリ

JPA は、単一属性のクエリだけでなく、複数の属性のクエリ、And、Or などのキーワードに基づいた結合クエリもサポートしています。サンプルコードは次のとおりです。

User findByNameOrPassword (String name, String password);

上記の例では、クエリは名前とパスワードの 2 つの属性の組み合わせに基づいており、属性の名前と番号はパラメータの位置と番号に 1 対 1 で対応している必要があります。クエリ条件に応じて継続的に追加や結合が可能であり、Spring Data JPA を正しく解析して実行することができます。

2.3 JPAキーワード

And および Or キーワードに加えて、JPA のカスタム クエリは基本的に SQL 構文のすべてのキーワード (like、 between など) をサポートします。

Spring Dataの仕様によれば、クエリメソッドはfind、read、getで始まります。クエリ条件が含まれる場合、条件の属性は条件キーワードを使用して接続されます。条件属性の最初の文字は大文字であることに注意してください。

3. カスタム SQL クエリ

一般的なデータクエリ関数は、メソッド名を定義することで実装できます。ただし、一部の特殊なシナリオでは、データ クエリ関数を実装するためにカスタマイズされた SQL が必要になる場合があります。Spring Data JPA も完全にサポートされており、Spring Data JPA は @Query アノテーションを提供しており、これを使用して HQL または SQL をカスタマイズして複雑なデータ クエリ関数を実装できます。以下では、サンプル プログラムを使用して、カスタム SQL クエリを実装するための @Query アノテーションを示します。

3.1 HQL クエリ

対応するクエリ メソッドで @Query アノテーションを使用し、アノテーションに HQL を記述してコンテンツをクエリします。

@Query("select u from User u")
List<User> findALL();

上記の例では、@Query アノテーションを使用してカスタム HQL ステートメントを定義し、カスタム HQL ステートメント クエリを実装しています。HQL を使用すると、ネイティブ SQL よりも読みやすく、オブジェクト指向の方法でデータ操作が可能になります。HQL を使用する場合の注意事項:

1) From の後にはデータ テーブル名ではなくエンティティ クラスが続きます。

2) クエリ フィールドは、データ テーブルのフィールドの代わりにエンティティ クラスの属性を使用します。

3) selectの後に "*" を続けることはできません。これはエンティティ クラスの属性である必要があります。

3.2 SQLクエリ

HQL ステートメント クエリのサポートに加えて、JPA はより直観的な SQL ステートメントを直接使用することもできます。別のパラメーター「nativeQuery = true」を追加するだけです。

@Query(value="select * from user u where u.name = ?1",nativeQuery = true)
List<User> findByName(String name);

上記の例の「?1」はメソッド パラメータの順序を表し、「nativeQuery = true」はネイティブ SQL ステートメントの実行を表します。この方法でパラメータを渡すことに加えて、@Param を使用して値を渡すこともできます。

@Query(value="select u from User u where u.password = :password")
List<User> findByPassword(@Param("password") String password);

3.3 変更と削除

カスタム クエリ ステートメントに加えて、@Query アノテーションを使用して変更ステートメントと削除ステートメントを定義することもできますが、@Modifying アノテーションを追加する必要があります。サンプルコードは次のとおりです。

@Modifying
@Query("update User set userName = ?1 where id = ?2")
int modifyById(String userName, Long id);

@Modifying
@Query("delete from User where id = ?1")
void deleteUserById(Long id);

上記の例では、@Modifying アノテーションをカスタムの delete ステートメントと update ステートメントに追加する必要があります。これを使用する場合、データがデータベースに正常に書き込まれることを確認するには、リポジトリ以上に @Transactional アノテーションを追加する必要があることに注意してください。

4. 名前付きクエリ

@Query アノテーションの使用に加えて、@NamedQuery や @NameQueries などのアノテーションを使用して名前付きクエリを定義することもできます。JPA の名前付きクエリでは、実際には SQL クエリ ステートメントに名前が付けられ、クエリの実行時にその名前が直接使用されるため、JPQL ステートメントの繰り返し記述を回避し、クエリ メソッドを再利用できます。以下では、サンプル プログラムを使用して JPA 名前付きクエリを示します。

4.1 名前付きクエリの定義

エンティティ クラスでは、@NamedQuery アノテーションによって名前付きクエリ ステートメントが定義されます。サンプル コードは次のとおりです。

@Entity
@Table(name="user")
@NamedQuery(name="findAllUser", query="SELECT U FROM User u")
public class User {
    
    

}

上記の例では、@NamedQuery の name 属性は名前付きクエリの名前を指定し、query 属性は名前付きクエリのステートメントを指定します。複数の名前付きクエリ メソッドを定義する場合は、 @NamedQueries アノテーションを使用する必要があります。

@Entity
@Table(name="users")
@NamedQueries({
    
    
        @NamedQuery(name = "findAllUser", query = "SELECT U FROM User u"),
        @NamedQuery(name = "findUserWithId", query = "SELECT U FROM User u WHERE u.id = ?1"),
        @NamedQuery(name = "findUserWithName", query = "SELECT U FROM User u WHERE u.name = :name")
})
public class User {
    
    

}

上記の例では、findAllUser()、findUserWithId()、および findUserWithName() の 3 つのメソッドが User エンティティ クラスに定義されています。

4.2 名前付きクエリの呼び出し

名前付きクエリを定義した後、EntityManager クラスの createNamedQuery() メソッドを使用して名前付きクエリの名前を渡すことでクエリを作成できます。

    @Resource
    EntityManagerFactory emf;
    @Test
    public void testNamedQuery() {
    
    
        EntityManager em = emf.createEntityManager();
        // 根User实体中定义的命名查询
        Query query = em.createNamedQuery("findUserWithName");
        query.setParameter("name", "ysxq");
        List<User> users = query.getResultList();
        for (User u : users) {
    
    
            System.out.println("name:" + u.getName() + ",age:" + u.getAge());
        }
    }

上の例では、createNamedQuery を使用して対応するクエリを作成します。JPA はまず、受信したクエリ名に基づいて対応する NamedQuery を検索し、次にクエリを実行し、getResultList() メソッドを呼び出して結果を返します。

@NamedQuery アノテーションの使用に加えて、Spring Data JPA が提供する名前付きクエリでは、SQL ステートメントの XML ファイルへの書き込みをサポートして、SQL と Java コードの分離を実現できます。Resources/META-INFディレクトリにorm.xmlファイルを作成し、ネーミング方法を定義する参考構成は以下のとおりです。

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings version="2.0"
                 xmlns="http://java.sun.com/xml/ns/persistence/orm"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
                 http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/persistence/orm_2_2.xsd">
    <named-native-query name="findUserWithName2" result-class="com.example.ysxq.model.User">
        <description>通过name查询用户数据</description>
        <query>select u.id , u.name , u.password , u.age from users u where u.name = :name</query>
    </named-native-query>
</entity-mappings>

orm.xml ファイル内のタグを使用して、queryByName の名前付きクエリを定義します。XML を使用した場合の効果は、@NamedQuery アノテーションを使用した場合と同じです。XML ファイルに SQL ステートメントを記述するだけで SQL と Java コードが分離され、定義された Java エンティティ クラスの複雑さや肥大化が軽減されます。

おすすめ

転載: blog.csdn.net/weixin_45627039/article/details/132830831