- NoSQL and Graph databases
Neo4j是一个开源的NOSQL图形数据库 - Requirements
a. JDK8及以上
b. Neo4j3.1及以上
c. Spring Framework 5.0.5.RELEASE及以上 - Dependencies
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-releasetrain</artifactId>
<version>${release-train}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
- Working with Spring Data Repositories
CrudRepository为实体类提供了复杂的CRUD功能。
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
//保存实体
<S extends T> S save(S entity);
//查询单个节点
Optional<T> findById(ID primaryKey);
//查询所有节点
Iterable<T> findAll();
//统计节点
long count();
//删除指定的节点
void delete(T entity);
//判断某个Id的节点是否存在
boolean existsById(ID primaryKey);
}
4.1 在CrudRepository之上,有一个添加额外的分页和排序存储库抽象
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
//查询条件:排序
Iterable<T> findAll(Sort sort);
//分页查询
Page<T> findAll(Pageable pageable);
}
- Query methods
标准的CRUD功能存储库通常对底层数据存储有查询。分为四步:
- 声明一个扩展存储库或其子接口的接口,并将其输入到域clas中
interface PersonRepository extends Repository<Person, Long> { … }
- 在接口上声
interface PersonRepository extends Repository<Person, Long> {
List<Person> findByLastname(String lastname);
} - 设置Spring,为这些接口创建代理实例。通过
注解方式或者xml注入
3.1 .import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@EnableJpaRepositories
class Config {}
3.2.
- 声明一个扩展存储库或其子接口的接口,并将其输入到域clas中
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<repositories base-package="com.acme.repositories" />
</beans:beans>
- 获取存储库实例并使用它(Get the repository instance injected and use it.)
class SomeClient {
private final PersonRepository repository;
SomeClient(PersonRepository repository) {
this.repository = repository;
}
void doSomething() {
List<Person> persons = repository.findByLastname("Matthews");
}
}
- 自定义Reponsitory接口
@NoRepositoryBean
interface MyBaseRepository<T, ID extends Serializable> extends Repository<T, ID> {
Optional<T> findById(ID id);
<S extends T> S save(S entity);
}
interface UserRepository extends MyBaseRepository<User, Long> {
User findByEmailAddress(EmailAddress emailAddress);
}
使用具有多个Spring数据模块的存储库
Example 11. Repository definitions using Module-specific Interfaces
interface MyRepository extends JpaRepository<User, Long> { }
@NoRepositoryBean
interface MyBaseRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
…
}
interface UserRepository extends MyBaseRepository<User, Long> {
…
}
MyRepository and UserRepository extend JpaRepository in their type hierarchy. They are valid candidates for the Spring Data JPA module.
Example 12. Repository definitions using generic Interfaces
interface AmbiguousRepository extends Repository<User, Long> {
…
}
@NoRepositoryBean
interface MyBaseRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
…
}
interface AmbiguousUserRepository extends MyBaseRepository<User, Long> {
…
}
AmbiguousRepository and AmbiguousUserRepository extend only Repository and CrudRepository in their type hierarchy. While this is perfectly fine using a unique Spring Data module, multiple modules cannot distinguish to which particular Spring Data these repositories should be bound.
Example 13. Repository definitions using Domain Classes with Annotations
interface PersonRepository extends Repository<Person, Long> {
…
}
@Entity
class Person {
…
}
interface UserRepository extends Repository<User, Long> {
…
}
@Document
class User {
…
}
PersonRepository references Person which is annotated with the JPA annotation @Entity so this repository clearly belongs to Spring Data JPA. UserRepository uses User annotated with Spring Data MongoDB’s @Document annotation.
Example 14. Repository definitions using Domain Classes with mixed Annotations
interface JpaPersonRepository extends Repository<Person, Long> {
…
}
interface MongoDBPersonRepository extends Repository<Person, Long> {
…
}
@Entity
@Document
class Person {
…
}
This example shows a domain class using both JPA and Spring Data MongoDB annotations. It defines two repositories, JpaPersonRepository and MongoDBPersonRepository. One is intended for JPA and the other for MongoDB usage. Spring Data is no longer able to tell the repositories apart which leads to undefined behavior.
- Query creation
The mechanism strips the prefixes find…By, read…By, query…By, count…By, and get…By from the method and starts parsing the rest of it.
Example 16. Query creation from method names
interface PersonRepository extends Repository<User, Long> {
List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);
// Enables the distinct flag for the query
List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);
// Enabling ignoring case for an individual property
List<Person> findByLastnameIgnoreCase(String lastname);
// Enabling ignoring case for all suitable properties
List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);
// Enabling static ORDER BY for a query
List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
List<Person> findByLastnameOrderByFirstnameDesc(String lastname);
}
8.1 Special parameter handling
Example 17. Using Pageable, Slice and Sort in query methods
Page<User> findByLastname(String lastname, Pageable pageable);
Slice<User> findByLastname(String lastname, Pageable pageable);
List<User> findByLastname(String lastname, Sort sort);
List<User> findByLastname(String lastname, Pageable pageable);
8.2. Limiting query results
User findFirstByOrderByLastnameAsc();
User findTopByOrderByAgeDesc();
Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);
Slice<User> findTop3ByLastname(String lastname, Pageable pageable);
List<User> findFirst10ByLastname(String lastname, Sort sort);
List<User> findTop10ByLastname(String lastname, Pageable pageable);
- Creating repository instances
9.1 xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<repositories base-package="com.acme.repositories" />
</beans:beans>
9.2 JavaConfig
@Configuration
@EnableJpaRepositories("com.acme.repositories")
class ApplicationConfiguration {
@Bean
EntityManagerFactory entityManagerFactory() {
// …
}
}
- WEB support
1.
@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
class WebConfiguration {}
2.
<bean class="org.springframework.data.web.config.SpringDataWebConfiguration" />
<!-- If you're using Spring HATEOAS as well register this one *instead* of the former -->
<bean class="org.springframework.data.web.config.HateoasAwareSpringDataWebConfiguration" />