26
Easy Data with Spring-Data JPA Miya W. Longwe, Tech Lead, Staples Inc. January 07, 2014 Java Meetup Group, Cambridge, MA , USA

Easy data-with-spring-data-jpa

  • Upload
    staples

  • View
    854

  • Download
    0

Embed Size (px)

DESCRIPTION

Java and Spring Data JPA: Easy SQL Data Access Abstract Presenter: Miya W. Longwe, MBA, MSE, Tech Lead, Staples, Inc, Framingham MA 01702 Accessing data repositories in various applications programming languages typically involves writing of tedious boilerplate lines of code. Some application development frameworks such as Spring have tried to make the experience more succinct by providing abstraction layers such as HibernateTemplate and JdbcTemplate, etc. Despite these APIs, the developers still spend a lot time writing repetitive code than concentrating on implementing business requirements. Developers at Spring, led by Oliver Gierke, introduced Spring Data JPA which “aims to significantly improve the implementation of data access layers by reducing the effort to the amount that's actually needed. As a developer you write your repository interfaces, including custom finder methods, and Spring will provide the implementation automatically”. Spring Data JPA provides a powerful, out-of-the-box alternative to creating your own DAO framework. You declare custom repository operations on an interface, and the framework generates dynamic implementations (not code generation) automatically, based on conventions around method names. As part of the presentation, we'll also review a demo to look at Spring Java configuration (as opposed to XML configuration), and investigate the @Profile annotation – configuration details which may make life a bit easier in various ways when setting up unit testing of our repository classes, using out-of-the-box alternative to creating DAO framework, how to create custom repositories, pagination and support for custom queries among other features. Presenter's Bio Miya W. Longwe is a Senior Software Engineer and Tech Lead at Staples, Inc. where he is currently working on an initiative to re-platform the company’s ecommerce architecture to offer platform-driven, modular products that can be quickly customized, enhanced, and branded as needed. Miya has been a software professional since 1997. His 16 years software development career includes working for large companies to small startups, building solutions for enterprises and consumers, working with a broad range of technologies. Miya Longwe is a hands-on java developer. He believes that in order to be a relevant and effective software developer one needs to remain a deeply knowledgeable, up-to-date, and productive software developer. His research interests include model-driven engineering, domain specific languages, test driven development and project risk management. Miya graduated from the University of Malawi (Lilongwe, Malawi) and has an MBA from the University of Wales Cardiff Business School (Wales, UK) and a Masters in Software Engineering from Brandeis University (MA, USA). Occasionally, Miya can be spotted fishing the banks of the south shore (MA) with his two boys, William and Daniel.

Citation preview

Page 1: Easy data-with-spring-data-jpa

Easy Data with Spring-Data JPA

Miya W. Longwe, Tech Lead, Staples Inc.January 07, 2014

Java Meetup Group, Cambridge, MA , USA

Page 2: Easy data-with-spring-data-jpa

Agenda Java DB Access Ordeal

Enter Spring-Data

Spring-Data JPA Features

Code Demo

Q and A

Page 3: Easy data-with-spring-data-jpa

Java DB AccessThe Developer’s Holy Pilgrim!

Page 4: Easy data-with-spring-data-jpa

Application Domain Domain driven design has become a

ubiquitous approach to tackle complex problem domains and build a rich object model.

Implementing a data access layer of an application has been cumbersome for quite a while.

Too much boilerplate code has to be written.

Code to execute simple queries as well as perform pagination, auditing, etc

Page 5: Easy data-with-spring-data-jpa

Java DB Access – AccessorInterface

public interface CustomerService {Customer findById(Long id);Customer save(Customer customer);List<Customer> findAll();List<Customer> findAll(int page, int pageSize);...}

Page 6: Easy data-with-spring-data-jpa

Java DB Access –The Boilerplate Code

/** * Plain JPA implementation of {@link CustomerService}. * * @author Miya W Longwe */@Repository@Transactional(readOnly = true)public class CustomerServiceImpl implements CustomerService {

@PersistenceContextprivate EntityManager em;

@Overridepublic Customer findById(Long id) {

return em.find(Customer.class, id);}

@Overridepublic List<Customer> findAll() {

return em.createQuery("select c from Customer c", Customer.class).getResultList();

}……

}

Page 7: Easy data-with-spring-data-jpa

Java DB Access – The Story● JPA handles mechanics of ORM● The catch:– You are responsible for accessor boilerplate code● Using direct JDBC?– More boilerplate code (think DAO layer)● What about Spring support?– Makes things better (JdbcTemplate)– Spring-Data eases the pain further

Page 8: Easy data-with-spring-data-jpa

Spring-Data to the Rescue!

Page 9: Easy data-with-spring-data-jpa

Spring-Data Uses the Repository abstraction for

data access

Automation of data access boilerplate code

Reduces level of efforts for accessor code

Support for multiple data stores including– JPA– Key-Value, column, document, graph data stores(Redis, Mongo, Neo4j, HBase)– Hadoop / HDFS – Others

Page 10: Easy data-with-spring-data-jpa

Spring-Data JPA Workflow Define an Entity Class

Define a Repository interface with data accessor methods

Then see you gator!

Page 11: Easy data-with-spring-data-jpa

Define Your Entity

/** * An entity class which contains the information of a single person. * @author Miya W. Longwe */@Entity@Table(name = "persons")public class Person { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column(name = "creation_time", nullable = false) private Date creationTime; @Column(name = "first_name", nullable = false) private String firstName;

@Column(name = "last_name", nullable = false) private String lastName; @Column(name = "modification_time", nullable = false) private Date modificationTime; ...}

