spring boot 项目是spring用来解决数据访问问题的一揽子解决方案,spring data是一个伞形项目,包含了大量关系型数据库及非关系型数据库的数据访问解决方案。spring data使我们可以快速且简单的使用普通的数据访问技术及新的数据访问技术。
spring data包含的子项目:
spring data jpa
spring data mongodb
spring data neo4j
spring data solr
spring data hadoop
spring data gemfire
spring data rest
spring data jdbc extensions
spring data elasticsearch
spring data cassandra
spring data dynamodb
以上子项目都依赖于spring data commons项目来实现,它让我们在使用关系型或非关系型数据访问技术时都使用基于spring的统一标准,该标准包括CRUD(创建,获取,更新,删除),查询,排序和分页的相关操作。
spring data commons的一个重要概念:spring data repository抽象。可以极大地减少数据访问层的代码。其中定义了各式各样的访问接口,repository接口:
import.java.io.serializable;
public inteface Repository<T,ID extends Serializable>{
}
repository接口的子接口CrudRepository定义了和CRUD操作相关的内容:
public inteface CrudRepository<T,ID extends Serializable> extends Repository<T,ID>{
<S extends T> S save(S entity);
<S extends T> Iteratable<S> save(Iterable<S> entities);
T findOne(ID id);
boolean exists(ID id);
Iterable<T> findAll();
Iterable<T> findAll(Iterable<ID> ids);
long count();
void delete(ID id);
void delete(T entity);
void delete(iterable<? extends T> entities);
void deleteAll();
}
CrudRepository的子接口PagingAndSortingRepository定义了于分页和排序操作相关的内容:
@NoRepostoryBean
public interface PagingAndSortingRepository<T,ID extends Serializable> extends CrudRepository<T,ID>{
Iterable<T> findALL(Sort sort);
Page<T> findAll(Pageable pageable);
}
不同的数据访问技术也提供了不同的Repository,如spring data jpa 有JpaRepository,Spring Data MongoDB有MongoRepository.
spring Data项目还给我们提供了根据属性名进行计数,删除,查询方法操作,例如:
public interface PersonRepository extends Repository<Person,Long>{
//按照年龄计数
Long countByAge(Integer age);
//按照名字删除
Long deleteByName(String name);
//按照名字查询
List<Person> findByName(String name);
//按照名字和地址查询
List<Person> findByNameAndAddress(String name,String address);
}
===============================================
spring data JPA
JPA是一个基于O/R映射的标准规范。所谓规范即只定义标准规则(如注解,接口),不提供实现,软件提供商可以按照标准规范来实现,而使用者只需按照规范中定义的方式来使用,而不用和软件提供商的实现打交道。JPA的主要实现由Hibernate,EclipseLink和OpenJPA等。
1,定义数据访问层
只需定义一个继承JpaRepository的接口即可:
public interface PersonRepository extends JpaRepository<Person,Long>{
//定义数据访问层操作的方法
}
继承JpaRepository接口就相当于有了CrudRepository和PagingAndSortingRepository接口中的操作方法。
2,配置使用Spring Data JPA
通过@EnabelJpaRepository注解来开启Spring Data JPA的支持,@EabelJpaRepository接收的value参数用来扫描数据访问层所在的包下的数据访问的接口定义。
操作方法的定义
限制结果数量。结果数量是用top和first关键字来实现,例如:
publicinterface PersonRepository extends JpaRepository<Person,Long>{
//获取符合查询条件的前10条数据
List<Person> findFirst10ByName(String name);
//获取符合查询条件的前30条数据
List<Person> findTop30ByName(String name);
}
3,使用JPA的NamedQuery查询
Spring Data JPA支持用JPA的NameQuery来定义查询方法,即一个名称映射一个查询语句,如下:
@Entity
@NamedQuery(name="Person.findByName",query="select p from Person p where p.name=?1")
public class Person{}
4,使用@Query查询
使用参数的索引号来查询:
public interface PersonRepository extends JpaRepository<Person,Long>{
@Query("select p from Person p where p.address=?1")
List<Person> findByAddress(String address);
}
在Query语句中用名称来匹配查询参数:
public interface PersonRepository extends JpaRepository<Person ,Long>{
@Query("select p from Person p where p.address = :address")
List<Person> findByAddress(@Param("address") String address);
}
4,更新查询。Spring Data JPA支持@Modifying 和@Query注解组合来事件更新查询,例如:
public interface PersonRepository extends JpaRepositroy<Person ,Long>{
@Modifying
@Transactionl
@Query("update Person p set p.name=?1")
int setName(String name);//返回值int表示更新语句影响的行数
}
5,Specification
JPA提供了基于准则查询的方式,即Criteria查询。而spring Data JPA提供了一个Spexification(规范)接口让我们可以更方便地构造准则查询,specification接口定义了一个toPredicate方法来构造查询条件。
定义接口类必须实现JpaSpecificationExector接口
public interface PersonRepository extends JpaRepository<Person,Long>,JpaSpecificationExecutor<Person>{}
然后定义Criterial查询,如下:
public class HelloWorld{
public static Specification<Person> PersonFromNanChang(){
return new Specification<Person>(){
@Override
public Predicate toPredicate(Root<Person) root,CriteriaQuery<?> query,CriteriaBuilder cb){
return cb.equal(root.get("address"),"南昌");
}
};
}
}
使用Root来获取需要查询的属性,通过CriteriaBuilder构造查询条件,查出所有来自南昌是人。
CriteriaBuilder,CriteriaQuery,Root,Predicate都是来自JPA的接口。
使用:List<Perosn> person = personRepository.findAll(personFromNanChang());
6,排序和分页
Spring Data JPA 提供可Sort类以及Page接口和Pageable接口
public interface PersonRepository extends JpaRepositroy<Person,Long>{
List<Person> findByName(String name,Sort sort);
Page<Person> findByName(String name,Pageable pageable);
}
使用排序:
List<Person> person = personRepository.findByName("xx",new Sort(Direction.ASC,"age"));
使用分页:
Page<Person> person = personRepository.findByName("xx",new PageRequest(0,10));
其中Page接口可以获得当前页面的记录,总页数,总记录条数,是否有上一页或下一页等。