SlideShare une entreprise Scribd logo
1  sur  51
Télécharger pour lire hors ligne
© 2012 SpringSource, A division of VMware. All rights reserved
Spring Data in a Nutshell
Tsuyoshi Miyake (@tsuyokb)
22
背景と動機
§ RDBMS はいまだ重要かつ支配的
• ただ “one size fits all” ではなくなってきている
§ Spring はデータアクセスに常に優れたサポートを行ってきた
§ Spring Data project のゴールは Spring のデータサポートを “リフレッシュ”
すること
• Traditional: JDBC, JPA
• New: Grid, Document, Graph, K-V (aka NoSQL or NewSQL)
§ なじみの一貫性のある Spring ベースのプログラミングモデルを提供
• 個々の技術的特徴はいかしながら
§ データアクセス層から boiler-plate code をなくす
• 異なるテクノロジーをまたがって利用できる共通のインタフェース
33
Spring Data は “umbrella project”
§ http://www.springframework.org/spring-data
§ JPA - Repositories
§ JDBC Extensions
§ MongoDB – Document Database
§ Neo4j – Graphs Database
§ Redis – Key Value Database
§ Gemfire – Distributed Data Grid
§ Commons – shared abstractions
• Repositories
• Object Mapping
§ QueryDSL – integration with type-safe query API
44
Spring Data Repositories (1/3)
public interface CrudRepository<T, ID extends Serializable> extends
Repository<T, ID> {
T save(T entity);
Iterable<T> save(Iterable<? extends T> entities);
T findOne(ID id);
boolean exists(ID id);
Iterable<T> findAll();
long count();
void delete(ID id);
void delete(T entity);
void delete(Iterable<? extends T> entities);
void deleteAll();
}
public interface Repository<T, ID extends Serializable> {
// マーカーインタフェース ex.) Repository<Customer, Long>
}
55
Spring Data Repositories (2/3)
public interface PagingAndSortingRepository<T, ID extends Serializable> extends
CrudRepository<T, ID> {
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);
}
§ “naming conventions” によるクエリメソッドの定義
public interface PersonRepository extends CrudRepository<Person,BigInteger> {
// Finder for a single entity
Person findByEmailAddress(String emailAddress);
// Finder for a multiple entities
List<Person> findByLastnameLike(String lastName);
// Finder with pagination
Page<Person> findByFirstnameLike(String firstName, Pageable page);
}
66
Spring Data Repositories (3/3)
@NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable> extends
Repository<T, ID> {
Iterable<T> findAll(Pageable sort);
<S extends T> S save(S entity);
<S extends T> S save(Iterable<S> entities);
}
§ Custom Repository インタフェースの定義
• CRUD は便利だが Read のみを提供したい、または Delete は提供したくない etc.
§ 定義方法
1. Repository を継承(or @RepositoryDefinition を付与)したインタフェースを定義
2. 公開したいメソッドのみをそのインタフェースに定義(ただし、メソッドシグネチャー
は Spring Data Repository と同一にする)
3. 出来上がったインタフェースを entity のベースに
77
Spring Data JPA – Entity Mapping
§ インタフェースを定義するだけ:
• PersonRepository の実装は Spring (Data) が提供
<jpa:repositories base-package="com.acme.repository" />
@Entity
public class Person {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private BigInteger id;
private String firstname, lastname;
@Column(name="email")
private String emailAddress;
@OneToMany
private Set<Person> colleagues;
}
@EnableJpaRepositoriesJavaConfig
XML
88
Spring Data JPA
§ transactional service layer (通常通り)
@Service
public class DefaultUserManagementService implements UserManagementService {
public PersonRepository personRepository;
public ShiftRepository shiftRepository;
@Autowired
public DefaultUserManagementService(PersonRepository personRepository,
ShiftRepository shiftRepository) {
this.personRepository = personRepository;
this.shiftRepository = shiftRepository;
}
@Transactional
public void assignToNightShift(String emailAddress) {
Person person = personRepository.findByEmailAddress(emailAddress);
// continue processing
}
}
99
Spring Data JPA
§ クエリメソッド(naming conventions ベース)
• Query annotation でオーバーライド可能
• JPA named query (@NamedQuery) の参照も可.
public interface PersonRepository extends CrudRepository<Person,BigInteger> {
// previous methods omitted…
@Query("select p from Person p where p.emailAddress = ?1")
Person findByEmailAddress(String emailAddress);
@Query("select p from Person p where p.firstname = :firstname or p.lastname = :lastname")
Person findByLastnameOrFirstname(@Param("lastname") String lastname,
@Param("firstname") String firstname);
}
1010
QueryDSL
§ ”タイプセーフ”な SQL-like なクエリを生成するためのフレームワーク
• http://www.querydsl.com/
• Open Source, Apache 2.0
§ IDE のコード補完フレンドリー
§ 不適切なクエリが構造上不可能(存在しないカラムへのアクセス etc.)
§ ドメインのプロパティと型への安全なアクセス(非文字列)
§ Java annotation processor (QueryDSL annotation processor) による
Q<DomainClass> の自動生成
§ Criteria API (JPA 2) より簡潔かつ通常の Java Collection にも使える
private static final QProduct $ = QProduct.product;
macBook = new Product("MacBook Pro", "Apple laptop");
iPad = new Product("iPad", "Apple tablet");
// …
products = Arrays.asList(macBook, iPad, iPod, turntable);
List<Product> result = from($, products).where($.description.contains("Apple")).list($);
1111
QueryDSL - Repositories
§ Repository に QueryDSL interface を拡張(追加)
• QueryDSL の Predicate を引数にもつメソッド
• JPA, MongoDB
public interface QueryDSLPredicateExecutor<T> {
long count(com.mysema.query.types.Predicate predicate);
T findOne(Predicate predicate);
List<T> findAll(Predicate predicate);
List<T> findAll(Predicate predicate, OrderSpecifier<?>... orders);
Page<T> findAll(Predicate predicate, Pageable pageable);
}
public interface CustomerRepository extends Repository<Customer, Long>,
QueryDslPredicateExecutor<Customer> {
// Your query methods here
}
QCustomer customer = QCustomer.customer;
LocalDate today = new LocalDate();
BooleanExpression customerHasBirthday = customer.birthday.eq(today);
BooleanExpression isLongTermCustomer = customer.createdAt.lt(today.minusYears(2));
customerRepository.findAll(customerHasBirthday.and(isLongTermCustomer));
1212
MongoDB
§ ドキュメント・データストア
§ ドキュメント == 構造化されたデータ (e.g. XML, JSON)
§ JSON スタイルのドキュメント (BSON)
• 基本的に Map、値にプリミティブ/コレクション/ネストのドキュメント型
§ ドキュメントはコレクションというコンテナ(~テーブル)に格納される
§ Index サポート – 任意の attribute に
§ リッチな query language
… 続きは http://www.mongodb.org/ で
{
firstname : "Dave",
lastname : "Matthews",
addresses : [ { city : "New York", street : "Broadway" } ]
}
1313
MongoDB Java API を使う (1/2)
public void mongoBasic() throws Exception {
Mongo mongo = new Mongo();
DB db = mongo.getDB("database");
DBCollection customers = db.getCollection("customers");
DBObject address = new BasicDBObject("city", ”Kobe");
address.put("street", "Broadway");
DBObject addresses = new BasicDBList();
((BasicDBList) addresses).add(address);
DBObject customer = new BasicDBObject("firstname", "Tsuyoshi");
customer.put("lastname", "Miyake");
customer.put("addresses", addresses);
customers.insert(customer);
System.out.println(customers.findOne());
}
}
1414
MongoDB Java API を使う (2/2)
§ Mongo クラスを使用
§ サーバに関する詳細は隠蔽される
§ Insert / Update
• (全ての)アプリケーション POJO -> DBObject にマップする必要あり
• mongo.getDatabase(…).getCollection(…).insert(…)
§ クエリ
• クエリを組み立て、
• mongo.getDatabase(…).getCollection(…).find(…)
• カーソルを使って結果を iterate
• DBObject -> アプリケーション POJO マップ(手動)
è JDBC よりは抽象化されていそうだけど(繰り返しが多い) …
1515
Spring Data MongoDB
§ MongoTemplate
• MongoDB 特有のオペレーションへのアクセス: geo, map/reduce etc.
• Fluent Query, Criteria, Update APIs
§ Object-Document マッピング
§ Repository サポート
§ Spring XML namespace (e.g. <mongo:XXX>)
§ QueryDSL サポート
§ JMX / Logging
1616
Spring Data MongoDB – Entity Mapping (1/3)
@Document
public class Customer {
@Id
private BigInteger id;
private String firstname, lastname;
@Field("email")
@Indexed(unique = true)
private EmailAddress emailAddress;
private Set<Address> addresses = new HashSet<Address>();
public Customer(String firstname, String lastname) {
Assert.hasText(firstname);
Assert.hasText(lastname);
this.firstname = firstname;
this.lastname = lastname;
}
…
}
1717
Spring Data MongoDB – Entity Mapping (2/3)
public final class EmailAddress {
private static final String EMAIL_REGEX = “…";
private static final Pattern PATTERN = Pattern.compile(EMAIL_REGEX);
@Field("email")
private final String value;
public EmailAddress(String emailAddress) {
Assert.isTrue(isValid(emailAddress), "Invalid email address!");
this.value = emailAddress;
}
… }
public class Address {
private final String street, city, country;
public Address(String street, String city, String country) {
Assert.hasText(street, "Street must not be null or empty!");
…
this.street = street;
this.city = city;
this.country = country;
}
… }
1818
Spring Data MongoDB – Entity Mapping (3/3)
public void mongoSpring() throws Exception {
MongoMappingContext context = new MongoMappingContext();
MongoDbFactory dbFactory = new SimpleMongoDbFactory(new Mongo(),
"database");
MappingMongoConverter converter = new MappingMongoConverter(dbFactory,
context);
Customer customer = new Customer("Tsuyoshi", "Miyake");
customer.setEmailAddress(new EmailAddress("tmiyake@vmware.com"));
customer.add(new Address("Minato-ku", "Tokyo", "Japan"));
DBObject sink = new BasicDBObject();
converter.write(customer, sink);
System.out.println(sink.toString());
}
{ "_class" : "com.oreilly.springdata.mongodb.core.Customer”
, "_id" : null ,
"firstname" : "Tsuyoshi" ,
"lastname" : "Miyake" ,
"email" : { "email" : "tmiyake@vmware.com"} ,
"addresses" : [ { "street" : "Minato-ku" , "city" : "Tokyo" , "country" : "Japan"}]}
1919
Spring Data Mongo – MongoTemplate 使用法
@Autowired
MongoTemplate template; // in AbstractMongoConfiguration (JavaConfig)
@Test
public void mongoTemplate() throws Exception {
Customer customer = new Customer("Kirari", "Miyake");
customer.setEmailAddress(new EmailAddress("kirari.miyake@gmail.com"));
template.save(customer);
Query query = new Query(
new
Criteria("emailAddress").is("kirari.miyake@gmail.com"));
assertThat(template.findOne(query, Customer.class), is(customer));
}
@Configuration
@ComponentScan
@EnableMongoRepositories
class ApplicationConfig extends AbstractMongoConfiguration {
@Override
protected String getDatabaseName() { return ”database”; }
@Override
public Mongo mongo() throws Exception {…}
… }
2020
Spring Data Mongo - Repositories
§ Spring Data Commons の Repository 同様
• インタフェースの定義(のみ) & naming convention
2121
Spring Data Mongo – Repository 使用法
or @EnableMongoRepositories in JavaConfig
2222
Neo4j
§ グラフデータベース
§ DB はグラフのノード (nodes) と関連 (relationships) から成る
• Nodes と relationships はプロパティーをもつ
§ Cypher Query Language
§ Indexes on node/relationship プロパティー
§ Java で記述されている、アプリケーションへ組み込み可能
• Also a REST API (Neo4j Server)
§ Transactional (ACID)
… 続きは http://neo4j.org/ で
2323
Neo4j データモデル
2424
Spring Data Neo4j
§ Neo4jTemplate
• Neo4j 特有のオペレーションへのアクセス: get/create Node and Relationship,
query, traverse, fluent query Result handling
• トランザクション管理
• Exception translation to Spring’s DAO exception hierarchy
• Also works via REST with Neo4jServer
§ アノテーションベースの Entity 定義(@NodeEntity/@RelationshipEntity..)
§ Repository サポート
§ Cypher query language
§ Spring XML namespace (<neo4j:XXX>)
§ Neo4j Server 統合
<bean id="graphDatabaseService" class="org.springframework.data.neo4j.rest.SpringRestGraphDatabase”
/>
2525
Classic Neo4j – Entity class
public class Person {
private final Node underlyingNode;
public Person(final Node node) {
underlyingNode = node;
}
public Node getUnderlyingNode() {
return underlyingNode;
}
public final String getName() {
return (String) underlyingNode.getProperty(“name”);
}
public void setName(final String name) {
underlyingNode.setProperty(“name”, name);
}
}
2626
Spring Data Neo4j – Entity class
@NodeEntity
public class Actor {
@Indexed // Neo4jTemplate.getOrCreateNode() etc. で利用可能
private String id;
@Indexed(indexType=IndexType.FULLTEXT , indexName=“people")
private String name;
public Person(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() { return id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
2727
Spring Data Neo4j – Entity class
@NodeEntity
public class Movie {
@Indexed
private String id;
@Indexed(indexType=IndexType.FULLTEXT , indexName=“search")
private String title;
// Collection of other nodes
@RelatedTo(type = "ACTS_IN", direction= INCOMING)
private Set<Actor> actors;
// Collection of relationships (actor -> (rating) -> movie)
@RelatedToVia(type = “RATED", direction= INCOMING)
private Set<Rating> rating;
public Movie(String id, String title) {
this.id = id;
this.title = title;
}
// Getters and Setters omitted
}
2828
Spring Data Neo4j - Repositories
§ Spring Data Commons の Repository 同様
• インタフェースの定義(のみ) & naming convention
§ Support for
• CRUD
• IndexRepository (findAllByPropertyValue, findAllByQuery etc.)
• TraversalRepository (findAllByTraversal)
public interface MovieRepository extends GraphRepository<Movie>,
NamedIndexRepository<Movie>,
RelationshipOperationsRepository<Movie> {
Movie findById(String id);
Page<Movie> findByTitleLike(String title, Pageable page);
@Query("start user=node({0}) " +
" match user-[r:RATED]->movie<-[r2:RATED]-other-[r3:RATED]->otherMovie " +
" where r.stars >= 3 and r2.stars >= 3 and r3.stars >= 3 " +
" return otherMovie, avg(r3.stars) " +
" order by avg(r3.stars) desc, count(*) desc" +
" limit 10")
List<MovieRecommendation> getRecommendations(User user);
}
<neo4j:repositories base-package="org.neo4j.cineasts.repository"/>
2929
Spring Data Neo4j – Neo4jTemplate
public void setUp() throws Exception {
dave = template.save(new Customer("Dave", "Matthews", "dave@dmband.com"));
template.save(new Customer("Carter","Beauford","carter@dmband.com"));
template.save(new Customer("Boyd","Tinsley","boyd@dmband.com"));
final Country usa = template.save(new Country("US", "United States"));
template.save(new Address("27 Broadway","New York",usa));
iPad = template.save(
new Product("iPad", "Apple tablet device")
.withPrice(BigDecimal.valueOf(499D)));
mbp = template.save(
new Product("MacBook Pro", "Apple notebook")
.withPrice(BigDecimal.valueOf(1299D)));
final Order order = new Order(dave);
order.add(iPad,2);
order.add(mbp,1);
template.save(order);
}
3030
Redis
§ Advanced key-value store
• 軽量 & 高パフォーマンス (in-memory)
• Values: binary strings, Lists, Sets, Ordered Sets, Hash maps, ..
• データタイプごとの操作: e.g. list への追加 ([RL]PUSH), set への追加
(SADD), retrieving a slice of a list (LRANGE key start end), …
• 各操作がアトミック (e.g. INCR)
§ Very fast: ~100K operations/second on entry-level hardware
§ 永続化対応
• Periodic snapshots (point-in-time)
• Write コマンドのログファイルへの書き出し (append-based)
§ PUB/SUB
§ トランザクション対応 (MULTI <-> EXEC)
§ 多言語対応, all separate open source projects
… 続きは http://redis.io/ で
K1
K2
K3
V1
V2
V2
3131
Spring Data Redis
§ Redis ドライバに依存しない統一された API を提供
§ RedisTemplate
• Redis の機能実装。各データタイプごとに専用のインタフェース
• Value/Hash/Set/Zset/ListOperations
• 名前は分かりやすいように変換: SETNX -> putIfAbsent()
• 自動で serialization と型変換を実施
• Fluent query API
§ 非同期 Publish-Subscribe サポート with message listener containers
§ JDK Atomic counters (AtomicLong etc.) backed by Redis
§ Spring 3.1 Cache abstraction provider
3232
Spring Data Redis – RedisTemplate – 型変換
<bean id="conFactory“ class="o.s.d.r.connection.jedis.JedisConnectionFactory"/>
<bean id=“template“ class="o.s.d.redis.core.StringRedisTemplate"
p:connection-factory-ref="conFactory"/>
@Bean
public RedisTemplate<String, Long> longTemplate() {
RedisTemplate<String, Long> tmpl = new RedisTemplate<String, Long>();
tmpl.setConnectionFactory( redisConnectionFactory() );
tmpl.setValueSerializer(LongSerializer.INSTANCE);
return tmpl;
}
public static enum LongSerializer implements RedisSerializer<Long> {
INSTANCE;
@Override public byte[] serialize( Long aLong ) throws SerializationException {
if ( null != aLong ) { return aLong.toString().getBytes(); }
else { return new byte[0]; }
}
@Override public Long deserialize( byte[] bytes ) throws SerializationException {
if ( bytes.length > 0 ) {
return Long.parseLong( new String( bytes ) );
} else { return null; }
}
}
3333
Spring Data Redis – RedisTemplate – アトミック操作
@Autowired RedisConnectionFactory connectionFactory;
@Test public void testAtomicCounters() {
RedisAtomicLong counter = new RedisAtomicLong("spring-data-book:counter-
test:hits", connectionFactory, 0);
Long l = counter.incrementAndGet();
assertThat(l, is(greaterThan(0L)));
}
3434
Spring Data Redis – RedisTemplate – Pub/Sub
@Configuration
public class PubSubConfig extends ApplicationConfig {
public static final String DUMP_CHANNEL = ”pubsub-test:dump";
@Bean RedisMessageListenerContainer container() {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisConnectionFactory());
container.addMessageListener(dumpToConsoleListener(), new ChannelTopic(DUMP_CHANNEL));
return container;
}
@Bean MessageListener dumpToConsoleListener() {
return new MessageListener() {
@Override public void onMessage(Message message, byte[] pattern) {
System.out.println("FROM MESSAGE: " + new String(message.getBody()));
}
};
}
}
@Test public void testPubSubWithoutConversion() {
RedisConnection redis = connectionFactory.getConnection();
try {
redis.publish( PubSubConfig.DUMP_CHANNEL.getBytes(), "Hello World!".getBytes() );
} finally { redis.close(); }
}
3535
• 分散/メモリーベースのデータ管理プラットフォ
ーム
• データトランザクションの多いアプリケーション
に対し、可用性、高パフォーマンス、スケーラビ
リティを提供
• データの一貫性を場合に応じて調節可能(分散
ロックのレベル)
• イベントドリブンなアーキテクチャ
… 続きは
http://www.vmware.com/support/pubs/vfabri
c-gemfire.html で
GemFire – The Enterprise Data Fabric
Java
Client
C#
Client
C++
Client
3636
GemFire High Level アーキテクチャ
Java
Client
C#
Client
C++
Client クライアントは Cache を組
み込み可能 (with disk
overflow)
物理的なサーバー群がひとつの
巨大な論理システムとしてみえ
る (DistributedSystem)
オブジェクトの変更がサブス
クライバに伝達される
同期 R/W、非同期 Write
データのパーティショニン
グ・レプリケーションはクライ
アントからは透過的に扱わ
れる。
また、ストレージにメモリデ
ータをバックアップ可能
動的にノードを追加可能
3737
• Cache がインメモリのストレージ、およびデータ管
理を提供 (RDBMS でいうところの Database)
• XML (cache.xml) and/or API calls の組合せで
Cache を構成
• 複数の Regions から構成される
Cache / Region
z
Application
Region
Region
Region
Cache
Cache
• Region class は java.util.Map interface を実装
• データの保存方法 (Replicated/Partition)や場所に
依らず一貫した API を提供
• Region 内でキーは一意である必要がある
Region
java.util.Map
Region
3838
• クライアントが distributed system に接続する方法としてGemFire server に(直接)、
または “locator” 経由で接続する方法がある
• クライアントは独自にサーバーからのデータをローカルにコピー(キャッシュ)すること
が可能
• クライアントはサーバー側の変更に対し register 可能。その場合変更があった際にク
ライアントに通知されるようになる
Client Cache
Application
Application
Region
Region
Region
Cache
Client Cache
3939
• GemFire distributed system に接続、および Cache を生成するプロセス
• Locator
• Cacheserver (Cache 保持)
• Agent
• 最小構成の GemFire プロセスは組み込みモードで実行される単一のノード
メンバー構成
Application
Region
Region
Region
Cache
Application
Region
Region
Region
Cache
Application
Region
Region
Region
Cache
Application ApplicationApplication
4040
GemFire Topologies
Embedded
Peer-To-Peer
Client/Server
Multi-site/WAN Gateway
Topologies of GemFire
4141
Application
Region
Region
Region
Cache
Application
Region
Region
Region
Cache
Application
Region
Region
Region
Cache
Topologies – Embedded / Peer to Peer
Application
Region
Region
Region
Cache
4242
Topologies – Client-Server
ApplicationApplicationApplication
Application
Region
Region
Region
Cache
Application
Region
Region
Region
Cache
Application
Region
Region
Region
Cache
4343
Creating a Cache - XML
Application
Region
Cache
<?xml version="1.0"?>
<!DOCTYPE cache PUBLIC
"-//GemStone Systems, Inc.//GemFire Declarative
Caching 6.6//EN"
"http://www.gemstone.com/dtd/cache6_6.dtd">
<cache>
<region name="Customer” refid="REPLICATE" />
</cache>
cache.xml
Load XML via Java
Cache cache = new CacheFactory()
.set("cache-xml-file", "xml/cache.xml")
.create();
Region<Integer, Customer> customers = cache.getRegion("Customer");
4444
Creating a Cache - API
Application
Region
Cache
// Create the cache without using a cache xml file
Cache cache = new CacheFactory().create();
// Create a region dynamically using the APIs
Region<Integer, Customer> customers =
(Region<Integer, Customer>)cache.createRegionFactory()
.create("Customer”);
§ Classes in
com.gemstone.gemfire.cache
§ Call cache.close() when done
4545
In gemfire.properties:
Setting startup parameters
log-level=warning
statistic-sampling-enabled=true
statistic-sample-rate=100
statistic-archive-file=/Users/myMac/myApp/stats1007.gfs
locators=localhost[41111],….
mcast-port=0
cache-xml-file=myCache.xml
§ 起動時に読み込まれる構成ファイル
§ cache-xml を指定も可能
4646
Spring Data Gemfire
§ Spring namespace (gfe) を用いた Gemfire の構成
§ cache.xml との比較
• Import, property placeholder, SpEL etc.
§ Declarative Transaction Management
• gfe:transaction-manager -> region 操作が atomic に
§ Exception translation
§ GemFireTemplate
• Connection/Transaction 管理の自動化
• GemFire native API にアクセス可能
§ Entity / PDX Mapping
§ Repository サポート
4747
Spring Data Gemfire - Configuration
<gfe:cache /> // id=“gemfireCache”
<gfe:replicated-region id="simple" />
<gfe:partitioned-region id="complex" local-max-memory="20">
<gfe:cache-listener>
<ref bean="c-listener"/>
<bean class="org.springframework.data.gemfire.SimpleCacheListener"/>
</gfe:cache-listener>
<gfe:cache-loader ref="c-loader"/>
<gfe:cache-writer ref="c-writer"/>
</gfe:partitioned-region>
<bean id="c-listener" class="org.springframework.data.gemfire.SimpleCacheListener"/>
<bean id="c-loader" class="org.springframework.data.gemfire.SimpleCacheLoader"/>
<bean id="c-writer" class="org.springframework.data.gemfire.SimpleCacheWriter"/>
§ 標準の Spring 機能 (property replacement, environment) を利用可能
4848
Spring Data Gemfire – Entity Mapping
@Region("myRegion")
public class Person {
@Id BigInteger id; // Cache キー
@Indexed String firstname;
@Transient String middleName; // persist されない
@PersistenceConstructor // コンストラクタの明示指定
public Person(String firstname, String lastname) { … }
}
4949
Spring Data Gemfire - Repositories
interface PersonRepository extends CrudRepository<Person, BigInteger> {
// Finder for a single entity
Person findByEmailAddress(String emailAddress);
// Finder for multiple entities
List<Person> findByLastnameLike(String lastname);
// Finder with manually defined query
@Query("SELECT p FROM /Person p WHERE p.firstname = $1")
List<Person> findByFirstname(String firstname);
}
5050
Spring Data Gemfire – Repositories
<gf:repositories base-package="com.acme.repositories"/>
@Service
public class MySimpleService {
@Autowired PersonRepository personRepository;
@Autowired AccountRepository accountRepository;
@Transactional
public List<Person> doSomething(Integer personId) {
Person person = personRepository.findOne(personId);
List<Person> persons = accountRepository.findByPerson(person);
}
}
public interface PersonRepository extends CrudRepository<Person, BigInteger> {
// Finder for a single entity
Person findByEmailAddress(String emailAddress);
// Finder for multiple entities
List<Person> findByLastnameLike(String lastname);
// Finder with manually defined query (OQL)
@Query("SELECT p FROM /Person p WHERE p.firstname = $1")
List<Person> findByFirstname(String firstname);
}
5151
Thank you!
Q&A
@tsuyokb

Contenu connexe

Tendances

Pro aspnetmvc3framework chap19
Pro aspnetmvc3framework chap19Pro aspnetmvc3framework chap19
Pro aspnetmvc3framework chap19
Hideki Hashizume
 
Parse introduction
Parse introductionParse introduction
Parse introduction
Tamura Koya
 

Tendances (20)

NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.0.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.0.0対応)NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.0.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.0.0対応)
 
Active Directoryデータのプロパティ出力(Output Properties)
Active Directoryデータのプロパティ出力(Output Properties)Active Directoryデータのプロパティ出力(Output Properties)
Active Directoryデータのプロパティ出力(Output Properties)
 
Javaでmongo db
Javaでmongo dbJavaでmongo db
Javaでmongo db
 
Html5j data visualization_and_d3
Html5j data visualization_and_d3Html5j data visualization_and_d3
Html5j data visualization_and_d3
 
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.4.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.4.0対応)NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.4.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.4.0対応)
 
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 2.4.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 2.4.0対応)FIWARE Orion Context Broker コンテキスト情報管理 (Orion 2.4.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 2.4.0対応)
 
Active Directoryデータの "大きい整数"
Active Directoryデータの "大きい整数"Active Directoryデータの "大きい整数"
Active Directoryデータの "大きい整数"
 
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.0.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.0.0対応)NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.0.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.0.0対応)
 
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.6.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.6.0対応)FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.6.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.6.0対応)
 
