下一步我们来实现博客中用户的注册、登陆等功能,需要使用对User
的增删改查功能。为了实现这些功能,需要了解Spring Data JPA的核心概念和使用步骤。
作为Spring数据存储抽象的核心接口,Repository
是一个泛型接口,其中领域类(即业务模型类,比如博客系统中的Post
)和领域类的ID
类型作为类型参数。
Repository
是最顶层的接口,不包含任何方法,目的是为了统一所有Repository
的类型,且能让组件扫描的时候自动识别。
CrudRepository
是Repository
的子接口,这里可以看到一些常用数据库CRUD方法。
public interface CrudRepository<T, ID extends Serializable>
extends Repository<T, ID> {
// 存储实体
<S extends T> S save(S entity);
// 返回id对应的实体
T findOne(ID primaryKey);
// 返回所有实体
Iterable<T> findAll();
// 返回实体的数量
Long count();
// 删除实体
void delete(T entity);
// 判断id对应的实体是否存在
boolean exists(ID primaryKey);
// … more functionality omitted.
}
PagingAndSortingRepository
是CrudRespository
的子接口,添加了分页和排序的功能。JpaRespository
则是PagingAndSortingRepository
的子接口。
Spring Data同时还提供了对应于其他存储技术的数据访问抽象,如MongoRespository
。
基于Spring Data,进行数据库操作只需要四个步骤:
Repository
或者它的子接口,将参数类型设置为领域类及其ID
类型,比如:import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@EnableJpaRepositories
class Config {}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="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">
<jpa:repositories base-package="com.acme.repositories"/>
</beans>
在上面的例子中使用了JPA命名空间,如果使用其他的Respository
类型,比如MongoRepository
,则需要替换为对应的命名空间。
@EnableJpaRepositories
会自动扫描被标注类所在的包,如果需要设置扫描的包位置,可以设置basePackage
属性。
提示
在Spring Boot项目中,如果在POM文件中引入了spring-boot-starter-data-jpa
依赖,则无需Java配置或者XML配置。
@Component
public class SomeClient {
@Autowired
private UserRepository repository;
public void doSomething() {
List<User> users = repository.findByName("Matthews");
}
}
基于Spring Data JPA自定义存储接口,需要直接或者间接继承Repository
,并且给出领域类以及ID类型以定义泛型接口的类型参数。如果希望拥有更多方法(CRUD、排序和分页、批处理等),则可以直接继承CrudRepository
、PagingAndSortingRepository
或者JpaRepository
接口。这种方式下我们可以自动拥有操作实体的一个比较完整的方法集合。有时如果仅仅想暴露一部分方法,只需要从JpaRepository
中拷贝所需的方法到自定义接口当中即可,例如:
@NoRepositoryBean
interface MyBaseRepository<T, ID extends Serializable> extends Repository<T, ID> {
T findOne(ID id);
T save(T entity);
}
interface UserRepository extends MyBaseRepository<User, Long> {
User findByEmail(String email);
}
MyBaseRepository
暴露了findOne
和save
两个方法。UserRepository
继承了MyBaseRepository
接口,同时定义了findByEmail
方法,因此一共暴露了三个方法。
提示
@NoRepositoryBean
修饰的接口,Spring Data在运行时不会进行实例化。
CrudRepository
、PagingAndSortingRepository
和JpaRepository
的完整定义如下:
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
<S extends T> S save(S var1); //将一个对象持久化到数据库中
<S extends T> Iterable<S> save(Iterable<S> var1); //将一组对象持久化到数据库中
T findOne(ID var1); //根据id查找并返回一个对象
boolean exists(ID var1); //判断某个id是否存在
Iterable<T> findAll(); //返回所有对象
Iterable<T> findAll(Iterable<ID> var1); //根据一组id返回对应的对象
long count(); //返回共有多少条数据
void delete(ID var1); //根据id删除某个对象
void delete(T var1); //删除某个对象
void delete(Iterable<? extends T> var1); //删除某一组对象
void deleteAll(); //删除所有对象
}
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
Iterable<T> findAll(Sort var1); //根据某个排序获取所有数据
Page<T> findAll(Pageable var1); //根据分页信息获取某一页的数据
}
public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {
List<T> findAll(); //获取所有数据,以List的方式返回
List<T> findAll(Sort var1); //根据某个排序获取所有数据,以List的方式返回
List<T> findAll(Iterable<ID> var1); //根据一组id返回对应的对象,以List的方式返回
<S extends T> List<S> save(Iterable<S> var1); //将一组对象持久化到数据库中,以List的方式返回
void flush(); //将修改更新到数据库
<S extends T> S saveAndFlush(S var1); //保存数据并将修改更新到数据库
void deleteInBatch(Iterable<T> var1); //批量删除数据
void deleteAllInBatch(); //批量删除所有数据
T getOne(ID var1); //根据id查找并返回一个对象
}
登录发表评论 登录 注册