データ]** リンク:/category/persistence/spring-persistence/[Spring Persistence]
-
リンク:/tag/couchbase/[Couchbase]
1前書き
このSpring Dataのチュートリアルでは、Spring Dataリポジトリとテンプレートの抽象化の両方を使用してCouchbaseドキュメント用の永続層を設定する方法、およびビューやインデックスを使用してこれらの抽象化をサポートするCouchbaseを準備するために必要な手順について説明します。 。
2 Mavenの依存関係
まず、 pom.xml ファイルに次のMaven依存関係を追加します。
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-couchbase</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
この依存関係を含めることで、ネイティブのCouchbase SDKの互換バージョンが自動的に取得されるので、明示的に含める必要はありません。
JSR-303 Bean検証のサポートを追加するために、以下の依存関係も含めます。
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>
Spring Data Couchbaseは、従来のDateクラスとCalendarクラス、およびJoda Timeライブラリを介して日付と時刻の永続化をサポートしています。
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.2</version>
</dependency>
3構成
次に、Couchbaseクラスタの1つ以上のノードと、ドキュメントを保存するバケットの名前とパスワードを指定して、Couchbase環境を設定する必要があります。
3.1. Javaの設定
Javaクラス設定の場合は、単純に AbstractCouchbaseConfiguration クラスを拡張します。
@Configuration
@EnableCouchbaseRepositories(basePackages={"org.baeldung.spring.data.couchbase"})
public class MyCouchbaseConfig extends AbstractCouchbaseConfiguration {
@Override
protected List<String> getBootstrapHosts() {
return Arrays.asList("localhost");
}
@Override
protected String getBucketName() {
return "baeldung";
}
@Override
protected String getBucketPassword() {
return "";
}
}
プロジェクトでCouchbase環境をさらにカスタマイズする必要がある場合は、 getEnvironment() メソッドをオーバーライドして提供することができます。
@Override
protected CouchbaseEnvironment getEnvironment() {
...
}
3.2. XML設定
これはXMLの同等の設定です。
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/data/couchbase
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/couchbase
http://www.springframework.org/schema/data/couchbase/spring-couchbase.xsd">
<couchbase:cluster>
<couchbase:node>localhost</couchbase:node>
</couchbase:cluster>
<couchbase:clusterInfo login="baeldung" password=""/>
<couchbase:bucket bucketName="baeldung" bucketPassword=""/>
<couchbase:repositories base-package="org.baeldung.spring.data.couchbase"/>
</beans:beans>
注:“ clusterInfo ”ノードはクラスタの認証情報またはバケットの認証情報のいずれかを受け入れ、CouchbaseクラスタがN1QL(NoSQLデータベース用のSQLのスーパーセット、Couchbase 4.0以降で利用可能)をサポートするかどうかを判断するために必要です。
プロジェクトにカスタムCouchbase環境が必要な場合は、 <couchbase:env/> タグを使用して提供することができます。
4データ・モデル
永続化するJSONドキュメントを表すエンティティクラスを作成しましょう。
最初にクラスに @ Document、 という注釈を付け、次に String フィールドに @ Id という注釈を付けてCouchbaseのドキュメントキーを表します。
Spring Dataの @ Id アノテーションまたはネイティブのCouchbase SDKのアノテーションを使用できます。 2つの異なるフィールドで同じクラス内で両方の @ Id アノテーションを使用すると、Spring Data @ Id アノテーションでアノテーションが付けられたフィールドが優先され、ドキュメントキーとして使用されます。
JSONドキュメントの属性を表すために、 @ Field というアノテーションを付けたプライベートメンバー変数を追加します。 @ NotNull アノテーションを使用して、特定のフィールドを必要に応じてマークします。
@Document
public class Person {
@Id
private String id;
@Field
@NotNull
private String firstName;
@Field
@NotNull
private String lastName;
@Field
@NotNull
private DateTime created;
@Field
private DateTime updated;
//standard getters and setters
}
@ Id というアノテーションが付けられたプロパティは単にドキュメントキーを表しているだけで、次のように @ Field もアノテーションが付けられている場合を除き、格納されているJSONドキュメントの一部ではありません。
@Id
@Field
private String id;
エンティティクラスのフィールドにJSONドキュメントに格納されるものとは異なる名前を付ける場合は、次の例のように単に @ Field アノテーションを修飾します。
@Field("fname")
private String firstName;
永続化された Person ドキュメントがどのように見えるかを示す例です。
{
"firstName": "John",
"lastName": "Smith",
"created": 1457193705667
"__class": "org.baeldung.spring.data.couchbase.model.Person"
}
Spring Dataは、各ドキュメントにエンティティのフルクラス名を含む属性を自動的に追加します。デフォルトでは、この属性の名前は “ class” ですが、Couchbaseの設定クラスでは typeKey()__メソッドをオーバーライドすることでオーバーライドできます。
たとえば、クラス名を保持するために “ dataType” という名前のフィールドを指定したい場合は、これをCouchbase設定クラスに追加します。
@Override
public String typeKey() {
return "dataType";
}
typeKey() をオーバーライドするもう1つの一般的な理由は、アンダースコアが前に付いたフィールドをサポートしないCouchbase Mobileのバージョンを使用している場合です。この場合は、前の例のように独自の代替タイプフィールドを選択することも、Springが提供する代替タイプを使用することもできます。
@Override
public String typeKey() {
//use "javaClass" instead of "__class"
return MappingCouchbaseConverter.TYPEKEY__SYNCGATEWAY__COMPATIBLE;
}
5 Couchbaseリポジトリ
Spring Data CouchbaseはJPAなどの他のSpring Dataモジュールと同じ組み込みクエリと派生クエリメカニズムを提供します。
CrudRepository <String、Person> を拡張し、派生クエリメソッドを追加して、 Person クラスのリポジトリインタフェースを宣言します。
public interface PersonRepository extends CrudRepository<Person, String> {
List<Person> findByFirstName(String firstName);
}
6. インデックスを介したN1QLのサポート
Couchbase 4.0以降を使用している場合、デフォルトではカスタムクエリはN1QLエンジンを使用して処理されます(次のセクションで説明するように、対応するリポジトリメソッドにバッキングビューの使用を示す @ View のアノテーションが付いていない場合)
N1QLのサポートを追加するには、バケットにプライマリインデックスを作成する必要があります。
インデックスを作成するには、 cbq コマンドラインクエリプロセッサを使用し(環境に合わせて cbq ツールを起動する方法についてはCouchbaseのドキュメントを参照)、次のコマンドを発行します。
CREATE PRIMARY INDEX ON baeldung USING GSI;
上記のコマンドで、 GSI は global secondary index を表します。これは、OLTPシステムをサポートするアドホックN1QLクエリの最適化に特に適した種類のインデックスで、特に指定がない場合はデフォルトのインデックスタイプです。
ビューベースのインデックスとは異なり、GSIインデックスはクラスタ内のすべてのインデックスノードに自動的に複製されないため、クラスタに複数のインデックスノードが含まれる場合は、クラスタ内の各ノードに各GSIインデックスを作成する必要があり各ノードで異なるインデックス名。
1つ以上の副次索引を作成することもできます。実行すると、Couchbaseはクエリ処理を最適化するために必要に応じてそれらを使用します。
たとえば、 firstName フィールドにインデックスを追加するには、 cbq ツールで次のコマンドを発行します。
CREATE INDEX idx__firstName ON baeldung(firstName) USING GSI;
7. バッキングビュー
各リポジトリインターフェースに対して、Couchbaseのデザインドキュメントとターゲットバケットに1つ以上のビューを作成する必要があります。デザインドキュメントの名前は、エンティティクラス名の lowerCamelCase バージョン(例: "person" )である必要があります。
どのバージョンのCouchbase Serverを実行しているかに関わらず、組み込みの“ findAll” リポジトリメソッドをサポートするために “ all” という名前のバッキングビューを作成する必要があります。これは、 Person クラスの “ all” ビューのマップ関数です。
function (doc, meta) {
if(doc.__class == "org.baeldung.spring.data.couchbase.model.Person") {
emit(meta.id, null);
}
}
4.0より前のバージョンのCouchbaseを使用する場合、カスタムリポジトリメソッドはそれぞれバッキングビューを持つ必要があります(バッキングビューの使用は4.0以降ではオプションです)。
次の例のように、ビューを基にしたカスタムメソッドに @ View というアノテーションを付ける必要があります。
@View
List<Person> findByFirstName(String firstName);
バッキングビューのデフォルトの命名規則は、“ find” キーワードに続くメソッド名のその部分の lowerCamelCase バージョンを使用することです(例: “ byFirstName” )。
これは、 “ byFirstName” ビューのマップ関数を作成する方法です。
function (doc, meta) {
if(doc.__class == "org.baeldung.spring.data.couchbase.model.Person"
&& doc.firstName) {
emit(doc.firstName, null);
}
}
それぞれの @ View アノテーションを対応するバッキングビューの名前で修飾することで、この命名規則をオーバーライドして独自のビュー名を使用することができます。例えば:
@View("myCustomView")
List<Person> findByFirstName(String lastName);
8サービス層
私たちのサービス層のために、私たちはインターフェースと2つの実装を定義します:
1つはSpring Dataリポジトリの抽象化を使用し、もう1つはSpring Dataテンプレートの抽象化を使用します。これが PersonService インターフェースです。
public interface PersonService {
Person findOne(String id);
List<Person> findAll();
List<Person> findByFirstName(String firstName);
void create(Person person);
void update(Person person);
void delete(Person person);
}
8.1. リポジトリサービス
これは上で定義したリポジトリを使った実装です。
@Service
@Qualifier("PersonRepositoryService")
public class PersonRepositoryService implements PersonService {
@Autowired
private PersonRepository repo;
public Person findOne(String id) {
return repo.findOne(id);
}
public List<Person> findAll() {
List<Person> people = new ArrayList<Person>();
Iterator<Person> it = repo.findAll().iterator();
while(it.hasNext()) {
people.add(it.next());
}
return people;
}
public List<Person> findByFirstName(String firstName) {
return repo.findByFirstName(firstName);
}
public void create(Person person) {
person.setCreated(DateTime.now());
repo.save(person);
}
public void update(Person person) {
person.setUpdated(DateTime.now());
repo.save(person);
}
public void delete(Person person) {
repo.delete(person);
}
}
8.2. テンプレートサービス
テンプレートベースの実装では、上記のセクション7にリストされているバッキングビューを作成する必要があります。 CouchbaseTemplate オブジェクトはSpringのコンテキストで利用可能であり、サービスクラスに注入されるかもしれません。
これはテンプレート抽象化を使った実装です。
@Service
@Qualifier("PersonTemplateService")
public class PersonTemplateService implements PersonService {
private static final String DESIGN__DOC = "person";
@Autowired
private CouchbaseTemplate template;
public Person findOne(String id) {
return template.findById(id, Person.class);
}
public List<Person> findAll() {
return template.findByView(ViewQuery.from(DESIGN__DOC, "all"), Person.class);
}
public List<Person> findByFirstName(String firstName) {
return template.findByView(ViewQuery.from(DESIGN__DOC, "byFirstName"), Person.class);
}
public void create(Person person) {
person.setCreated(DateTime.now());
template.insert(person);
}
public void update(Person person) {
person.setUpdated(DateTime.now());
template.update(person);
}
public void delete(Person person) {
template.remove(person);
}
}
9結論
Spring Data Couchbaseモジュールを使用するようにプロジェクトを構成する方法、および単純なエンティティークラスとそのリポジトリーインターフェースを記述する方法を示しました。簡単なサービスインターフェイスを書き、リポジトリを使った実装とSpring DataテンプレートAPIを使った実装を提供しました。
このチュートリアルの完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/persistence-modules/spring-data-couchbase-2[GitHubプロジェクト]にあります。
詳細については、http://projects.spring.io/spring-data-couchbase/[Spring Data Couchbase]プロジェクトサイトを参照してください。