Page 12: Easy data-with-spring-data-jpa

Define The Repository Interface

You provide a Java interface

– Attach an entity type along with key type

– CRUD/data accessor method signatures

Spring-Data can automatically derive proper JPQL

In simpler cases, no additional code required

Queries are derived from method signatures

Page 13: Easy data-with-spring-data-jpa

Repository Interface

* Specifies methods used to obtain and modify person related information * which is stored in the database. * @author Miya W. Longwe */public interface PersonRepository extends JpaRepository<Person, Long> {}

Page 14: Easy data-with-spring-data-jpa

No More Boilerplate Code It goes away (sort of) *

Spring-Data framework derives and attaches JPQL (or specified query) at load-time

Page 15: Easy data-with-spring-data-jpa

Spring-Data Features

Page 16: Easy data-with-spring-data-jpa

Provided Repositories Spring-Data JPA provides two

repositories

CrudRepository– Long list of standard CRUD operations provided– findOne(), findAll(), save(), delete(), exists(), etc

PagingAndSortingRepository

– Derived from CrudRepository

– Provides paginated repository access methods

Page 17: Easy data-with-spring-data-jpa

Configure Spring Framework Specify your repository locations for

scanning

Spring will create proxy instances for repositories

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http:/www.springframework.org/schema/beans" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd"><mvc:resources mapping="/static/**" location="/static/"/>

<mvc:default-servlet-handler/>

<!-- Configures Spring Data JPA and sets the base package of my DAOs. --> <jpa:repositories base-package="com.meetup.easydata.spring.datajpa.repository"/></beans>

Page 18: Easy data-with-spring-data-jpa

Spring-Data Query Generation Derived from method signatures

Parses method names for attributes and keywords

Uses method parameters as query params

public interface UserRepository extends CrudRepository<User, Long> {List<Customer> findByEmailAddressAndLastname(String emailAddress, String lastname);}

Select c from Customer where c.emailAddress = ?1 and c.lastName = ?2

Page 19: Easy data-with-spring-data-jpa

Spring-DataMethod Name-to-JPQL Mapping

Method Name Generated JPQL

findByXxxAndYyy(aaa, bbb)

... where t.xxx = ?1 and t.yyy = ?2

findByXxxOrYyy(aaa, bbb)

... where t.xxx = ?1 or t.yyy = ?2

findByXxxStartingWith(aaa)

('%' appended to param value)

findByXxxNot(aaa) ... where t.xxx <> ?1

findByXxxIn(Collection<E>aaa)

...where t.xxx in ?1

---and many more!

Page 20: Easy data-with-spring-data-jpa

Spring-DataFurther Property Parsing Features

-Traversal can reach into nested properties -Will do best effort using camelCase-You can delineate properties using “_”

}@Entitypublic class User <Long> {private ZiCode zicode;--}

}public interface UserRepository extends CrudRepository<User, Long>{...User findByAddress_ZipCode(ZipCode zipCode);

Page 21: Easy data-with-spring-data-jpa

@Query – Use Your Own Query

• You don't like the derived query or want to do

something fancier?● Use @Query notation to provide your own● Support both JPQL or native SQL● Still provides automatic proxy implementationpublic interface UserRepository extends

CrudRepository<User, Long>{...@Query("select u from User u where u.firstname = ?1")List<User> findByFirstname(String firstname);@Query(value="SELECT FROM USERS WHERE EMAIL_ADDRESS = ?1" nativeQuery=true)User findByEmailAddress(String email);

...

Page 22: Easy data-with-spring-data-jpa

@Query – Named Params

• Spring-Data JPA will use position for parameter binding• You can also use named params instead

interface UserRepository extends CrudRepository<User, Long>{...@Query("select u from User u where u.firstname = :name or u.lastname = :name")List<User> findByFirstnameOrLastname(@Param("name") String name);...}

Page 23: Easy data-with-spring-data-jpa

Result Pagination

• Seamlessly provides support for result set pagination via Pageable Interface

• Define repository method with Pageable• Call method with PageRequest class (or define your

own)

public interface ProductRepository extends CrudRepository<User, Long>{...Page<Product> findAll(Pageable pageable);...}

class ProductService {Pageable pageable = new PageRequest(1, 20);Page<Product> page = repository.findByDescriptionContaining(pageable);}

Page 24: Easy data-with-spring-data-jpa

Custom Repositories

• When Spring-Data JPA derived queries are not• enough or you need additional logic• Provide your own repository implementation• A bean that lives in Spring Context

interface UserRepositoryCustom {List<User> myCustomBatchOperation();}

class UserRepositoryImpl implements UserRepositoryCustom {@PersistenceContextprivate EntityManager em;public List<User> myCustomBatchOperation() {CriteriaQuery<User> criteriaQuery = em.getCriteriaBuilder().createQuery(User.class);return em.createQuery(criteriaQuery).getResultList();}}

Page 25: Easy data-with-spring-data-jpa

Transaction Support

• Repository classes are transactional by default• Reads are made readOnly• Other methods are @Transactional by default• Ability to override by providing your own@Transactional demarcation

public interface UserRepository extends CrudRepository<User, Long>{...@Transactional(timeout=10)@Modifying@Query("update User u set u.firstname = ?1 where u.lastname = ?2")User fixFirstNameByLastName(String firstname, String lastname);...}

Page 26: Easy data-with-spring-data-jpa

Code Demo