Pro aspnetmvc3framework chap19
Pro aspnetmvc3framework chap19Pro aspnetmvc3framework chap19
Pro aspnetmvc3framework chap19
 
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.2.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.2.0対応)NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.2.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.2.0対応)
 
jQuery超入門編
jQuery超入門編jQuery超入門編
jQuery超入門編
 
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.1.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.1.0対応)NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.1.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.1.0対応)
 
Xslt
XsltXslt
Xslt
 
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.4.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.4.0対応)FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.4.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.4.0対応)
 
EWD 3トレーニングコース#20 GlobalストレージのJavaScript用抽象化-(a)DocumentNodeオブジェクト
EWD 3トレーニングコース#20 GlobalストレージのJavaScript用抽象化-(a)DocumentNodeオブジェクトEWD 3トレーニングコース#20 GlobalストレージのJavaScript用抽象化-(a)DocumentNodeオブジェクト
EWD 3トレーニングコース#20 GlobalストレージのJavaScript用抽象化-(a)DocumentNodeオブジェクト
 
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.5.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.5.0対応)FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.5.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.5.0対応)
 
AndroidでActiveRecordライクにDBを使う
AndroidでActiveRecordライクにDBを使うAndroidでActiveRecordライクにDBを使う
AndroidでActiveRecordライクにDBを使う
 
