Spring Data: a new perspective of data operations
Spring Data is an umbrella project from SpringSource Community, which tries to provide a more generic abstraction of data operations for RDBMS, NoSQL and cloud based data and indexing service.
The status of Spring Data
Spring Data is evolved out of an open source project named Hades, which mainly provided a GenericDao interface for Hibernate/JPA. Spring Data extends the core concept to other domains and APIs.
According to the Spring data project page, currently the official Spring Data project provides the following sub modules.
- JPA
- REST
- JDBC Extensions
- Apache Hadoop
- GemFire
- Redis
- MongoDB
- Neo4j
- Commons
Besides, there are some community based projects available.
- Spring Data Solr , Spring Data repositories abstraction for Apache Solr
- Spring Data Elasticsearch , Spring Data repositories abstraction for Elasticsearch
- Spring Data Couchbase , Spring Data repositories abstraction for Couchbase
- Spring Data FuzzyDB , Spring Data repositories abstraction for FuzzyDB
Spring Data Commons(Maven archetype id is spring-data-commons) is the base for other modules.
Overview of Spring Data Commons
The most attractive feature of Commons is it provides a genericRepository interface and two extended variants for CRUD operations(CurdRepository) and pagination(PagingAndSortingRepository) purposes which can be used in all other sub modules.
public interface Repository<T, ID extends Serializable> { }
Repository is an empty interface which can accept a domain class and a serialable primary key as type parameters. CurdRepository extendsRepository and adds some common methods for CRUD operations,PagingAndSortingRepository extends CurdRepository and provides pagination and sort capability.
You can select any one of them to extend in your project. But in the real world project, you should extend the one in the certain sub module, which provides more features. For example, if you are using Spring Data JPA, it is better to create your Repository to extendJpaRepository which is extended from PagingAndSortingRepository.
When you use any sub modules, you must add Spring Data Commons as project dependency, and specify the package which includes the your Repository in Spring configuration. Spring Data will discover theRepository beans automatically.
For example, if you are using Spring Data JPA, you have to add the following configuration
<jpa:repositories base-package="com.hantsylabs.example.spring.jpa"></jpa:repositories>
or use @EanbleJpaRepositories via Spring java configuration
@EnableJpaRepositories(basePackages = { "com.hantsylabs.example.spring.jpa" })
to activate your own repositories.
NOTE: If you are using the Repository API in other data storage, such as MongoDB, you should include Spring Data Mongo dependency in project classpath and activate it via mongo namespace.
Up to now, you can not see any magic of the Repository API. Keep patient!
Query by convention
Assume there is a JPA entity class defined as:
@Entity public class Conference { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id") private Long id; @Version @Column(name = "version") private Integer version; @NotNull private String name; @NotNull private String description; @NotNull @Temporal(TemporalType.TIMESTAMP) @DateTimeFormat(style = "M-") private Date startedDate; @NotNull @Temporal(TemporalType.TIMESTAMP) @DateTimeFormat(style = "M-") private Date endedDate; @NotNull private String slug; //getters and setters ... }
And declare an Repository interface for Conference class like this:
public interface ConferenceRepository extends PagingAndSortingRepository<Conference, Long>{ Conference findBySlug(String slug); Conference findByName(String name); Conference findByDescriptionLike(String desc); Conference findByStartedDateBetween(Date started, Date ended); //... }
Now you can call them directly in your Services or Controllers, yes, you do not need to implement them at all, Spring Data prepare the query and get the results for you.
When you are using JPA, findBySlug are equivalent to the following JPQL.
from Conference where slug=?1
When you are using Mongo, you do not need the JPA entity declaration, and the method will be converted into Mongo specific expression.
In this example, the methods return a single object, in most of case, they should return a Collection of object.
Ideally, the above logic are available in all Spring Data sub modules, but the method naming convention maybe some difference among the specific data storage.
Common annotations
If you have used Spring Data in projects, you will find it try to provide a series of common annotations for all data storage. Such as, @Id, @Version, @Persistent, @Transient, @PersistenceConstructor, etc. Please explorer the package org.springframework.data.annotation for more details.
But currently they behaves a little different in the sub modules, they can not be exchanged with the ones in the existing API, such as JPA API.
Personally, I do not think this is a good idea. If you are keep an open on the world outside of Spring, you will find there are some better solutions.
EclipseLink and Hibernate are starting to support NoSQL in the new version, but base on JPA API(and some extension), DataNucleus is a mature solution for multi storage(RDBMS, NoSQL, even filesystem), but it supports standard JPA, JDO API, and it is also used in Google App Engine for Java developers. Obviously, if you select these solutions, the learning curve to switch between different storage will be decreased dramatically.
Audit API
Commons provides some interfaces(such as Auditable, Persistable,AuditorAware) and annotations(@CreatedDate, @CreatedBy,@LastModifidedBy, @LastModifiedDate) to developers to add some simple audit capabilities for your domain classes.
Pagination capability
Pagination is a basic feature for web application, some APIs in Commons are ready for this purpose.
The PagingAndSortingRepository provides some methods which can accept a Pageable object as parameter and return a Page object.
Pageable interface which will be passed in includes the essential data for pagination, such page size, offset, sort field and direction. There is a default implementation class PageRequest provided in Commons.
Page class wraps all information of the pagination query result, the collection of result data, the count of all data, etc.
Commons provides some pagination integration with Spring MVC.
We will discuss these in details in future post.
评论