• Like
Spring data in_a_nutshell
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

Spring data in_a_nutshell

  • 2,257 views
Published

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
2,257
On SlideShare
0
From Embeds
0
Number of Embeds
5

Actions

Shares
Downloads
17
Comments
0
Likes
2

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Spring Data in a NutshellTsuyoshi Miyake (@tsuyocky) © 2012 SpringSource, A division of VMware. All rights reserved
  • 2. 背景と動機§  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 をなくす •  異なるテクノロジーをまたがって利用できる共通のインタフェース 2
  • 3. 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 3
  • 4. Spring Data Repositories (1/3)public  interface  Repository<T,  ID  extends  Serializable>  {      //  マーカーインタフェース  ex.)  Repository<Customer,  Long>  }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();  } 4
  • 5. 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);      } 5
  • 6. Spring Data Repositories (3/3)§  Custom Repository インタフェースの定義 •  CRUD は便利だが Read のみを提供したい、または Delete は提供したくない etc.§  定義方法 1.  Repository を継承(or @RepositoryDefinition を付与)したインタフェースを定義 2.  公開したいメソッドのみをそのインタフェースに定義(ただし、メソッドシグネチャー は Spring Data Repository と同一にする) 3.  出来上がったインタフェースを entity のベースに @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);   }   6
  • 7. Spring Data JPA – Entity Mapping@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;    }§  インタフェースを定義するだけ: •  PersonRepository の実装は Spring (Data) が提供 XML <jpa:repositories  base-­‐package="com.acme.repository"  />  JavaConfig @EnableJpaRepositories   7
  • 8. 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        }  }   8
  • 9. 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);      } 9
  • 10. 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($);   10
  • 11. QueryDSL - Repositories§  Repository に QueryDSL interface を拡張(追加) •  QueryDSL の Predicate を引数にもつメソッド •  JPA, MongoDBpublic  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)); 11
  • 12. 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" } ] } 12
  • 13. 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());    }  }   13
  • 14. MongoDB Java API を使う (2/2)§  Mongo クラスを使用§  サーバに関する詳細は隠蔽される§  Insert / Update •  (全ての)アプリケーション POJO -> DBObject にマップする必要あり •  mongo.getDatabase(…).getCollection(…).insert(…)§  クエリ •  クエリを組み立て、 •  mongo.getDatabase(…).getCollection(…).find(…) •  カーソルを使って結果を iterate •  DBObject -> アプリケーション POJO マップ(手動) è JDBC よりは抽象化されていそうだけど(繰り返しが多い) … 14
  • 15. 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 15
  • 16. 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;    }  …  }   16
  • 17. 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;    }   …  }   17
  • 18. 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"}]} 18
  • 19. 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  {…}  …  }   19
  • 20. Spring Data Mongo - Repositories§  Spring Data Commons の Repository 同様 •  インタフェースの定義(のみ) & naming convention 20
  • 21. Spring Data Mongo – Repository 使用法 or @EnableMongoRepositories  in  JavaConfig 21
  • 22. 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/ で 22
  • 23. Neo4j データモデル 23
  • 24. 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” /> 24
  • 25. Classic Neo4j – Entity classpublic  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);      }    }   25
  • 26. 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;  }    }   26
  • 27. 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  }   27
  • 28. 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"/>   28
  • 29. Spring Data Neo4j – Neo4jTemplatepublic  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);  } 29
  • 30. 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 K1 V1 K2 V2 … 続きは http://redis.io/ で K3 V2 30
  • 31. 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 31
  • 32. 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;  }          }      }   32
  • 33. 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)));      } 33
  • 34. 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();  }      }   34
  • 35. GemFire – The Enterprise Data Fabric •  分散/メモリーベースのデータ管理プラット フォーム Java C# C++ Client Client Client •  データトランザクションの多いアプリケーショ ンに対し、可用性、高パフォーマンス、スケー ラビリティを提供 •  データの一貫性を場合に応じて調節可能(分 散ロックのレベル) •  イベントドリブンなアーキテクチャ … 続きは http://www.vmware.com/support/pubs/ vfabric-gemfire.html で 35
  • 36. GemFire High Level アーキテクチャ Java C# C++ Client Client Client クライアントは Cache を組 み込み可能 (with disk overflow) 物理的なサーバー群がひとつの 巨大な論理システムとしてみえ る (DistributedSystem) 動的にノードを追加可能 オブジェクトの変更がサブス クライバに伝達される データのパーティショニン グ・レプリケーションはクライ アントからは透過的に扱わ れる。 また、ストレージにメモリデ ータをバックアップ可能 同期 R/W、非同期 Write 36
  • 37. Cache / RegionCache Application•  Cache がインメモリのストレージ、およびデータ 管理を提供 (RDBMS でいうところの Database)•  XML (cache.xml) and/or API calls の組合せで Cache を構成 z Region•  複数の Regions から構成される RegionRegion Region•  Region class は java.util.Map interface を実装 Cache•  データの保存方法 (Replicated/Partition)や場所 に依らず一貫した API を提供 Region•  Region 内でキーは一意である必要がある java.util.Map 37
  • 38. Client Cache •  クライアントが distributed system に接続する方法としてGemFire server に(直接) 、または “locator” 経由で接続する方法がある •  クライアントは独自にサーバーからのデータをローカルにコピー(キャッシュ)するこ とが可能 •  クライアントはサーバー側の変更に対し register 可能。その場合変更があった際に クライアントに通知されるようになる Application Application Region Region Client Cache Region Cache 38
  • 39. メンバー構成•  GemFire distributed system に接続、および Cache を生成するプロセス •  Locator •  Cacheserver (Cache 保持) •  Agent•  最小構成の GemFire プロセスは組み込みモードで実行される単一のノード Application Application Application Application Application Application Region Region Region Region Region Region Region Region Region Cache Cache Cache 39
  • 40. GemFire Topologies Embedded Peer-To-Peer Client/Server Multi-site/WAN Gateway Topologies of GemFire 40
  • 41. Topologies – Embedded / Peer to Peer Application Region Region Region Cache Application Application Application Region Region Region Region Region Region Region Region Region Cache Cache Cache 41
  • 42. Topologies – Client-Server Application Application Application Application Application Application Region Region Region Region Region Region Region Region Region Cache Cache Cache 42
  • 43. Creating a Cache - XML Application cache.xml <?xml version="1.0"?> <!DOCTYPE cache PUBLIC "-//GemStone Systems, Inc.//GemFire Declarative Caching 6.6//EN" "http://www.gemstone.com/dtd/cache6_6.dtd"> Region <cache> <region name="Customer” refid="REPLICATE" /> Cache </cache> Load XML via Java Cache cache = new CacheFactory() .set("cache-xml-file", "xml/cache.xml") .create(); Region<Integer, Customer> customers = cache.getRegion("Customer"); 43
  • 44. Creating a Cache - API Application §  Classes in com.gemstone.gemfire.cache §  Call cache.close() when done 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”); 44
  • 45. Setting startup parameters In gemfire.properties: 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 を指定も可能 45
  • 46. 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 サポート 46
  • 47. Spring Data Gemfire - Configuration§  標準の Spring 機能 (property replacement, environment) を利用可能<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"/>   47
  • 48. 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) { … }} 48
  • 49. Spring Data Gemfire - Repositoriesinterface 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);} 49
  • 50. Spring Data Gemfire – Repositories<gf:repositories  base-­‐package="com.acme.repositories"/>  @Servicepublic 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);} 50
  • 51. Thank you! Q&A @tsuyocky 51