12
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Java][Spring Boot][JPA] データベースを使う - NetBeansで始めるSpring Boot (6)

Last updated at Posted at 2016-11-10

概要

Spring Bootは、データベースアクセスにSpring Dataを使用します。
Spring Dataは、JPAやMongoDBなどのデータストアへのアクセスを抽象化する層です。

自分はJPAを使います。

作らなくちゃいけないもの

Entityクラス

データベースのテーブルへ対応するクラスです。

すでにデータベースが用意されているのであれば、NetBeansの機能を使って生成するのが簡単です。

[File]>[New File]メニューから、Persistence > Entity Classes from Databaseとたどれば、データベースのテーブルからEntityクラスを生成できます。

Repositoryインターフェース

Entityを操作するインターフェースです。org.springframework.data.repository.Repository<T, ID extends Serializable>の派生インターフェースにします。

派生インターフェースとして、あらかじめ次のものが用意されています。

インターフェース 解説
CrudRepository 一般的なCread/Read/Update/Delete操作が定義されています
PagingAndSortingRepository ソートとページング付きの全検索が定義されています。CrudRepositoryを継承しています。

使い方

Repositoryインターフェースに対して@Autowired等で依存しておくと、Springが自動的にプロキシインスタンスを作成してくれます。

@Component
public class SomeClass {
  // ...
  @Autowired
  private SomeRepository someRepository;
  // ...
}

あとは定義されているメソッドを呼び出せばよいです。

CRUD以外の操作をしたい

CrudRepositoryにあらかじめ用意されているCRUD以外の操作をしたいときのやり方です。

方法1 - 命名規約にそったメソッドを実装

以下の命名規約にそったメソッドを実装すると、メソッド名に応じて振る舞いが用意されます。

  • find...By
  • read...By
  • get...By
  • query...By
  • stream...By Java 8のStreamを返します。
  • count...By
  • exists...By
  • delete...By
  • remove...By

最初に出てくるByより後ろが検索式になります。

...の副式部分にはDistinctや、リレーション先のEntity名等が入ります。

検索式いろいろ

あらかじめいろいろなものが用意されています。

2016/11/11追記 【Spring Data JPA】自動実装されるメソッドの命名ルール に解説がありました。

検索式
2項目をAndで結ぶ findByFirstnameAndLastname(String lastname)
2項目をOrで結ぶ findByFirstnameOrLastname(String firstname, String lastname)
2項目の間 findByCreateDateBetween(Date since, Date to)
After/GreaterThan
GreaterThanEqual
Before/LessThan
LessThanEqual
IsNull
IsNotNull
NotIn
In
StartingWith/EndingWith/Containing
NotContaining
Like
NotLike
大文字小文字を無視 findByFirstnameIgnoreCase(String firstname)
ソート findAllOrderByFirstnameAsc() findAllOrderByFirstnameDesc()

副式...に入るもの

副式 解説
Distinct SQLのDISTINCTと一緒です。
Top<数字> / First<数字> 先頭から<数字>レコード分を返します。
エンティティ名 リレーション先のエンティティを返します。

方法2 - @Queryをつけたメソッドを実装

例えば、このようになります。

@Query("SELECT u FROM User WHERE u.firstname = :firstname")
List<User> findByFirstname(String firstname);

@Queryの中身はJPQLでよいのかな?

Spring Expression Languageも使えます。

方法3 - Customクラスを作る

命名規約やJPQLでは足りない機能を実装するときには、Customクラスを作ります。

例えば、もともとこんなRepositoryインターフェースがあったとしたら、

UserRepository.java
public interface UserRepository extends CrudRepository<User, Long> {}

まずは独自の機能をもったインターフェースを作ります。

UserRepositoryCustom.java
public interface UserRepositoryCustom {
  public void executeSomeOperation(User user);
}

もともとあったインターフェースに継承させます。

UserRepository.java
public interface UserRepository extends CrudRepository<User, Long>, UserRepositoryCustom {}

さらに実装を作ります。

public class UserRepostitoryImpl implements UserRepositoryCustom {
    public void executeSomeOperation(User user) {
       // なにか特別な処理
    }
}

もう少し詳しく書きました。 > Customクラスを使用してデータベースアクセスする

テストする

Repositoryインターフェースをテストします。

テストにはHSQLデータベースを使用します。

pom.xmlを変更

テストのスターター、JDBCドライバ~~、いつものjunit~~を依存ライブラリに追加します。

2016/11/11編集 junitとhamcrestは、スターターに入っていたので不要でした。

pom.xml
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <scope>test</scope>
        </dependency>

テスト用アプリケーションクラスの作成

アプリケーションクラスがなければ作成します。

src/test/java/com/example/TestApplicationi.java
package com.example;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@SpringBootApplication
@EnableJpaRepositories("com.example.repository")
public class TestApplication {
    
}

普通は@SpringBootApplicationだけで足りるのですが、Repositoryクラスが別にあるので@EnableJpaRepositoriesを付けています。

テストクラスの作成

@RunWithを付けて、テストランナーを指定します。

@SpringBootTest@Transactionalは何をやっているのかわかりません。 :sweat:

2016/11/17 追記 @SpringBootTest@Transactionalは不要でした。@DataJpaTestを付けるだけでよいです。これをつければSQLもログ出力してくれます。

src/test/java/com/example/repository/UserRepositoryTest.java
package com.example.repository;

import com.example.entity.User;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringRunner.class)
@DataJpaTest
public class UserRepositoryTest {
    
    @Autowired
    private UserRepository instance;
    
    @Before
    public void setUp() {
       // 初期データの用意等
    }

    @Test
    public void testFindSomething() {
       // テストを書く
    }
}

参考リンク

12
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?