Spring Boot/第三回 Spring Bootでデータベース操作(JPA編)
Spring Bootでデータベース操作をする。
Spring Bootでのデータベース操作は
の2種類があるが、今回はORマッピングの方の話。
JavaのORマッピングの仕様「JPA(Java Persistence API=Javaの永続化のAPI)」でデータベースを操作する。
依存関係の追加
まずはMavenの依存関係の変更。
<dependencies> <!-- append start --> <dependency> <!-- a --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <!-- b --> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> <dependency> <!-- c --> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.14.0</version> <scope>provided</scope> </dependency> <!-- append end --> </dependencies>
a -> Spring BootでJPAを扱うための依存関係。
b -> H2の依存関係。
c -> Lombokの依存関係。
JDBCを使うときは「spring-boot-starter-jdbc」だが、JPAを使うときは「spring-boot-starter-data-jpa」を指定する。
依存関係を見てみる
mvn dependency:tree
結果は以下の通り。
[INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building SpringSample03 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ SpringSample03 --- [INFO] tools.springsample.springsample03:SpringSample03:jar:1.0-SNAPSHOT [INFO] +- junit:junit:jar:3.8.1:test [INFO] +- org.springframework.boot:spring-boot-starter-web:jar:1.1.5.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot-starter:jar:1.1.5.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot:jar:1.1.5.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot-autoconfigure:jar:1.1.5.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:1.1.5.RELEASE:compile [INFO] | | | +- org.slf4j:jul-to-slf4j:jar:1.7.7:compile [INFO] | | | +- org.slf4j:log4j-over-slf4j:jar:1.7.7:compile [INFO] | | | \- ch.qos.logback:logback-classic:jar:1.1.2:compile [INFO] | | | \- ch.qos.logback:logback-core:jar:1.1.2:compile [INFO] | | \- org.yaml:snakeyaml:jar:1.13:runtime [INFO] | +- org.springframework.boot:spring-boot-starter-tomcat:jar:1.1.5.RELEASE:compile [INFO] | | +- org.apache.tomcat.embed:tomcat-embed-core:jar:7.0.54:compile [INFO] | | +- org.apache.tomcat.embed:tomcat-embed-el:jar:7.0.54:compile [INFO] | | \- org.apache.tomcat.embed:tomcat-embed-logging-juli:jar:7.0.54:compile [INFO] | +- com.fasterxml.jackson.core:jackson-databind:jar:2.3.3:compile [INFO] | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.3.3:compile [INFO] | | \- com.fasterxml.jackson.core:jackson-core:jar:2.3.3:compile [INFO] | +- org.hibernate:hibernate-validator:jar:5.0.3.Final:compile [INFO] | | +- javax.validation:validation-api:jar:1.1.0.Final:compile [INFO] | | +- org.jboss.logging:jboss-logging:jar:3.1.1.GA:compile [INFO] | | \- com.fasterxml:classmate:jar:1.0.0:compile [INFO] | +- org.springframework:spring-core:jar:4.0.6.RELEASE:compile [INFO] | +- org.springframework:spring-web:jar:4.0.6.RELEASE:compile [INFO] | | +- org.springframework:spring-aop:jar:4.0.6.RELEASE:compile [INFO] | | | \- aopalliance:aopalliance:jar:1.0:compile [INFO] | | +- org.springframework:spring-beans:jar:4.0.6.RELEASE:compile [INFO] | | \- org.springframework:spring-context:jar:4.0.6.RELEASE:compile [INFO] | \- org.springframework:spring-webmvc:jar:4.0.6.RELEASE:compile [INFO] | \- org.springframework:spring-expression:jar:4.0.6.RELEASE:compile [INFO] +- org.springframework.boot:spring-boot-starter-test:jar:1.1.5.RELEASE:test [INFO] | +- org.mockito:mockito-core:jar:1.9.5:test [INFO] | | \- org.objenesis:objenesis:jar:1.0:test [INFO] | +- org.hamcrest:hamcrest-core:jar:1.3:test [INFO] | +- org.hamcrest:hamcrest-library:jar:1.3:test [INFO] | \- org.springframework:spring-test:jar:4.0.6.RELEASE:test [INFO] +- org.springframework.boot:spring-boot-starter-data-jpa:jar:1.1.5.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot-starter-aop:jar:1.1.5.RELEASE:compile [INFO] | | +- org.aspectj:aspectjrt:jar:1.8.1:compile [INFO] | | \- org.aspectj:aspectjweaver:jar:1.8.1:compile [INFO] | +- org.springframework.boot:spring-boot-starter-jdbc:jar:1.1.5.RELEASE:compile [INFO] | | +- org.springframework:spring-jdbc:jar:4.0.6.RELEASE:compile [INFO] | | +- org.apache.tomcat:tomcat-jdbc:jar:7.0.54:compile [INFO] | | | \- org.apache.tomcat:tomcat-juli:jar:7.0.54:compile [INFO] | | \- org.springframework:spring-tx:jar:4.0.6.RELEASE:compile [INFO] | +- org.hibernate:hibernate-entitymanager:jar:4.3.5.Final:compile [INFO] | | +- org.jboss.logging:jboss-logging-annotations:jar:1.2.0.Beta1:compile [INFO] | | +- org.hibernate:hibernate-core:jar:4.3.5.Final:compile [INFO] | | | +- antlr:antlr:jar:2.7.7:compile [INFO] | | | \- org.jboss:jandex:jar:1.1.0.Final:compile [INFO] | | +- dom4j:dom4j:jar:1.6.1:compile [INFO] | | | \- xml-apis:xml-apis:jar:1.0.b2:compile [INFO] | | +- org.hibernate.common:hibernate-commons-annotations:jar:4.0.4.Final:compile [INFO] | | +- org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile [INFO] | | +- org.jboss.spec.javax.transaction:jboss-transaction-api_1.2_spec:jar:1.0.0.Final:compile [INFO] | | \- org.javassist:javassist:jar:3.18.1-GA:compile [INFO] | +- org.springframework:spring-orm:jar:4.0.6.RELEASE:compile [INFO] | +- org.springframework.data:spring-data-jpa:jar:1.6.2.RELEASE:compile [INFO] | | +- org.springframework.data:spring-data-commons:jar:1.8.2.RELEASE:compile [INFO] | | +- org.slf4j:slf4j-api:jar:1.7.7:compile [INFO] | | \- org.slf4j:jcl-over-slf4j:jar:1.7.7:compile [INFO] | \- org.springframework:spring-aspects:jar:4.0.6.RELEASE:compile [INFO] +- com.h2database:h2:jar:1.3.176:compile [INFO] \- org.projectlombok:lombok:jar:1.14.0:provided [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.135 s [INFO] Finished at: 2015-03-23T00:53:09+09:00 [INFO] Final Memory: 12M/29M [INFO] ------------------------------------------------------------------------
org.springframework.boot:spring-boot-starter-data-jpaにぶら下がっているのがorg.hibernate:hibernate-entitymanagerであることから、JPAの実装としてHibernateであることがわかる。
JPAは仕様であって、それを実装したライブラリを実際には使用する。
実装したライブラリのことを「JPAプロバイダ」と言う。
なので、「今回のJPAプロバイダはHibernate」となる。
Hibernateの設定
Hibernateの設定をapplication.ymlに追加する。
src/main/resources/application.yml
このファイルに下記の内容を記載する。
spring: datasource: driverClassName: org.h2.Driver url: jdbc:h2:file:testdb/testdb username: sa password: jpa: hibernate: ddl-auto: update
datasourceの設定は準備編と同じ。
jpaからの設定を追加する。
ddl-autoはHibernateによるテーブル作成をどう制御するかを定義する。
以下のものがある。
- create-drop -> テーブルがあったら削除してから作り直す。なかったら作る。つまりデータは毎回消える。(UTに便利?)
- update -> テーブルの作り直しはしないが、なかったら作る。
- none -> なくても作らない。本番運用向き。
何を基にテーブルを作るかというと、下記で説明するエンティティクラスを基に作る。
なので、準備編で作成したschema.sqlは不要なので削除する。
エンティティクラスを用意する
準備編で作成したCustomerクラスをJPA用にカスタマイズする。
package tools.springsample.springsample03.domain; import javax.persistence.Entity; import javax.persistence.Table; import javax.persistence.Id; import javax.persistence.GeneratedValue; import javax.persistence.Column; import lombok.Data; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; @Entity // a @Table(name="customer") // b @Data @AllArgsConstructor @NoArgsConstructor public class Customer { @Id // c @GeneratedValue // d private Integer id; @Column(nullable=false) // e private String name; @Column(nullable=false) // e private String email; }
JPA用に変更したのは下記の通り。
a -> エンティティクラスであることを記すアノテーション。
b -> どのテーブルとマッピングするのか指定する。
c -> フィールドidがエンティティの主キーであることを表す。
d -> 自動採番する主キーであることを表す。
e -> テーブルに該当するカラムであることを表す。nullでの更新を抑制する。
リポジトリクラスを用意する
今まで作成したCustomerRepositoryクラスをJPA用に変更する。
(変更というかほとんど書き換え)
package tools.springsample.springsample03.repository; import tools.springsample.springsample03.domain.Customer; import org.springframework.data.jpa.repository.JpaRepository; public interface CustomerRepository extends JpaRepository<Customer, Integer> { }
クラスではなくインターフェースになる。
JpaRepositoryを拡張すると、実行時に実装クラスが自動生成される。
CRUDの各メソッドが用意されているので、それを呼ぶとデータベースを操作できる。
JPAを使ってSQLがソースから消えた。
コンパイルして実行
JDBC編で作成したAppクラスはそのまま使えるので、ここまでの状態でコンパイルして実行することができる。
mvn package
続いて起動。
java -jar target\SpringSample03-1.0-SNAPSHOT.jar
実行したあとデータベースを見て登録されることを確認すること。
やったことと言えば、1:設定書いて、2:エンティティ作って、3:リポジトリの宣言、の3ステップだけ。
これだけでデータベース更新できてしまうのが、手軽すぎて逆に怖い。
ただ、不明なことも見えてきた。
- JpaRepositoryを拡張して出来る検索は全検索かPKでの検索だけだが、他のキーで検索するにはどうする?
- ほかのテーブルをJOINして検索する場合はどうする?
- JpaRepositoryに主キーを知らせる(今回はInteger)が、複合主キー(複数カラムを用いた主キー)の場合はどうする?
これらは追々。
■ 参考文献 ■
この記事で参考にしたのは「はじめての Spring Boot」です。
はじめてのSpring Boot―「Spring Framework」で簡単Javaアプリ開発 (I・O BOOKS)
- 作者: 槇俊明
- 出版社/メーカー: 工学社
- 発売日: 2014/11
- メディア: 単行本
- この商品を含むブログ (6件) を見る
Spring Boot/第三回 Spring Bootでデータベース操作(JDBC編)
Spring Bootでデータベース操作をする。
前回の準備編に続いて、今回はデータベースに対してデータの操作を行う。
Spring Bootでのデータベース操作は
の2種類があるが、今回はJDBCの方の話。
依存関係の追加
まずはMavenの依存関係を追加するが、前回の準備編と同じなので、すでに記述していたら不要。
<dependencies> <!-- append start --> <dependency> <!-- a --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <!-- b --> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> <dependency> <!-- c --> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.14.0</version> <scope>provided</scope> </dependency> <!-- append end --> </dependencies>
a -> Spring BootでJDBCを扱うための依存関係。
b -> H2の依存関係。
c -> Lombokの依存関係。
行挿入
データベース操作はリポジトリの役目なので、CustomerRepositoryクラスに処理を書いて行く。
まずは行挿入から。
(第二回で宣言したgetCustomer()メソッドは不要なので削除した)
package tools.springsample.springsample03.repository; import tools.springsample.springsample03.domain.Customer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; import org.springframework.stereotype.Repository; @Repository public class CustomerRepository { @Autowired private NamedParameterJdbcTemplate jdbcTemplate; public Customer save(Customer customer) { // a SqlParameterSource param // b = new BeanPropertySqlParameterSource(customer); // c jdbcTemplate.update("insert into customer(name, email) " + " values(:name, :email)", param); // d return customer; } }
a -> 行挿入メソッド。これを実装する。
b -> SqlParameterSourceクラスは後のSQLの「:」で始まるプレースホルダのパラメータを保持するクラス。
c -> プレースホルダのマッピングにCustomerクラスのインスタンスを使用する。
Customerクラスのgetterメソッドを検知してデータを取得し、プレースホルダに当てはめてくれる。
d -> NamedParameterJdbcTemplateを使ってSQLを実行する。
第一引数がプレースホルダ付のSQL、第二引数がプレースホルダに当てはめる値が入ったcで作ったインスタンス。
プレースホルダの「:name」にCustomerクラスのgetName()メソッドで取得した値を、「:email」にgetEmail()メソッドで取得した値を当てはめてSQLを実行する。
続いてこのリポジトリクラスを呼び出すクラスを作成する。
package tools.springsample.springsample03; import tools.springsample.springsample03.domain.Customer; import tools.springsample.springsample03.repository.CustomerRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.ComponentScan; @EnableAutoConfiguration @ComponentScan public class App implements CommandLineRunner { @Autowired private CustomerRepository customerRepository; @Override public void run(String... strings) throws Exception { Customer customer01 = new Customer(); // a customer01.setName("user01"); // b customer01.setEmail("user01@foo.bar"); // c customerRepository.save(customer01); // d } public static void main(String[] args) { SpringApplication.run(App.class, args); } }
a -> ドメインクラスCustomerのインスタンスを作成。
b -> Customerの初期化。フィールドnameに「user01」を設定する。
c -> Customerの初期化。フィールドemailに「user01@foo.bar」を設定する。
d -> リポジトリクラスの行挿入メソッドを呼び出す。
実行すると以下のようなSQLが実行される。
insert into customer(name, email) values('user01', 'user01@foo.bar')
コンパイルして実行
以下のようにコンパイルする。
今回は実行したいのでコンパイルしてJARファイルでパッケージする。
mvn package
続いて起動。
今回はコマンドライン実行する「CommandLineRunner」を拡張したAppクラスなので、下記のコマンドで実行。
JARファイルは適宜読み替えましょう。
java -jar target\SpringSample03-1.0-SNAPSHOT.jar
実行したあとデータベースを見ると下記のように登録される。
ID | NAME | |
---|---|---|
1 | user01 | user01@foo.bar |
業務でJDBCを使って実装することはまれだと思うので、JDBC編はここまで。
■ 参考文献 ■
この記事で参考にしたのは「はじめての Spring Boot」です。
はじめてのSpring Boot―「Spring Framework」で簡単Javaアプリ開発 (I・O BOOKS)
- 作者: 槇俊明
- 出版社/メーカー: 工学社
- 発売日: 2014/11
- メディア: 単行本
- この商品を含むブログ (4件) を見る
Spring Boot/第三回 Spring Bootでデータベース操作(準備編)
Spring Bootでデータベース操作をする。
今回は準備編としてSpring Bootでのデータベース接続と、サンプルのドメインオブジェクトを作成する。
依存関係の追加
今回はH2を使う。
まずはMavenの依存関係を追加する。
<dependencies> <!-- append start --> <dependency> <!-- a --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <!-- b --> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> <dependency> <!-- c --> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.14.0</version> <scope>provided</scope> </dependency> <!-- append end --> </dependencies>
a -> Spring BootでJDBCを扱うための依存関係。
b -> H2の依存関係。
c -> Lombokの依存関係。
LombokはデータベースともSpring Bootとも関係はないが、Javaの短所の一つsetter/getter地獄から解放してくれたり、toString()・equals()メソッドを自動実装してくれたりしてくれるプロダクト。
コードが短くなるのでここで依存関係を追加する。
Lombokについて、詳しくはググりましょう。
データベース接続
アプリケーションが接続する先のデータベースを定義する。
定義は下記のYAML形式のファイルに行う。
src/main/resources/application.yml
このファイルに下記の内容を記載する。
spring: datasource: driverClassName: org.h2.Driver url: jdbc:h2:file:testdb/testdb username: sa password:
接続先はurlで指定していて、今回はカレントフォルダにtestdbフォルダを作って、その中に作成する。
実行環境によって作成される場所が変わるので注意が必要。
Spring Bootはクラスパス直下に下記のファイルがあると自動で実行する。
ファイル名からわかるように、schemaにはテーブル定義用のDDLを、dataには初期データ用のDMLを記載する。
どちらのファイルも起動するたびに実行されるので注意が必要。
つまりDDLはテーブルが存在する場合を考慮しないといけないし、DMLはキー重複しないよう考慮しないといけない。
・・・実際の業務ではあまり使わない機能かと思う。
今回はschema.sqlを使ってサンプルテーブルを作成する。
前述の通り、テーブルが存在する場合を考慮して「if not exists」を入れている。
create table if not exists customer ( id int primary key auto_increment, name varchar(50), email varchar(50) );
ここまででコンパイルする。
mvn compile
続いて起動
mvn spring-boot:run
するとプロジェクトフォルダに「testdb」フォルダが作成され、その中に「testdb.h2.db」と「testdb.lock.db」の2ファイルが生成される。
これがH2のデータベースファイルとなる。
起動後のコンソールの最後のに「Executing SQL script」とあり「schema.sql」を実行したとのことなので、テーブルが出来ているのでしょう。
ドメインオブジェクト
先ほど作ったcustomerテーブルのドメインオブジェクトを作る。
package tools.springsample.springsample03.domain; public class Customer { private Integer id; private String name; private String email; }
まずはcustomerテーブルのカラムと同名のフィールドを宣言する。
これだけだとprivateフィールドなのでどこからもアクセスできない。
setter/getter等が必要だが、決まりきった実装をするのが手間なので、ここで先述のLombokの出番となる。
Lombokを使って宣言すると下記のようになる。
package tools.springsample.springsample03.domain; import lombok.Data; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; @Data // a @AllArgsConstructor // b @NoArgsConstructor // c public class Customer { private Integer id; private String name; private String email; }
アノテーションを付けたのと、そのアノテーションのimportを追加した。
アノテーションの意味は下記の通り。
a -> すべてのフィールドに対するsetter/getterメソッド、equalsメソッド、hashCodeメソッド、toStringメソッドが生成される。
b -> すべてのフィールドを初期化する引数を持つコンストラクタが生成される。
c -> 引数なしのデフォルトコンストラクタが生成される。
これらの煩雑なコードを自動的に生成してくれるLombokは便利。
本当に生成されたのか、javapコマンドで見てみる。
Compiled from "Customer.java" public class tools.springsample.springsample03.domain.Customer { public java.lang.Integer getId(); public java.lang.String getName(); public java.lang.String getEmail(); public void setId(java.lang.Integer); public void setName(java.lang.String); public void setEmail(java.lang.String); public boolean equals(java.lang.Object); public int hashCode(); public java.lang.String toString(); public tools.springsample.springsample03.domain.Customer(java.lang.Integer, java.lang.String, java.lang.String); public tools.springsample.springsample03.domain.Customer(); }
@Dataで指定したgetterメソッドが3つ、setterメソッドが3つ、equalsメソッド、hashCodeメソッド、toStringメソッドが、
@AllArgsConstructorで指定した全フィールドを引数を持つコンストラクタが、
@NoArgsConstructorで指定したデフォルトコンストラクタが生成されたのがわかる。
ほかにどのようなアノテーションがあり、何が起きるかは、Lombokのサイトを参照。
http://projectlombok.org/features/index.html
準備編はここまで。
■ 参考文献 ■
この記事で参考にしたのは「はじめての Spring Boot」です。
はじめてのSpring Boot―「Spring Framework」で簡単Javaアプリ開発 (I・O BOOKS)
- 作者: 槇俊明
- 出版社/メーカー: 工学社
- 発売日: 2014/11
- メディア: 単行本
- この商品を含むブログ (4件) を見る
Spring Boot/第二回 Spring Bootで階層モデル
Spring Bootで階層モデルを実装する。
まずは実装の内容なしで、処理の呼び出しがうまくいくことを確認する。
階層モデルとは
Spring Bootの階層モデルは下記のようになる。
HTTPリクエストを起点にそれぞれの階層でそれぞれの役割を果たして処理をリレーする。
Controller
いわゆるMVCのコントローラ。
HTTPを受け取ってサービスを呼び出し、その結果からUIをコントロールする。
Service
ビジネスロジックを書く。
コントローラからの入力値をチェックしたり、データベースの値と比較したり、データベースへの書き込み要求をしたりする。
Repository
永続化処理を書く。
データベースから値を取ったり書いたりする。
Controller
コントローラは下記のように実装する。
@Controllerアノテーションを付けて宣言すると、そのクラスがコントローラとして機能する。
package tools.springsample.springsample02; import tools.springsample.springsample02.service.SampleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * Hello world! * */ @Controller // a -> コントローラの目印 @EnableAutoConfiguration // b -> Springの設定を自動でやってくれるオマジナイ @ComponentScan // c -> @Autowiredで指定したコンポーネントをスキャンする場所(パッケージ)を指定 // 自クラス配下なのでパラメータは不要 public class App { @Autowired // d -> DIコンテナからインスタンスを取得する private SampleService sampleService; @RequestMapping("/") // e -> URLとメソッドのマッピング @ResponseBody // f -> 戻り値をレスポンスとして返すという意味 public String hello() { System.out.println("★★★★★ Controller called."); return sampleService.getMessage(); } public static void main( String[] args ) { SpringApplication.run(App.class, args); } }
Service
サービスは下記のように実装する。
これもServiceアノテーションを付けて宣言すると、そのクラスがサービスとして機能する。
package tools.springsample.springsample02.service; import tools.springsample.springsample02.repository.CustomerRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service // DIする対象の目印 public class SampleService { @Autowired // d -> DIコンテナからインスタンスを取得する private CustomerRepository customerRepository; public String getMessage() { System.out.println("★★★★★ Service called."); return "Hello world. Hello "+customerRepository.getCustomer()+"."; } }
Repository
これもRepositoryアノテーションを付けて宣言すると、そのクラスがリポジトリとして機能する。
今は中身は空っぽで。
package tools.springsample.springsample02.repository; import org.springframework.stereotype.Repository; @Repository // DIする対象の目印 public class CustomerRepository { public String getCustomer() { System.out.println("★★★★★ Repository called."); return "Smith"; } }
コンパイルして実行
以下のようにコンパイルする。
mvn compile
続いて起動
mvn spring-boot:run
その後、http://localhost:8080/ にアクセスしてコマンドプロンプトに表示される内容を見てみる。
★★★★★ Controller called. ★★★★★ Service called. ★★★★★ Repository called.
お、それぞれの階層の処理が呼ばれている。
今日はここまで。
■ 参考文献 ■
この記事で参考にしたのは「はじめての Spring Boot」です。
はじめてのSpring Boot―「Spring Framework」で簡単Javaアプリ開発 (I・O BOOKS)
- 作者: 槇俊明
- 出版社/メーカー: 工学社
- 発売日: 2014/11
- メディア: 単行本
- この商品を含むブログ (4件) を見る
Gradleの導入
Gradle徹底入門を買ったので、試してみる。
Gradle徹底入門 次世代ビルドツールによる自動化基盤の構築
- 作者: 綿引琢磨,須江信洋,林政利,今井勝信
- 出版社/メーカー: 翔泳社
- 発売日: 2014/11/07
- メディア: Kindle版
- この商品を含むブログを見る
まずはGradleが起動するまで。
Java環境
GradleはGroovyで動くので。
GroovyはJavaで動くので。
Javaは必要。
Javaのインストールフォルダの環境変数「JAVA_HOME」が必要なので設定すること。
例えば以下のように。
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_25
バイナリダウンロード
Windows以外だとcurlコマンドで最小セットをダウンロードして初回起動にあれこれ自動でダウンロードしてくれるようだけど、Windowsはフルセットのバイナリをダウンロードしないとならないようだ。
Gradle2.3を以下からダウンロード。
https://services.gradle.org/distributions/gradle-2.3-bin.zip
インストール
ZIPファイルを適当なフォルダに解凍して、そこまでのパスを環境変数「GRADLE_HOME」に登録する。
さらに「GRADLE_HOME」の「bin」にパスを通す。
例えば以下のように。
set GRADLE_HOME=D:\Packages\Java\gradle-2.3 set %PATH%;%GRADLE_HOME%\bin
動くか確認
以下のコマンドで確認。
gradle -v
動いた動いた。
# gradle -v ------------------------------------------------------------ Gradle 2.3 ------------------------------------------------------------ Build time: 2015-02-16 05:09:33 UTC Build number: none Revision: 586be72bf6e3df1ee7676d1f2a3afd9157341274 Groovy: 2.3.9 Ant: Apache Ant(TM) version 1.9.3 compiled on December 23 2013 JVM: 1.8.0_25 (Oracle Corporation 25.25-b02) OS: Windows 7 6.1 x86
今日はここまで。
VMwareを使う勘所
VMwareを使う上で、いくつかポイントがあるので今更ながら自分用のメモとしてまとめておく。
メモリ関連のチューニング
一番パフォーマンスに影響するチューニング。
仮想環境を作ったら、いの一番にこれをコピペする。
構成ファイル(vmxファイル)をテキストエディタで開いて下記を追記する。
mainMem.useNamedFile= "FALSE" MemTrimRate = "0" sched.mem.pshare.enable = "FALSE" prefvmx.useRecommendedLockedMemSize = "TRUE" MemAllowAutoScaleDown = "FALSE"
以下、主なものの説明する。
mainMem.useNamedFile= "FALSE"
標準ではゲストOSのメモリ内容をvmemファイルに出力するが、それを使用しないように設定する。
ディスク容量関連のチューニング
仮想OSを使用していると徐々にディスクファイルが大きくなる(可変長にしている場合)。
時々最適化して圧縮すると良い。
今度はゲストOSからの操作で、コマンドプロンプトを立ち上げて、ゲストOSにインストールされているVMware Toolsの下記コマンドを実行する。
"C:\Program Files\VMware\VMware Tools\VMwareToolboxCmd.exe" disk shrink C:\
Dドライブを圧縮するなら
"C:\Program Files\VMware\VMware Tools\VMwareToolboxCmd.exe" disk shrink D:\
対象のドライブを表示したいなら
"C:\Program Files\VMware\VMware Tools\VMwareToolboxCmd.exe" disk list
実行にはかなりの時間がかかるのと、ホストOSのディスクを一時的に大量消費するので、時間とディスクにゆとりがあるときに実行する。
(ホストOSのディスク容量がなくなったから実行しようとしても、容量オーバーで実行できなかったのは自分)
ちなみにLinuxの場合は
sudo vmware-toolbox-cmd disk shrink /
ドライブの表示は
sudo vmware-toolbox-cmd disk list
Macの場合は
sudo /Library/Application\ Support/VMware\ Tools/vmware-tools-cli disk shrink /
ドライブの表示は
sudo /Library/Application\ Support/VMware\ Tools/vmware-tools-cli disk list
ドラッグアンドドロップ領域の削除
ゲストOSにファイルをコピーするのに、ゲストOSにファイルをドロップしてコピーするが、それは一時的にゲストOSの下記にコピーされる。
C:\Users\%ログインユーザー%\AppData\Local\Temp\VMwareDnD
「%ログインユーザー%」はユーザーごとに読み替えること。
ゲストOSのシャットダウン等、タイミングを見て消してくれるらしいが、たまに残ったままなので気になった時に消すと良い。
前述のディスク容量関連のチューニングをする前には必ず消すこと。
ここが残ってたら圧縮の妨げになる。
ディスクを読み取り専用にする
構成ファイル(vmxファイル)をテキストエディタで開いて下記を追記する。
scsi0:0.mode = "independent-nonpersistent"
指定したディスクとパーティションを「読み取り専用」にして起動してくれる。
UUIDを常に更新する/更新しない
仮想環境には必ずUUIDが割り当てられる。
このUUIDは下記のページによると「物理コンピュータの識別子と仮想マシンの構成ファイルのパスを基に決められます」とあるので、仮想環境を別のPCに移動すると起動時に「この仮想マシンは移動またはコピーされた可能性があります。」とメッセージが表示されて移動したのかコピーしたのか問われる。
この時に「コピーした」と答えると新たなUUIDが生成され更新される(併せてMACアドレスも生成される)。
「移動した」と答えるとUUIDは更新されない。
VMware KB: 移動した仮想マシンの UUID の変更または保持
このメッセージ出力を抑制して常に「コピーした」とするか「移動した」とするかの制御が構成ファイル(vmxファイル)の「uuid.action」の値で制御出来る。
構成ファイルのパスを変更した時にUUIDを常に更新する場合は、構成ファイル(vmxファイル)をテキストエディタで開いて下記を追記する。
uuid.action = "create"
逆に構成ファイルのパスを変更してもUUIDを更新しない場合は、構成ファイル(vmxファイル)をテキストエディタで開いて下記を追記する。
uuid.action = "keep"