Parse introduction
Parse introductionParse introduction
Parse introduction
 
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.1.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.1.0対応)FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.1.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.1.0対応)
 

En vedette

En vedette (14)

Cloudera + MicrosoftでHadoopするのがイイらしい。 #CWT2016
Cloudera + MicrosoftでHadoopするのがイイらしい。 #CWT2016Cloudera + MicrosoftでHadoopするのがイイらしい。 #CWT2016
Cloudera + MicrosoftでHadoopするのがイイらしい。 #CWT2016
 
Cloudera Data Science WorkbenchとPySparkで 好きなPythonライブラリを 分散で使う #cadeda
Cloudera Data Science WorkbenchとPySparkで 好きなPythonライブラリを 分散で使う #cadedaCloudera Data Science WorkbenchとPySparkで 好きなPythonライブラリを 分散で使う #cadeda
Cloudera Data Science WorkbenchとPySparkで 好きなPythonライブラリを 分散で使う #cadeda
 
Spring Cloud in a Nutshell
Spring Cloud in a NutshellSpring Cloud in a Nutshell
Spring Cloud in a Nutshell
 
Cloudera in the Cloud #CWT2017
Cloudera in the Cloud #CWT2017Cloudera in the Cloud #CWT2017
Cloudera in the Cloud #CWT2017
 
