Spring data

1,017 views

Published on

spring data repository

Published in: Technology
1 Comment
2 Likes
Statistics
Notes
No Downloads
Views
Total views
1,017
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
33
Comments
1
Likes
2
Embeds 0
No embeds

No notes for slide

Spring data

  1. 1. M.C. Kang
  2. 2.  Overview  Spring Data is a high level SpringSource project whose purpose is to unify and ease the access to different kinds of persistence stores, both relational database systems and NoSQL data stores. Source http://www.infoq.com/articles/spring-data-introSpring Data projects support the followings aspects:TemplatingObject/Datastore mappingRepository support
  3. 3.  Overview - Templates The main purpose of a Spring Data template (and all other Spring templates) is resource allocation and exception translation. A template offers store specific operations like saving, updating and deleting a single record or for executing queries or map/reduce jobs. But all these methods work only for the corresponding underlying datastore.MongoDb Template Configuration Example<!-- Connection to MongoDB server --><mongo:db-factory host="localhost" port="27017" dbname="test" /><!-- MongoDB Template --><bean id="mongoTemplate“class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/></bean>
  4. 4.  Overview - Object/Datastore Mapping With Spring Data, this support is extended to NoSQL datastores with object-like data structures. But these data structures can be quite different from each other, so it would be difficult to make up a common API for object/datastore mapping. Each type of datastore comes with its own set of annotations to provide the needed meta information for the mapping. JPA MongoDB Neo4j@Entity @Document( collection="usr") @NodeEntity@Table(name="TUSR") public class User {    public class User {   public class User {    @Id   private String id;    @GraphId   Long id;   @Id    private String id; @Field("fn")   private String name;     private String name;    @Column(name="fn")   private String name;    private Date lastLogin; private Date lastLogin; private Date lastLogin;  ... ... ... } }}
  5. 5.  Overview - Repository Supportgeneric support for CRUD and paging , sorting by providing special parameters to the findermethods for all persistence storesThe main advantages of repository support are: The developer writes a lot less boilerplate code Queries can by defined alongside the finder method and its documentation As a bonus, the JPQL queries are compiled as soon as the Spring context is assembled, not the first time you use the query, which makes it easier to detect syntax errors
  6. 6.  Data Model  Domain Model Customer Address <<MappedSuperClass>> AbstractEntityCREATE TABLE customer ( id BIGINT IDENTITY PRIMARY KEY, firstname VARCHAR(255), lastname VARCHAR(255), email_address VARCHAR(255)); <<Entity>>CREATE UNIQUE INDEX ix_customer_email CustomerON CUSTOMER (email_address ASC);CREATE TABLE address ( id BIGINT IDENTITY PRIMARY KEY, customer_id BIGINT CONSTRAINTaddress_customer_ref REFERENCEScustomer (id), street VARCHAR(255), city VARCHAR(255), <<Entity>> <<Embeddable>> country VARCHAR(255)); Address EmailAddress Step1. “Define Domain Model”
  7. 7.  AbstractEntity  Customer@M appedSupercl ass @Entitypublic class AbstractEntity { public class Customer extends AbstractEntity { @Id private String firstname, lastname; @GeneratedValue(strategy = GenerationT ype. AUTO) private Long id; @Col umn(unique = true) private EmailAddress emailAddress; public Long getId() { return id; @OneToMany(cascade = CascadeType.ALL, orphanRemoval = } true) @JoinColumn(nam e = "custom er_id") public boolean equals(Object obj) { private Set<Address> addresses = new HashSet<Address>(); if (this == obj) { return true; public Customer(String firstname, String lastname) { } Assert.hasText(firstname); if (this.id == null || obj == null || ! Assert.hasText(lastname); (this.getClass().equals(obj.getClass()))) { return false; this.firstname = firstname; } this.lastname = lastname; } AbstractEntity that = (AbstractEntity) obj; protected Customer() { return this.id.equals(that.getId()); } } public int hashCode() { public void add(Address address) { return id == null ? 0 : id.hashCode(); } Assert.notNull(address);} this.addresses.add(address); } … @MappedSuperclass to express that it is not a If there were demand to customize the names of the managed columns to which the properties would be persisted, entity class on its own but rather will be extended you could use the @Column annotation. by entity classes. Step1. “Define Domain Model”
  8. 8.  Address  CustomerRepository@Entity public interface CustomerRepositorypublic class Address extends AbstractEntity { ext ends CrudRepos itory<Customer, Long> { Customer findByEmailAddress(EmailAddress emailAddress);private String street, city, country; Customer findById(Long id); List<Customer> findAll();public Address(String street, String city, String country) { } Assert.hasText(street, "Street must not be null or empty!"); Assert.hasText(city, "City must not be null or empty!"); Assert.hasText(country, "Country must not be null or empty!"); this.street = street; this.city = city; this.country = country; Step2. “Define Repository} Interface”protected Address() { -Just only interface} …  EmailAddress@Em beddabl epublic class EmailAddress {@Colum n(nam e = "email_address")private String value;public EmailAddress(String emailAddress) { Assert.isTrue(isValid(emailAddress), "Invalid email address!"); this.value = emailAddress;} the EmailAddress class is an @Embeddable, whichprotected EmailAddress() { will cause the persistence provider to flatten out all properties of it into the table of the}… surrounding class. Step1. “Define Domain Model”
  9. 9.  SpringConfig@Configuration@EnableT ransactionManagement@ComponentS can@EnableJ paReposi toriespublic class InfrastructureConfig {@Beanpublic DataSource dataSource() { return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).addScript("classpath:sql/schema.sql") .addScript("classpath:sql/test-data.sql").build();}@Beanpublic LocalContainerEntityManagerFactoryBean entityManagerFactory() { HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); vendorAdapter.setDatabase(Database.HSQL); //vendorAdapter.setGenerateDdl(true); vendorAdapter.setShowSql(true); LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setJpaVendorAdapter(vendorAdapter); factory.setPackagesToScan(getClass().getPackage().getName()); factory.setDataSource(dataSource()); return factory;}@Beanpublic PlatformTransactionManager transactionManager() { JpaTransactionManager txManager = new JpaTransactionManager(); txManager.setEntityManagerFactory(entityManagerFactory().getObject()); return txManager;}} Step3. “Configure Spring Beans”
  10. 10.  TestCase@RunWit h(SpringJUnit4Cl assRunner.class) @Test@Cont extConfiguration(classes = { TestConfig.cl ass }) public void saveNewCustomer() {@T ransactional Customer c = new Customer();@Di rtiesContext //c.setFirstname("Sven");public class TestMain { c.setLastname("Svensson"); c.setEmailAddress(new EmailAddress("sven@svensson.org"));@A utowired Address a = new Address("Storgaten 6", "Trosa", "Sweden");CustomerRepository repository; c.add(a); repository.save(c);@Autowired System.out.println(repository.findAll());DataSource dataSource; Customer result = repository.findOne(c.getId()); assertThat(result, is(notNullValue()));@Test //assertThat(result.getFirstName(), is("Sven"));public void testFindAll() { assertThat(result.getEmailAddress().toString(), is(notNullValue()));List< Custom er> results = reposi tory.findAl l(); }assertThat(results, is(notNullValue()));assertThat(results, hasSize(3));assertThat(results.get(0), notNullValue()); @Test(expected = DataIntegrityViolationException.class)assertThat(results.get(1), notNullValue()); public void saveNewCustomerWithDuplicateEmail() {assertThat(results.get(2), notNullValue()); Customer c = new Customer("Bob","Doe");} c.setEmailAddress(new EmailAddress("bob@doe.com")); Address a = new Address("66 Main St", "Middletown", "USA");@Test c.add(a);public void testFindById() { repository.save(c);Customer res ult = repository.findOne(100L); }assertThat(result, is(notNullValue()));assertThat(result.getFirstname(), is("John")); @Test} public void deleteCustomer() { Customer c = repository.findOne(100L);@Test repository.delete(c);public void testFindByEmail() { Customer result = repository.findOne(100L); assertThat(result, is(nullValue()));Customer result = repository.fi ndByEm ail Address(new EmailA ddress("bob@doe.com"));assertThat(result, is(notNullValue())); }assertThat(result.getFirstname(), is("Bob"));} } Step4. “Test it…”
  11. 11.  Document Model  Domain Model Customer Email (*)Address AbstractDocument{ firstname : "Dave", lastname : "Matthews", email : { email : "dave@dmband.com" <<Document>> }, addresses : [ Customer { street : "Broadway", city : "New York", country : "UnitedStates" } ]} <<Entity>> <<Embeddable>> Address EmailAddress Step1. “Define Domain Model”
  12. 12.  AbstractDocument  Customerpublic class AbstractDocument { @Document public class Customer extends AbstractDocument { @Id private BigInteger id; private String firstname, lastname; public BigInteger getId() { @Fi eld("em ail ") return id; @Indexed(unique = true) } private EmailAddress emailAddress; private Set<Address> addresses = new HashSet<Address>(); public boolean equals(Object obj) { public Customer(String firstname, String lastname) { if (this == obj) { return true; Assert.hasText(firstname); } Assert.hasText(lastname); if (this.id == null || obj == null || ! this.firstname = firstname; (this.getClass().equals(obj.getClass()))) { this.lastname = lastname; return false; } } protected Customer() { AbstractDocument that = (AbstractDocument) obj; } return this.id.equals(that.getId()); … } public int hashCode() { return id == null ? 0 : id.hashCode(); }} Step1. “Define Domain Model”
  13. 13.  Address  CustomerRepositorypublic class Address { public interface CustomerRepository ext ends CrudRepos itory<Customer, Long> { private final String street, city, country; Customer findByEmailAddress(EmailAddress emailAddress); Customer findById(Long id); public Address(String street, String city, String country) { List<Customer> findAll(); } Assert.hasText(street, "Street must not be null or empty!"); Assert.hasText(city, "City must not be null or empty!"); Assert.hasText(country, "Country must not be null or empty!"); this.street = street; this.city = city; this.country = country; Step2. “Define Repository … } Interface” -Just only interface  EmailAddresspublic class EmailAddress {@F iel d("emai l")private final String value;public EmailAddress(String emailAddress) { Assert.isTrue(isValid(emailAddress), "Invalid email address!"); this.value = emailAddress;}protected EmailAddress() {}… Step1. “Define Domain Model”
  14. 14.  SpringConfig@Configuration@ComponentS can@EnableM ongoRepositories(baseP ackages="com.mck ang.springdata.mongo")class ApplicationConfig extends AbstractMongoConfiguration { @Autowired private List<Converter<?, ?>> converters; protected String getDatabaseName() { return "e-store"; } public Mongo mongo() throws Exception { Mongo mongo = new Mongo("127.0.0.1"); mongo.setWriteConcern(WriteConcern.FSYNC_SAFE); return mongo; } public CustomConversions customConversions() { return new CustomConversions(converters); } protected String get MappingBasePackage () { return "com.mckang.springdata.mongo"; }} Step3. “Configure Spring Beans”
  15. 15.  TestCase@RunWith(S pringJUnit4ClassRunner.class ) @Test@ContextConfigurati on(cl asses = { T es tConfi g.class }) public void saveNewCustomer() {@T ransactional Customer c = new Customer();@DirtiesContext //c.setFirstname("Sven");public class TestMain { c.setLastname("Svensson"); c.setEmailAddress(new EmailAddress("sven@svensson.org"));@Autowi red Address a = new Address("Storgaten 6", "Trosa", "Sweden");Custom erRepository reposi tory; c.add(a); repository.save(c);@Autowired }DataSource dataSource;@Test @Test(expected = DataIntegrityViolationException.class)public void testFindAll() { public void saveNewCustomerWithDuplicateEmail() { List<Custom er> results = repository.f indAll (); Customer c = new Customer("Bob","Doe"); assertThat(results, is(notNullValue())); c.setEmailAddress(new EmailAddress("bob@doe.com")); assertThat(results, hasSize(3)); Address a = new Address("66 Main St", "Middletown", "USA"); assertThat(results.get(0), notNullValue()); c.add(a); assertThat(results.get(1), notNullValue()); repository.save(c); assertThat(results.get(2), notNullValue()); }} @Test@Test public void deleteCustomer() {public void testFindById() { Customer c = repository.findOne(100L); Custom er result = repos it ory.findOne(100L); repository.delete(c); assertThat(result, is(notNullValue())); } assertThat(result.getFirstname(), is("John"));} }@Testpublic void testFindByEmail() { Customer result = repository.f indByEm ai lAddres s(new Em ail Address("bob@doe.com"));} Step4. “Test it…” (Need Fixture…)
  16. 16.  Graph DatabaseNeo4j is the leading implementation of a property graph database. It is writtenpredominantly in Java and leverages a custom storage format and the facilities of the JavaTransaction Architecture (JTA) to provide XA transactions.Neo4j integrates a transactional, pluggable indexing subsystem that uses Lucene as thedefault. The index is used primarily to locate starting points for traversals. Its second useis to support unique entity creation.
  17. 17.  Cypher statementWith the declarative Cypher query language, Neo4j makes it easier to get started foreveryone who knows SQL from working with relational databases.enabling users to define sophisticated queries like “find me all the customers who havefriends who have recently bought similar products.”Like other query languages, it supports filtering, grouping, and paging. Cypher allows easycreation, deletion, update, and graph construction.
  18. 18.  Graph Model  Domain Model AbstractEntity Customer Address <<NodeEntity>> Customer Address <<NodeEntity>> EmailAddress Address Step1. “Define Domain Model”
  19. 19.  AbstractDocument  Customerpublic abstract class AbstractEntity { @NodeEnti ty public class Customer extends AbstractEntity { @GraphId private Long id; private String firstName, lastName; public Long getId() { @Indexed(unique = true) return id; private String emailAddress; } @Rel atedT o(type = "ADDRESS") @Override private Set<Address> addresses = new HashSet<Address>(); public boolean equals(Object obj) { public Customer(String firstName, String lastName, String emailAddress) { if (this == obj) { return true; Assert.hasText(firstName); } Assert.hasText(lastName); Assert.hasText(emailAddress); if (id == null || obj == null || ! getClass().equals(obj.getClass())) { this.firstName = firstName; return false; this.lastName = lastName; } this.emailAddress = emailAddress; return id.equals(((AbstractEntity) obj).id); } } protected Customer() { @Override } public int hashCode() { … return id == null ? 0 : id.hashCode(); }} Step1. “Define Domain Model”
  20. 20.  Address  CustomerRepository@NodeEntity public interface CustomerRepository extends GraphRepository<Customer> {public class Address extends AbstractEntity { Customer findOne(Long id); private String street, city; <C extends Customer> C save(C customer); public Address(String street, String city) { Customer findByEmailAddress(String emailAddress); this.street = street; } this.city = city; } public Address() { } Step2. “Define Repository … Interface” -Just only interface  EmailAddresspublic class EmailAddress {private final String value;public EmailAddress(String emailAddress) { Assert.isTrue(isValid(emailAddress), "Invalid email address!"); this.value = emailAddress;}protected EmailAddress() {}… Step1. “Define Domain Model”
  21. 21.  SpringConfig@Configuration@ComponentS can@ImportResource("cl asspath:ME TA-INF /spring/spring-data-context.xml ")@EnableT ransactionManagementclass ApplicationConfig { @Bean(destroyMethod = "shutdown") public GraphDatabaseService graphDatabaseService() { //return new EmbeddedGraphDatabase("target/graph.db"); return new SpringRestGraphDatabase("http://localhost:7474/db/data"); }}<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:neo4j="http://www.springframework.org/schema/data/neo4j" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j-2.0.xsd"> <!--neo4j:config storeDi rectory="target/graph.db" /--> <neo4j :c onfig graphDatabaseService= "graphDatabaseService" /> <neo4j :repositori es base-package="com. mckang.springdata.neo4j" /></beans> Step3. “Configure Spring Beans”
  22. 22.  TestCase@RunWith(SpringJUni t4ClassRunner.cl ass)@Context Confi guration(classes = { TestConfig.class }) @Testpublic class TestMain { public void preventsDuplicateEmail() {@Autowired final EmailAddress email = new EmailAddress("dave@dmband.com");CustomerReposi tory repository; Customer dave = repository.findByEmailAddress(email.getEmail()); Customer anotherDave = new Customer("Dave", "Matthews",dave.getEmailAddress());@Autowired repository.save(anotherDave);DataSource dataSource; }@Test }public void savesCustomerCorrectly() {EmailAddress email = new EmailAddress("alicia@keys.com");Customer alicia = new Customer("Alicia", "Keys",email.getEmail()); // todoalicia.add(new Address("27 Broadway", "New York"));Customer result = repository.save(alicia);assertThat(result.getId(), is(notNullValue()));}@Testpublic void readsCustomerByEmail() {EmailAddress email = new EmailAddress("alicia@keys.com");Customer alicia = new Customer("Alicia", "Keys",email.getEmail());repository.save(alicia);Customer result = repository.findByEmailAddress(email.getEmail());assertThat(result, is(alicia));} Step4. “Test it…” (Need Fixture…)

×