今回はデータベースとのデータのやり取りについてやっていきたい。
Accessing Data with JPAをやってみる
Javaでデータベースを扱う方法でやったことがあるのはJDBCとOrmLiteくらいだったので、JPAは多分初めて使う。
まずはbuild.gradleを変更する。
dependencies {
// compile("org.springframework.boot:spring-boot-starter-web:1.2.1.RELEASE")
// compile("org.springframework.boot:spring-boot-starter-actuator:1.2.1.RELEASE")
compile("org.springframework.boot:spring-boot-starter-thymeleaf:1.2.1.RELEASE")
compile("org.springframework.boot:spring-boot-starter-security:1.2.1.RELEASE")
compile("org.springframework.boot:spring-boot-starter-data-jpa:1.2.1.RELEASE")
compile("com.h2database:h2:1.4.183")
compile("org.webjars:jquery:2.1.3")
testCompile("org.springframework.boot:spring-boot-starter-test:1.2.1.RELEASE")
}
H2はJavaでできたデータベースだ。Javaでデータベースを試すのであればこれがお手軽のようだ。
シンプルなEntityクラスを作る
今回はJPAのEntityアノテーションを使ったシンプルなEntityクラスを作るようだ。
package sample;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String firstName;
private String lastName;
protected Customer(){}
public Customer(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@Override
public String toString() {
return String.format(
"Customer[id=%d, firstName='%s', lastName='%s']",
id, firstName, lastName
);
}
}
protectedなコンストラクタは直接使うことはしない。そしてpublicなコンストラクタはデータを保存するときに使う。@Tableアノテーションがない場合はCustomerテーブルがあると仮定して動くようだ。
そして、プライマリキーに@Idをつけ、@GeneratedValueアノテーションのstrategyにGenerationType.AUTOを設定することでインクリメントされていくということだろう。
Spring Data JPA
Spring Data JPAはJPAを使ってデータベースにアクセスするためのものだ。interfaceを定義しておいたら、継承したCrudRepositoryが様々な処理を追加してくれるようである。独自に定義したい場合もルールに則ったメソッドを定義しておいたら、おそらくメタプログラミングしてくれるのだろう。
package sample;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
public interface CustomerRepository extends CrudRepository<Customer, Long> {
List<Customer> findByLastName(String lastName);
}
通常のJavaアプリケーションであれば、CustomerRepositoryクラスを定義するところであろうが、Spring Data JPAはパワフルなのでそんな必要はない、と書いてあった。さぁ!早速試してみようぜ!と書いてあるので試してみよう。
Applicationクラスにrunメソッドを
今回は画面上にではなくて、システムログに出すだけのようだ。
CommandLineRunnerインターフェースを入れたApplicationクラスにするようだ。
package sample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import java.util.Arrays;
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
CustomerRepository repository;
public static void main(String[] args) {
// 略
}
@Override
public void run(String... args) throws Exception {
repository.save(new Customer("Jack", "Bauer"));
repository.save(new Customer("Chloe", "O'Brian"));
repository.save(new Customer("Kim", "Bauer"));
repository.save(new Customer("David", "Palmer"));
repository.save(new Customer("Michelle", "Dessler"));
// fetch all customers
System.out.println("Customers found with findAll():");
System.out.println("-------------------------------");
for (Customer customer : repository.findAll()) {
System.out.println(customer);
}
System.out.println();
// fetch an individual customer by ID
Customer customer = repository.findOne(1L);
System.out.println("Customer found with findOne(1L):");
System.out.println("--------------------------------");
System.out.println(customer);
System.out.println();
// fetch customers by last name
System.out.println("Customer found with findByLastName('Bauer'):");
System.out.println("--------------------------------------------");
for (Customer bauer : repository.findByLastName("Bauer")) {
System.out.println(bauer);
}
}
}
CustomerRepositoryインターフェースがSpring Application Contextによって生成されるようなので、newとか別にしなくてもいいらしい。saveメソッドにCustomerインスタンスを渡すと保存されるし、findAllメソッドで全部のデータを持ってこれるし、findOneメソッドでidを指定すれば1件だけ取得することもできる。自分でメソッド名のみ定義したfindByLastNameメソッドも作られていて利用できる。うーむ、すごい。
whereとかはJPAのドキュメントを読めってことだと思うんだけれど、とりあえずここまででサンプルは終わっていて、RESTで使ってみるのは?へのリンクがあったので、次回はそれをやってみようと思う。