クラウド時代の Spring Framework (aka Spring Framework in Cloud Era)
クラウド時代の Spring Framework (aka Spring Framework in Cloud Era)クラウド時代の Spring Framework (aka Spring Framework in Cloud Era)
クラウド時代の Spring Framework (aka Spring Framework in Cloud Era)
 
#cwt2016 Apache Kudu 構成とテーブル設計
#cwt2016 Apache Kudu 構成とテーブル設計#cwt2016 Apache Kudu 構成とテーブル設計
#cwt2016 Apache Kudu 構成とテーブル設計
 
Hue 4.0 / Hue Meetup Tokyo #huejp
Hue 4.0 / Hue Meetup Tokyo #huejpHue 4.0 / Hue Meetup Tokyo #huejp
Hue 4.0 / Hue Meetup Tokyo #huejp
 
Cloud Native Hadoop #cwt2016
Cloud Native Hadoop #cwt2016Cloud Native Hadoop #cwt2016
Cloud Native Hadoop #cwt2016
 
先行事例から学ぶ IoT / ビッグデータの始め方
先行事例から学ぶ IoT / ビッグデータの始め方先行事例から学ぶ IoT / ビッグデータの始め方
先行事例から学ぶ IoT / ビッグデータの始め方
 
Clouderaが提供するエンタープライズ向け運用、データ管理ツールの使い方 #CW2017
Clouderaが提供するエンタープライズ向け運用、データ管理ツールの使い方 #CW2017Clouderaが提供するエンタープライズ向け運用、データ管理ツールの使い方 #CW2017
Clouderaが提供するエンタープライズ向け運用、データ管理ツールの使い方 #CW2017
 
How to go into production your machine learning models? #CWT2017
How to go into production your machine learning models? #CWT2017How to go into production your machine learning models? #CWT2017
How to go into production your machine learning models? #CWT2017
 
Apache Kuduは何がそんなに「速い」DBなのか? #dbts2017
Apache Kuduは何がそんなに「速い」DBなのか? #dbts2017Apache Kuduは何がそんなに「速い」DBなのか? #dbts2017
Apache Kuduは何がそんなに「速い」DBなのか? #dbts2017
 
Apache Kudu - Updatable Analytical Storage #rakutentech
Apache Kudu - Updatable Analytical Storage #rakutentechApache Kudu - Updatable Analytical Storage #rakutentech
Apache Kudu - Updatable Analytical Storage #rakutentech
 
大規模データに対するデータサイエンスの進め方 #CWT2016
大規模データに対するデータサイエンスの進め方 #CWT2016大規模データに対するデータサイエンスの進め方 #CWT2016
大規模データに対するデータサイエンスの進め方 #CWT2016
 

