跳至主要内容

Spring Data: a new perspective of data operations


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.
发表评论

此博客中的热门博文

JPA 2.1: Attribute Converter

JPA 2.1: Attribute Converter If you are using Hibernate, and want a customized type is supported in your Entity class, you could have to write a custom Hibernate Type. JPA 2.1 brings a new feature named attribute converter, which can help you convert your custom class type to JPA supported type. Create an Entity Reuse thePostentity class as example. @Entity @Table(name="POSTS") public class Post implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name="ID") private Long id; @Column(name="TITLE") private String title; @Column(name="BODY") private String body; @Temporal(javax.persistence.TemporalType.DATE) @Column(name="CREATED") private Date created; @Column(name="TAGS") private List<String> tags=new ArrayList<>(); } Create an attribute converter In this example…

Spring Data Mongo: bridge MongoDB and Spring

Spring Data Mongo: bridge MongoDB and SpringMongoDBis one of the most popular NoSQL products, Spring Data Mongo(Maven archetype id is spring-data-mongodb) tries to provides a simple approach to access MongoDB. Configuration Add the following code fragments in your Spring configuration. <!-- Mongo config --> <mongo:db-factory id="mongoDbFactory" host="localhost" port="27017" dbname="conference-db" /> <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-arg ref="mongoDbFactory" /> </bean> <mongo:repositories base-package="com.hantsylabs.example.spring.mongo" /> Firstly, declare aDbFactorywhich is responsible for connecting to the MongoDB server. Then, register theMongoTemplateobject which envelop the data operations on MongoDB. Lastly addmongo:repositorieswith an essentialbase-packageattribute, Spring will discovery your d…

Auditing with Hibernate Envers

Auditing with Hibernate Envers The approaches provided in JPA lifecyle hook and Spring Data auditing only track the creation and last modification info of an Entity, but all the modification history are not tracked. Hibernate Envers fills the blank table. Since Hibernate 3.5, Envers is part of Hibernate core project. Configuration Configure Hibernate Envers in your project is very simple, just need to addhibernate-enversas project dependency. <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-envers</artifactId> </dependency> Done. No need extra Event listeners configuration as the early version. Basic Usage Hibernate Envers provides a simple@Auditedannotation, you can place it on an Entity class or property of an Entity. @Audited private String description; If@Auditedannotation is placed on a property, this property can be tracked.