970 likes | 1.3k Views
Introduction to Spring Data. Dr. Mark Pollack. Agenda. The current data landscape Project Goals Project Tour. Enterprise Data Trends. Enterprise Data Trends. Unstructured Data No predefined data model Often doesn’t fit well in RDBMS Pre-Aggregated Data Computed during data collection
E N D
Introduction to Spring Data Dr. Mark Pollack
Agenda The current data landscape Project Goals Project Tour
Enterprise Data Trends • Unstructured Data • No predefined data model • Often doesn’t fit well in RDBMS • Pre-Aggregated Data • Computed during data collection • Counters • Running Averages
The Value of Data Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/418.9 (KHTML, like Gecko) Safari/419.3 • Value from Data Exceeds Hardware & Software costs • Value in connecting data sets • Grouping e-commerce users by user agent
The Data Revolution • Extremely difficult/impossible to scale writes in RDBMS • Vertical scaling is limited/expensive • Horizontal scaling is limited or requires $$ • Shift from ACID to BASE • Basically Available, Scalable, Eventually Consistent • NoSQL datastores emerge as “point solutions” • Amazon/Google papers • Facebook, LinkedIn …
NoSQL “Not Only SQL” NOSQL \no-seek-wool\ n. Describes ongoing trend where developers increasingly opt for non-relational databases to help solve their problems, in an effort to use the right tool for the right job. • Query Mechanisms: • Key lookup, map-reduce, query-by-example, query language, traversals
Big Data “Big data” refers to datasets whose size is beyond the ability of typical database software tools to capture, store, manage, and analyze. A subjective and moving target. Big data in many sectors today range from 10’s of TB to multiple PB
Spring Data - Background and Motivation • Data access landscape has changed considerably • RDBMS are still important and predominant • but no longer considered a “one size fits all” solution • But they have limitations • Hard to scale • New data access technologies are solving problems RDBMS can’t • Higher performance and scalability, different data models • Often limited transactional model and relaxed consistency • Polyglot persistence is becoming more prevalent • Combine RDBMS + other DBs in a solution
Spring and Data Access • Spring has always provided excellent data access support • Transaction Management • Portable data access exception hierarchy • JDBC – JdbcTemplate • ORM - Hibernate, JPA, JDO, Ibatis support • Cache support (Spring 3.1) • Spring Data project started in 2010 • Goal is to “refresh” Spring’s Data Access support • In light of new data access landscape
Spring Data Mission Statement 89% of all virtualized applications in the world run on VMware. Gartner, December 2008 “ Provides a familiar and consistent Spring-based programming model for Big Data, NoSQL, and relational stores while retaining store-specific features and capabilities.
Spring Data Mission Statement 89% of all virtualized applications in the world run on VMware. Gartner, December 2008 “ Provides a familiar and consistent Spring-based programming model for Big Data, NoSQL, and relational stores while retaining store-specific features and capabilities.
Spring Data Mission Statement 89% of all virtualized applications in the world run on VMware. Gartner, December 2008 “ store-specific features and capabilities.
Spring Data – Supported Technologies • Big Data • Hadoop • HDFS and M/R • Hive • Pig • Cascading • Splunk • Access • Repositories • QueryDSL • REST • Relational • JPA • JDBC Extensions • NoSQL • Redis • HBase • Mongo • Neo4j • Lucene • Gemfire
Spring Data – Have it your way • Shared programming models and data access mechanisms • Repository Model • Common CRUD across data stores • Integration with QueryDSL • Typesafe query language • REST Exporter • Expose repository over HTTP in a RESTful manner. • Database specific features are accessed through familiar Spring Template pattern • RedisTemplate • HBaseTemplate • MongoTemplate • Neo4jTemplate • GemfireTemplate
Spring Data JDBC Extensions – Oracle Support • Easy Access to native XML, Struct, Array data types • API for customizing the connection environment • Fast Connection Failover • Simplified configuration for Advanced Queuing JMS support and DataSource • Single local transaction for messaging and database access
QueryDSL “ Enables the construction of type-safe SQL-like queries for multiple backends including JPA, JDO, MongoDB, Lucence, SQL and plain collections in Java • http://www.querydsl.com/ - Open Source, Apache 2.0
Problems using Strings for a query language Using strings is error-prone Must remember query syntax, domain classes, properties and relationships Verbose parameter binding by name or position Each back-end has its own query language and API Note: .NET has LINQ
QueryDSL Features QCustomer customer = QCustomer.customer; JPQLQuery query = new JPAQuery(entityManger) Customer bob = query.from(customer) .where(customer.firstName.eq(“Bob”) .uniqueResult(customer) • Code completion in IDE • Almost no syntactically invalid queries allowed • Domain types and properties can be references safely (no Strings) • Helper classes generated via Java annotation processor • Much less verbose than JPA2 Criteria API
Using QueryDSL for JDBC QAddress qAddress = QAddress.address; SQLTemplates dialect = new HSQLDBTemplates(); SQLQuery query = new SQLQueryImpl(connection, dialect) .from(qAddress) .where(qAddress.city.eq("London")); List<Address> results = query.list(new QBean<Address>(Address.class, qAddress.street, qAddress.city, qAddress.country)); Querydsl Predicate • Incorporate code-generation into your build process • To create a query meta-model of domain classes or Tables (JDBC) • For SQL
Spring JDBC Extension – QueryDslJdbcTemplate • Wrapper around JdbcTemplate that supports • Using Querydsl SQLQuery classes to execute queries • Integrates with Spring’s transaction management • Automatically detects DB type and set SQLTemplates dialect • Spring RowMapper and ResultSetExtractors for mapping to POJOs • Executing insert, updates and deletes with Querdsl’s SQLInsertClause, SQLUpdateClause, and SQLDeleteClause
Spring JDBC Extension – QueryDslJdbcTemplate // Query with join QCustomer qCustomer = QCustomer.customer; SQLQuery findByIdQuery = qdslTemplate.newSqlQuery() .from(qCustomer) .leftJoin(qCustomer._addressCustomerRef, qAddress) .where(qCustomer.id.eq(id));
Repositories Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects. http://martinfowler.com/eaaCatalog/repository.html
Spring Data Repositories We remove the busy work of developing a repository
For Example… publicinterface CustomerRepository { Customer findOne(Long id); Customer save(Customer customer); Customer findByEmailAddress(EmailAddress emailAddress); } @Entity publicclass Customer { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column(unique = true) private EmailAddress emailAddress; @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "customer_id") private Set<Address> addresses = new HashSet<Address>(); // constructor, properties, equals, hashcode omitted for brevity }
Traditional JPA Implementation @Repository public class JpaCustomerRepository implements CustomerRepository { @PersistenceContext private EntityManager em; @Override public Customer findOne(Long id) { returnem.find(Customer.class, id); } public Customer save(Customer customer) { if (customer.getId() == null) { em.persist(customer); return customer; } else { returnem.merge(customer); } } ...
Traditional JPA Implementation . . . @Override public Customer findByEmailAddress(EmailAddress emailAddress) { TypedQuery<Customer> query = em.createQuery("select c from Customer c where c.emailAddress = :email", Customer.class); query.setParameter("email", emailAddress); return query.getSingleResult(); } }
Spring Data Repositories • A simple recipe • Map your POJO using JPA • Extend a repository (marker) interface or use an annotation • Add finder methods • Configure Spring to scan for repository interfaces and create implementations • Inject implementations into your services and use as normal…
Spring Data Repository Example publicinterface CustomerRepository extends Repository<Customer, Long> { // Marker Interface Customer findOne(Long id); Customer save(Customer customer); Customer findByEmailAddress(EmailAddress emailAddress); } @RepositoryDefinition(domainClass=Customer.class, idClass=Long.class) publicinterface CustomerRepository { . . . } or
Spring Data Repository Example @Configuration @EnableJpaRepositories @Import(InfrastructureConfig.class) publicclass ApplicationConfig { } <jpa:repositories base-package="com.oreilly.springdata.jpa" /> Boostratp with JavaConfig Or XML And Spring will create an implementation the interface
Spring Data JPA - Usage Wire into your transactional service layer as normal
Query Method Keywords How does findByEmailAddres work…
Spring Data Repositories - CRUD publicinterface 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(); }
Paging, Sorting, and custom finders publicinterface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> { Iterable<T> findAll(Sort sort); Page<T> findAll(Pageable pageable); } publicinterfacePersonRepositoryextendsCrudRepository<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); }
Spring Data JPA – Customize Query Methods publicinterfaceCustomerRepositoryextendsCrudRepository<Customer,Long> { // 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); } • Query methods use method naming conventions • Can override with Query annotation • Or method name references JPA named query
Spring Data JPA – Other features Specifications using JPA Criteria API LockMode, override Transactional metadata, QueryHints Auditing, CDI Integration QueryDSL support
Querydsl and JPA CriteriaBuilder builder = entityManagerFactory.getCriteriaBuilder(); CriteriaQuery<Person> query = builder.createQuery(Person.class); Root<Person> men = query.from( Person.class ); Root<Person> women = query.from( Person.class ); Predicate menRestriction = builder.and( builder.equal( men.get( Person_.gender ), Gender.MALE ), builder.equal( men.get( Person_.relationshipStatus ), RelationshipStatus.SINGLE ) ); Predicate womenRestriction = builder.and( builder.equal( women.get( Person_.gender ), Gender.FEMALE ), builder.equal( women.get( Person_.relationshipStatus ),RelationshipStatus.SINGLE ) ); query.where( builder.and( menRestriction, womenRestriction ) ); • Easier and less verbose and JPA2 Criteria API • “equals property value” vs. “property equals value” • Operations via a builder object
Querydsl and JPA JPAQuery query = new JPAQuery(entityManager); QPerson men = new QPerson("men"); QPerson women = new QPerson("women"); query.from(men, women).where(men.gender.eq(Gender.MALE), men.relationshipStatus.eq(RelationshipStatus.SINGLE), women.gender.eq(Gender.FEMALE), women.relationshipStatus.eq(RelationshipStatus.SINGLE)); Querydsl Predicates verus…
QueryDSL - Repositories publicinterface 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 ProductRepository extends Repository<Product,Long>, QueryDslPredicateExecutor<Product> { … } Product iPad = productRepository.findOne(product.name.eq("iPad")); Predicate tablets = product.description.contains("tablet"); Iterable<Product> result = productRepository.findAll(tablets);
Key/Value Familiar, much like a hash table Redis, Riak, Voldemort,… Amazon Dynamo inspired
Column Family • Extended key/value model • values can also be key/value pairs • HBase, Cassandra • Google Bigtable inspired