Similaire à Spring Data in a Nutshell

Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理
土岐 孝平
 
.NET最先端技術によるハイパフォーマンスウェブアプリケーション
.NET最先端技術によるハイパフォーマンスウェブアプリケーション.NET最先端技術によるハイパフォーマンスウェブアプリケーション
.NET最先端技術によるハイパフォーマンスウェブアプリケーション
Yoshifumi Kawai
 
Alfresco勉強会20120829: やさしいShareダッシュレットの作り方
Alfresco勉強会20120829: やさしいShareダッシュレットの作り方Alfresco勉強会20120829: やさしいShareダッシュレットの作り方
Alfresco勉強会20120829: やさしいShareダッシュレットの作り方
linzhixing
 
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回
Naoyuki Yamada
 
RとSQLiteで気軽にデータベース作成
RとSQLiteで気軽にデータベース作成RとSQLiteで気軽にデータベース作成
RとSQLiteで気軽にデータベース作成
弘毅 露崎
 
Google App Engine for Java
Google App Engine for JavaGoogle App Engine for Java
Google App Engine for Java
Takuya Tsuchida
 
[DI07] あらゆるデータに価値がある! アンチ断捨離ストのための Azure Data Lake
[DI07] あらゆるデータに価値がある! アンチ断捨離ストのための Azure Data Lake[DI07] あらゆるデータに価値がある! アンチ断捨離ストのための Azure Data Lake
[DI07] あらゆるデータに価値がある! アンチ断捨離ストのための Azure Data Lake
de:code 2017
 

Similaire à Spring Data in a Nutshell (20)

ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-
ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-
ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-
 
20181031 springfest spring data geode
20181031 springfest spring data geode20181031 springfest spring data geode
20181031 springfest spring data geode
 
[東京] JapanSharePointGroup 勉強会 #2
[東京] JapanSharePointGroup 勉強会 #2[東京] JapanSharePointGroup 勉強会 #2
[東京] JapanSharePointGroup 勉強会 #2
 
Mongo db + xsd:xml(20130219)
Mongo db + xsd:xml(20130219)Mongo db + xsd:xml(20130219)
Mongo db + xsd:xml(20130219)
 
Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理Spring3.1概要 データアクセスとトランザクション処理
Spring3.1概要 データアクセスとトランザクション処理
 
.NET最先端技術によるハイパフォーマンスウェブアプリケーション
.NET最先端技術によるハイパフォーマンスウェブアプリケーション.NET最先端技術によるハイパフォーマンスウェブアプリケーション
.NET最先端技術によるハイパフォーマンスウェブアプリケーション
 
RestKitの紹介 - Webサービスのクライアント実装補助フレームワーク -
RestKitの紹介 - Webサービスのクライアント実装補助フレームワーク -RestKitの紹介 - Webサービスのクライアント実装補助フレームワーク -
RestKitの紹介 - Webサービスのクライアント実装補助フレームワーク -
 
Alfresco勉強会20120829: やさしいShareダッシュレットの作り方
Alfresco勉強会20120829: やさしいShareダッシュレットの作り方Alfresco勉強会20120829: やさしいShareダッシュレットの作り方
Alfresco勉強会20120829: やさしいShareダッシュレットの作り方
 
Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略
 
pi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピングpi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピング
 
MongoDB2.2の新機能
MongoDB2.2の新機能MongoDB2.2の新機能
MongoDB2.2の新機能
 
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回
 
第5回LinkedData勉強会@yayamamo
第5回LinkedData勉強会@yayamamo第5回LinkedData勉強会@yayamamo
第5回LinkedData勉強会@yayamamo
 
RとSQLiteで気軽にデータベース作成
RとSQLiteで気軽にデータベース作成RとSQLiteで気軽にデータベース作成
RとSQLiteで気軽にデータベース作成
 
PHP開発者のためのNoSQL入門
PHP開発者のためのNoSQL入門PHP開発者のためのNoSQL入門
PHP開発者のためのNoSQL入門
 
Teclab3
Teclab3Teclab3
Teclab3
 
Google App Engine for Java
Google App Engine for JavaGoogle App Engine for Java
Google App Engine for Java
 
[DI07] あらゆるデータに価値がある! アンチ断捨離ストのための Azure Data Lake
[DI07] あらゆるデータに価値がある! アンチ断捨離ストのための Azure Data Lake[DI07] あらゆるデータに価値がある! アンチ断捨離ストのための Azure Data Lake
[DI07] あらゆるデータに価値がある! アンチ断捨離ストのための Azure Data Lake
 
XPages 開発 Tips 百連発
XPages 開発 Tips 百連発XPages 開発 Tips 百連発
XPages 開発 Tips 百連発
 
Springでdao 20070413
Springでdao 20070413Springでdao 20070413
Springでdao 20070413
 

Plus de Tsuyoshi Miyake

Artifact Driven CI/CD
Artifact Driven CI/CDArtifact Driven CI/CD
Artifact Driven CI/CD
Tsuyoshi Miyake
 

Plus de Tsuyoshi Miyake (19)

猿でもわかる DevOps
猿でもわかる DevOps猿でもわかる DevOps
猿でもわかる DevOps
 
はじめての JFrog Platform V2
はじめての JFrog Platform V2はじめての JFrog Platform V2
はじめての JFrog Platform V2
 
はじめての JFrog Distribution
はじめての JFrog Distributionはじめての JFrog Distribution
はじめての JFrog Distribution
 
はじめての JFrog Pipelines
はじめての JFrog Pipelinesはじめての JFrog Pipelines
はじめての JFrog Pipelines
 
はじめての JFrog Xray
はじめての JFrog Xrayはじめての JFrog Xray
はじめての JFrog Xray
 
はじめての JFrog Artifactory
はじめての JFrog Artifactoryはじめての JFrog Artifactory
はじめての JFrog Artifactory
 
はじめての JFrog Platform
はじめての JFrog Platformはじめての JFrog Platform
はじめての JFrog Platform
 
猿でもわかる Helm
猿でもわかる Helm猿でもわかる Helm
猿でもわかる Helm
 
Artifact Driven CI/CD
Artifact Driven CI/CDArtifact Driven CI/CD
Artifact Driven CI/CD
 
猿でもわかるサーバーレス
猿でもわかるサーバーレス猿でもわかるサーバーレス
猿でもわかるサーバーレス
 
Java 開発者のための次世代 DevOps: BinOps
Java 開発者のための次世代 DevOps: BinOpsJava 開発者のための次世代 DevOps: BinOps
Java 開発者のための次世代 DevOps: BinOps
 
カエルと実践するコンテナ
カエルと実践するコンテナカエルと実践するコンテナ
カエルと実践するコンテナ
 
猿でもわかるコンテナ・オーケストレーション
猿でもわかるコンテナ・オーケストレーション猿でもわかるコンテナ・オーケストレーション
猿でもわかるコンテナ・オーケストレーション
 
猿でもわかるコンテナ
猿でもわかるコンテナ猿でもわかるコンテナ
猿でもわかるコンテナ
 
カエルと実践する CI/CD CD 編
カエルと実践する CI/CD CD 編カエルと実践する CI/CD CD 編
カエルと実践する CI/CD CD 編
 
カエルと実践する CI/CD CI 編
カエルと実践する CI/CD CI 編カエルと実践する CI/CD CI 編
カエルと実践する CI/CD CI 編
 
猿でもわかる CI/CD
猿でもわかる CI/CD猿でもわかる CI/CD
猿でもわかる CI/CD
 
カエルと実践するバイナリ・リポジトリマネージャー
カエルと実践するバイナリ・リポジトリマネージャーカエルと実践するバイナリ・リポジトリマネージャー
カエルと実践するバイナリ・リポジトリマネージャー
 
猿でもわかるバイナリ・リポジトリマネージャー
猿でもわかるバイナリ・リポジトリマネージャー猿でもわかるバイナリ・リポジトリマネージャー
猿でもわかるバイナリ・リポジトリマネージャー
 

Dernier

Dernier (12)

論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 

