+ All Categories
Transcript
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


Top Related