Spring Data in a Nutshell

  • 1. © 2012 SpringSource, A division of VMware. All rights reserved Spring Data in a Nutshell Tsuyoshi Miyake (@tsuyokb)
  • 2. 22 背景と動機 § RDBMS はいまだ重要かつ支配的 • ただ “one size fits all” ではなくなってきている § Spring はデータアクセスに常に優れたサポートを行ってきた § Spring Data project のゴールは Spring のデータサポートを “リフレッシュ” すること • Traditional: JDBC, JPA • New: Grid, Document, Graph, K-V (aka NoSQL or NewSQL) § なじみの一貫性のある Spring ベースのプログラミングモデルを提供 • 個々の技術的特徴はいかしながら § データアクセス層から boiler-plate code をなくす • 異なるテクノロジーをまたがって利用できる共通のインタフェース
  • 3. 33 Spring Data は “umbrella project” § http://www.springframework.org/spring-data § JPA - Repositories § JDBC Extensions § MongoDB – Document Database § Neo4j – Graphs Database § Redis – Key Value Database § Gemfire – Distributed Data Grid § Commons – shared abstractions • Repositories • Object Mapping § QueryDSL – integration with type-safe query API
  • 4. 44 Spring Data Repositories (1/3) public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> { T save(T entity); Iterable<T> save(Iterable<? extends T> entities); T findOne(ID id); boolean exists(ID id); Iterable<T> findAll(); long count(); void delete(ID id); void delete(T entity); void delete(Iterable<? extends T> entities); void deleteAll(); } public interface Repository<T, ID extends Serializable> { // マーカーインタフェース ex.) Repository<Customer, Long> }
  • 5. 55 Spring Data Repositories (2/3) public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> { Iterable<T> findAll(Sort sort); Page<T> findAll(Pageable pageable); } § “naming conventions” によるクエリメソッドの定義 public interface PersonRepository extends CrudRepository<Person,BigInteger> { // Finder for a single entity Person findByEmailAddress(String emailAddress); // Finder for a multiple entities List<Person> findByLastnameLike(String lastName); // Finder with pagination Page<Person> findByFirstnameLike(String firstName, Pageable page); }
  • 6. 66 Spring Data Repositories (3/3) @NoRepositoryBean public interface BaseRepository<T, ID extends Serializable> extends Repository<T, ID> { Iterable<T> findAll(Pageable sort); <S extends T> S save(S entity); <S extends T> S save(Iterable<S> entities); } § Custom Repository インタフェースの定義 • CRUD は便利だが Read のみを提供したい、または Delete は提供したくない etc. § 定義方法 1. Repository を継承(or @RepositoryDefinition を付与)したインタフェースを定義 2. 公開したいメソッドのみをそのインタフェースに定義(ただし、メソッドシグネチャー は Spring Data Repository と同一にする) 3. 出来上がったインタフェースを entity のベースに
  • 7. 77 Spring Data JPA – Entity Mapping § インタフェースを定義するだけ: • PersonRepository の実装は Spring (Data) が提供 <jpa:repositories base-package="com.acme.repository" /> @Entity public class Person { @Id @GeneratedValue(strategy=GenerationType.AUTO) private BigInteger id; private String firstname, lastname; @Column(name="email") private String emailAddress; @OneToMany private Set<Person> colleagues; } @EnableJpaRepositoriesJavaConfig XML
  • 8. 88 Spring Data JPA § transactional service layer (通常通り) @Service public class DefaultUserManagementService implements UserManagementService { public PersonRepository personRepository; public ShiftRepository shiftRepository; @Autowired public DefaultUserManagementService(PersonRepository personRepository, ShiftRepository shiftRepository) { this.personRepository = personRepository; this.shiftRepository = shiftRepository; } @Transactional public void assignToNightShift(String emailAddress) { Person person = personRepository.findByEmailAddress(emailAddress); // continue processing } }
  • 9. 99 Spring Data JPA § クエリメソッド(naming conventions ベース) • Query annotation でオーバーライド可能 • JPA named query (@NamedQuery) の参照も可. public interface PersonRepository extends CrudRepository<Person,BigInteger> { // previous methods omitted… @Query("select p from Person p where p.emailAddress = ?1") Person findByEmailAddress(String emailAddress); @Query("select p from Person p where p.firstname = :firstname or p.lastname = :lastname") Person findByLastnameOrFirstname(@Param("lastname") String lastname, @Param("firstname") String firstname); }
  • 10. 1010 QueryDSL § ”タイプセーフ”な SQL-like なクエリを生成するためのフレームワーク • http://www.querydsl.com/ • Open Source, Apache 2.0 § IDE のコード補完フレンドリー § 不適切なクエリが構造上不可能(存在しないカラムへのアクセス etc.) § ドメインのプロパティと型への安全なアクセス(非文字列) § Java annotation processor (QueryDSL annotation processor) による Q<DomainClass> の自動生成 § Criteria API (JPA 2) より簡潔かつ通常の Java Collection にも使える private static final QProduct $ = QProduct.product; macBook = new Product("MacBook Pro", "Apple laptop"); iPad = new Product("iPad", "Apple tablet"); // … products = Arrays.asList(macBook, iPad, iPod, turntable); List<Product> result = from($, products).where($.description.contains("Apple")).list($);
  • 11. 1111 QueryDSL - Repositories § Repository に QueryDSL interface を拡張(追加) • QueryDSL の Predicate を引数にもつメソッド • JPA, MongoDB public interface QueryDSLPredicateExecutor<T> { long count(com.mysema.query.types.Predicate predicate); T findOne(Predicate predicate); List<T> findAll(Predicate predicate); List<T> findAll(Predicate predicate, OrderSpecifier<?>... orders); Page<T> findAll(Predicate predicate, Pageable pageable); } public interface CustomerRepository extends Repository<Customer, Long>, QueryDslPredicateExecutor<Customer> { // Your query methods here } QCustomer customer = QCustomer.customer; LocalDate today = new LocalDate(); BooleanExpression customerHasBirthday = customer.birthday.eq(today); BooleanExpression isLongTermCustomer = customer.createdAt.lt(today.minusYears(2)); customerRepository.findAll(customerHasBirthday.and(isLongTermCustomer));
  • 12. 1212 MongoDB § ドキュメント・データストア § ドキュメント == 構造化されたデータ (e.g. XML, JSON) § JSON スタイルのドキュメント (BSON) • 基本的に Map、値にプリミティブ/コレクション/ネストのドキュメント型 § ドキュメントはコレクションというコンテナ(~テーブル)に格納される § Index サポート – 任意の attribute に § リッチな query language … 続きは http://www.mongodb.org/ で { firstname : "Dave", lastname : "Matthews", addresses : [ { city : "New York", street : "Broadway" } ] }
  • 13. 1313 MongoDB Java API を使う (1/2) public void mongoBasic() throws Exception { Mongo mongo = new Mongo(); DB db = mongo.getDB("database"); DBCollection customers = db.getCollection("customers"); DBObject address = new BasicDBObject("city", ”Kobe"); address.put("street", "Broadway"); DBObject addresses = new BasicDBList(); ((BasicDBList) addresses).add(address); DBObject customer = new BasicDBObject("firstname", "Tsuyoshi"); customer.put("lastname", "Miyake"); customer.put("addresses", addresses); customers.insert(customer); System.out.println(customers.findOne()); } }
  • 14. 1414 MongoDB Java API を使う (2/2) § Mongo クラスを使用 § サーバに関する詳細は隠蔽される § Insert / Update • (全ての)アプリケーション POJO -> DBObject にマップする必要あり • mongo.getDatabase(…).getCollection(…).insert(…) § クエリ • クエリを組み立て、 • mongo.getDatabase(…).getCollection(…).find(…) • カーソルを使って結果を iterate • DBObject -> アプリケーション POJO マップ(手動) è JDBC よりは抽象化されていそうだけど(繰り返しが多い) …
  • 15. 1515 Spring Data MongoDB § MongoTemplate • MongoDB 特有のオペレーションへのアクセス: geo, map/reduce etc. • Fluent Query, Criteria, Update APIs § Object-Document マッピング § Repository サポート § Spring XML namespace (e.g. <mongo:XXX>) § QueryDSL サポート § JMX / Logging
  • 16. 1616 Spring Data MongoDB – Entity Mapping (1/3) @Document public class Customer { @Id private BigInteger id; private String firstname, lastname; @Field("email") @Indexed(unique = true) private EmailAddress emailAddress; private Set<Address> addresses = new HashSet<Address>(); public Customer(String firstname, String lastname) { Assert.hasText(firstname); Assert.hasText(lastname); this.firstname = firstname; this.lastname = lastname; } … }
  • 17. 1717 Spring Data MongoDB – Entity Mapping (2/3) public final class EmailAddress { private static final String EMAIL_REGEX = “…"; private static final Pattern PATTERN = Pattern.compile(EMAIL_REGEX); @Field("email") private final String value; public EmailAddress(String emailAddress) { Assert.isTrue(isValid(emailAddress), "Invalid email address!"); this.value = emailAddress; } … } public class Address { private final String street, city, country; public Address(String street, String city, String country) { Assert.hasText(street, "Street must not be null or empty!"); … this.street = street; this.city = city; this.country = country; } … }
  • 18. 1818 Spring Data MongoDB – Entity Mapping (3/3) public void mongoSpring() throws Exception { MongoMappingContext context = new MongoMappingContext(); MongoDbFactory dbFactory = new SimpleMongoDbFactory(new Mongo(), "database"); MappingMongoConverter converter = new MappingMongoConverter(dbFactory, context); Customer customer = new Customer("Tsuyoshi", "Miyake"); customer.setEmailAddress(new EmailAddress("tmiyake@vmware.com")); customer.add(new Address("Minato-ku", "Tokyo", "Japan")); DBObject sink = new BasicDBObject(); converter.write(customer, sink); System.out.println(sink.toString()); } { "_class" : "com.oreilly.springdata.mongodb.core.Customer” , "_id" : null , "firstname" : "Tsuyoshi" , "lastname" : "Miyake" , "email" : { "email" : "tmiyake@vmware.com"} , "addresses" : [ { "street" : "Minato-ku" , "city" : "Tokyo" , "country" : "Japan"}]}
  • 19. 1919 Spring Data Mongo – MongoTemplate 使用法 @Autowired MongoTemplate template; // in AbstractMongoConfiguration (JavaConfig) @Test public void mongoTemplate() throws Exception { Customer customer = new Customer("Kirari", "Miyake"); customer.setEmailAddress(new EmailAddress("kirari.miyake@gmail.com")); template.save(customer); Query query = new Query( new Criteria("emailAddress").is("kirari.miyake@gmail.com")); assertThat(template.findOne(query, Customer.class), is(customer)); } @Configuration @ComponentScan @EnableMongoRepositories class ApplicationConfig extends AbstractMongoConfiguration { @Override protected String getDatabaseName() { return ”database”; } @Override public Mongo mongo() throws Exception {…} … }
  • 20. 2020 Spring Data Mongo - Repositories § Spring Data Commons の Repository 同様 • インタフェースの定義(のみ) & naming convention
  • 21. 2121 Spring Data Mongo – Repository 使用法 or @EnableMongoRepositories in JavaConfig
  • 22. 2222 Neo4j § グラフデータベース § DB はグラフのノード (nodes) と関連 (relationships) から成る • Nodes と relationships はプロパティーをもつ § Cypher Query Language § Indexes on node/relationship プロパティー § Java で記述されている、アプリケーションへ組み込み可能 • Also a REST API (Neo4j Server) § Transactional (ACID) … 続きは http://neo4j.org/ で
  • 24. 2424 Spring Data Neo4j § Neo4jTemplate • Neo4j 特有のオペレーションへのアクセス: get/create Node and Relationship, query, traverse, fluent query Result handling • トランザクション管理 • Exception translation to Spring’s DAO exception hierarchy • Also works via REST with Neo4jServer § アノテーションベースの Entity 定義(@NodeEntity/@RelationshipEntity..) § Repository サポート § Cypher query language § Spring XML namespace (<neo4j:XXX>) § Neo4j Server 統合 <bean id="graphDatabaseService" class="org.springframework.data.neo4j.rest.SpringRestGraphDatabase” />
  • 25. 2525 Classic Neo4j – Entity class public class Person { private final Node underlyingNode; public Person(final Node node) { underlyingNode = node; } public Node getUnderlyingNode() { return underlyingNode; } public final String getName() { return (String) underlyingNode.getProperty(“name”); } public void setName(final String name) { underlyingNode.setProperty(“name”, name); } }
  • 26. 2626 Spring Data Neo4j – Entity class @NodeEntity public class Actor { @Indexed // Neo4jTemplate.getOrCreateNode() etc. で利用可能 private String id; @Indexed(indexType=IndexType.FULLTEXT , indexName=“people") private String name; public Person(String id, String name) { this.id = id; this.name = name; } public String getId() { return id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
  • 27. 2727 Spring Data Neo4j – Entity class @NodeEntity public class Movie { @Indexed private String id; @Indexed(indexType=IndexType.FULLTEXT , indexName=“search") private String title; // Collection of other nodes @RelatedTo(type = "ACTS_IN", direction= INCOMING) private Set<Actor> actors; // Collection of relationships (actor -> (rating) -> movie) @RelatedToVia(type = “RATED", direction= INCOMING) private Set<Rating> rating; public Movie(String id, String title) { this.id = id; this.title = title; } // Getters and Setters omitted }
  • 28. 2828 Spring Data Neo4j - Repositories § Spring Data Commons の Repository 同様 • インタフェースの定義(のみ) & naming convention § Support for • CRUD • IndexRepository (findAllByPropertyValue, findAllByQuery etc.) • TraversalRepository (findAllByTraversal) public interface MovieRepository extends GraphRepository<Movie>, NamedIndexRepository<Movie>, RelationshipOperationsRepository<Movie> { Movie findById(String id); Page<Movie> findByTitleLike(String title, Pageable page); @Query("start user=node({0}) " + " match user-[r:RATED]->movie<-[r2:RATED]-other-[r3:RATED]->otherMovie " + " where r.stars >= 3 and r2.stars >= 3 and r3.stars >= 3 " + " return otherMovie, avg(r3.stars) " + " order by avg(r3.stars) desc, count(*) desc" + " limit 10") List<MovieRecommendation> getRecommendations(User user); } <neo4j:repositories base-package="org.neo4j.cineasts.repository"/>
  • 29. 2929 Spring Data Neo4j – Neo4jTemplate public void setUp() throws Exception { dave = template.save(new Customer("Dave", "Matthews", "dave@dmband.com")); template.save(new Customer("Carter","Beauford","carter@dmband.com")); template.save(new Customer("Boyd","Tinsley","boyd@dmband.com")); final Country usa = template.save(new Country("US", "United States")); template.save(new Address("27 Broadway","New York",usa)); iPad = template.save( new Product("iPad", "Apple tablet device") .withPrice(BigDecimal.valueOf(499D))); mbp = template.save( new Product("MacBook Pro", "Apple notebook") .withPrice(BigDecimal.valueOf(1299D))); final Order order = new Order(dave); order.add(iPad,2); order.add(mbp,1); template.save(order); }
  • 30. 3030 Redis § Advanced key-value store • 軽量 & 高パフォーマンス (in-memory) • Values: binary strings, Lists, Sets, Ordered Sets, Hash maps, .. • データタイプごとの操作: e.g. list への追加 ([RL]PUSH), set への追加 (SADD), retrieving a slice of a list (LRANGE key start end), … • 各操作がアトミック (e.g. INCR) § Very fast: ~100K operations/second on entry-level hardware § 永続化対応 • Periodic snapshots (point-in-time) • Write コマンドのログファイルへの書き出し (append-based) § PUB/SUB § トランザクション対応 (MULTI <-> EXEC) § 多言語対応, all separate open source projects … 続きは http://redis.io/ で K1 K2 K3 V1 V2 V2
  • 31. 3131 Spring Data Redis § Redis ドライバに依存しない統一された API を提供 § RedisTemplate • Redis の機能実装。各データタイプごとに専用のインタフェース • Value/Hash/Set/Zset/ListOperations • 名前は分かりやすいように変換: SETNX -> putIfAbsent() • 自動で serialization と型変換を実施 • Fluent query API § 非同期 Publish-Subscribe サポート with message listener containers § JDK Atomic counters (AtomicLong etc.) backed by Redis § Spring 3.1 Cache abstraction provider
  • 32. 3232 Spring Data Redis – RedisTemplate – 型変換 <bean id="conFactory“ class="o.s.d.r.connection.jedis.JedisConnectionFactory"/> <bean id=“template“ class="o.s.d.redis.core.StringRedisTemplate" p:connection-factory-ref="conFactory"/> @Bean public RedisTemplate<String, Long> longTemplate() { RedisTemplate<String, Long> tmpl = new RedisTemplate<String, Long>(); tmpl.setConnectionFactory( redisConnectionFactory() ); tmpl.setValueSerializer(LongSerializer.INSTANCE); return tmpl; } public static enum LongSerializer implements RedisSerializer<Long> { INSTANCE; @Override public byte[] serialize( Long aLong ) throws SerializationException { if ( null != aLong ) { return aLong.toString().getBytes(); } else { return new byte[0]; } } @Override public Long deserialize( byte[] bytes ) throws SerializationException { if ( bytes.length > 0 ) { return Long.parseLong( new String( bytes ) ); } else { return null; } } }
  • 33. 3333 Spring Data Redis – RedisTemplate – アトミック操作 @Autowired RedisConnectionFactory connectionFactory; @Test public void testAtomicCounters() { RedisAtomicLong counter = new RedisAtomicLong("spring-data-book:counter- test:hits", connectionFactory, 0); Long l = counter.incrementAndGet(); assertThat(l, is(greaterThan(0L))); }
  • 34. 3434 Spring Data Redis – RedisTemplate – Pub/Sub @Configuration public class PubSubConfig extends ApplicationConfig { public static final String DUMP_CHANNEL = ”pubsub-test:dump"; @Bean RedisMessageListenerContainer container() { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(redisConnectionFactory()); container.addMessageListener(dumpToConsoleListener(), new ChannelTopic(DUMP_CHANNEL)); return container; } @Bean MessageListener dumpToConsoleListener() { return new MessageListener() { @Override public void onMessage(Message message, byte[] pattern) { System.out.println("FROM MESSAGE: " + new String(message.getBody())); } }; } } @Test public void testPubSubWithoutConversion() { RedisConnection redis = connectionFactory.getConnection(); try { redis.publish( PubSubConfig.DUMP_CHANNEL.getBytes(), "Hello World!".getBytes() ); } finally { redis.close(); } }
  • 35. 3535 • 分散/メモリーベースのデータ管理プラットフォ ーム • データトランザクションの多いアプリケーション に対し、可用性、高パフォーマンス、スケーラビ リティを提供 • データの一貫性を場合に応じて調節可能(分散 ロックのレベル) • イベントドリブンなアーキテクチャ … 続きは http://www.vmware.com/support/pubs/vfabri c-gemfire.html で GemFire – The Enterprise Data Fabric Java Client C# Client C++ Client
  • 36. 3636 GemFire High Level アーキテクチャ Java Client C# Client C++ Client クライアントは Cache を組 み込み可能 (with disk overflow) 物理的なサーバー群がひとつの 巨大な論理システムとしてみえ る (DistributedSystem) オブジェクトの変更がサブス クライバに伝達される 同期 R/W、非同期 Write データのパーティショニン グ・レプリケーションはクライ アントからは透過的に扱わ れる。 また、ストレージにメモリデ ータをバックアップ可能 動的にノードを追加可能
  • 37. 3737 • Cache がインメモリのストレージ、およびデータ管 理を提供 (RDBMS でいうところの Database) • XML (cache.xml) and/or API calls の組合せで Cache を構成 • 複数の Regions から構成される Cache / Region z Application Region Region Region Cache Cache • Region class は java.util.Map interface を実装 • データの保存方法 (Replicated/Partition)や場所に 依らず一貫した API を提供 • Region 内でキーは一意である必要がある Region java.util.Map Region
  • 38. 3838 • クライアントが distributed system に接続する方法としてGemFire server に(直接)、 または “locator” 経由で接続する方法がある • クライアントは独自にサーバーからのデータをローカルにコピー(キャッシュ)すること が可能 • クライアントはサーバー側の変更に対し register 可能。その場合変更があった際にク ライアントに通知されるようになる Client Cache Application Application Region Region Region Cache Client Cache
  • 39. 3939 • GemFire distributed system に接続、および Cache を生成するプロセス • Locator • Cacheserver (Cache 保持) • Agent • 最小構成の GemFire プロセスは組み込みモードで実行される単一のノード メンバー構成 Application Region Region Region Cache Application Region Region Region Cache Application Region Region Region Cache Application ApplicationApplication
  • 43. 4343 Creating a Cache - XML Application Region Cache <?xml version="1.0"?> <!DOCTYPE cache PUBLIC "-//GemStone Systems, Inc.//GemFire Declarative Caching 6.6//EN" "http://www.gemstone.com/dtd/cache6_6.dtd"> <cache> <region name="Customer” refid="REPLICATE" /> </cache> cache.xml Load XML via Java Cache cache = new CacheFactory() .set("cache-xml-file", "xml/cache.xml") .create(); Region<Integer, Customer> customers = cache.getRegion("Customer");
  • 44. 4444 Creating a Cache - API Application Region Cache // Create the cache without using a cache xml file Cache cache = new CacheFactory().create(); // Create a region dynamically using the APIs Region<Integer, Customer> customers = (Region<Integer, Customer>)cache.createRegionFactory() .create("Customer”); § Classes in com.gemstone.gemfire.cache § Call cache.close() when done
  • 45. 4545 In gemfire.properties: Setting startup parameters log-level=warning statistic-sampling-enabled=true statistic-sample-rate=100 statistic-archive-file=/Users/myMac/myApp/stats1007.gfs locators=localhost[41111],…. mcast-port=0 cache-xml-file=myCache.xml § 起動時に読み込まれる構成ファイル § cache-xml を指定も可能
  • 46. 4646 Spring Data Gemfire § Spring namespace (gfe) を用いた Gemfire の構成 § cache.xml との比較 • Import, property placeholder, SpEL etc. § Declarative Transaction Management • gfe:transaction-manager -> region 操作が atomic に § Exception translation § GemFireTemplate • Connection/Transaction 管理の自動化 • GemFire native API にアクセス可能 § Entity / PDX Mapping § Repository サポート
  • 47. 4747 Spring Data Gemfire - Configuration <gfe:cache /> // id=“gemfireCache” <gfe:replicated-region id="simple" /> <gfe:partitioned-region id="complex" local-max-memory="20"> <gfe:cache-listener> <ref bean="c-listener"/> <bean class="org.springframework.data.gemfire.SimpleCacheListener"/> </gfe:cache-listener> <gfe:cache-loader ref="c-loader"/> <gfe:cache-writer ref="c-writer"/> </gfe:partitioned-region> <bean id="c-listener" class="org.springframework.data.gemfire.SimpleCacheListener"/> <bean id="c-loader" class="org.springframework.data.gemfire.SimpleCacheLoader"/> <bean id="c-writer" class="org.springframework.data.gemfire.SimpleCacheWriter"/> § 標準の Spring 機能 (property replacement, environment) を利用可能
  • 48. 4848 Spring Data Gemfire – Entity Mapping @Region("myRegion") public class Person { @Id BigInteger id; // Cache キー @Indexed String firstname; @Transient String middleName; // persist されない @PersistenceConstructor // コンストラクタの明示指定 public Person(String firstname, String lastname) { … } }
  • 49. 4949 Spring Data Gemfire - Repositories interface PersonRepository extends CrudRepository<Person, BigInteger> { // Finder for a single entity Person findByEmailAddress(String emailAddress); // Finder for multiple entities List<Person> findByLastnameLike(String lastname); // Finder with manually defined query @Query("SELECT p FROM /Person p WHERE p.firstname = $1") List<Person> findByFirstname(String firstname); }
  • 50. 5050 Spring Data Gemfire – Repositories <gf:repositories base-package="com.acme.repositories"/> @Service public class MySimpleService { @Autowired PersonRepository personRepository; @Autowired AccountRepository accountRepository; @Transactional public List<Person> doSomething(Integer personId) { Person person = personRepository.findOne(personId); List<Person> persons = accountRepository.findByPerson(person); } } public interface PersonRepository extends CrudRepository<Person, BigInteger> { // Finder for a single entity Person findByEmailAddress(String emailAddress); // Finder for multiple entities List<Person> findByLastnameLike(String lastname); // Finder with manually defined query (OQL) @Query("SELECT p FROM /Person p WHERE p.firstname = $1") List<Person> findByFirstname(String firstname); }