组态
您必须在spring bean配置文件中添加以下配置。 您必须指定一个新的存储库工厂类。 我们将在以后开发课程。
<jpa:repositories base-package='example.borislam.dao'
factory-class='example.borislam.data.springData.DefaultRepositoryFactoryBean/>
只需开发一个扩展JpaRepository的接口即可。 您应该记得用@NoRepositoryBean对其进行注释。
@NoRepositoryBean
public interface GenericRepository <T, ID extends Serializable>
extends JpaRepository<T, ID> {
}
定义自定义存储库基础实现类
下一步是开发定制的基础存储库类。 您可以看到我只是这个自定义基础存储库中的一个属性(即springDataRepositoryInterface)。 我只想对存储库接口的自定义行为的行为进行更多控制。 在下一篇文章中,我将展示如何添加此基础存储库类的更多功能。
@SuppressWarnings('unchecked')
@NoRepositoryBean
public class GenericRepositoryImpl<T, ID extends Serializable>
extends SimpleJpaRepository<T, ID> implements GenericRepository<T, ID> , Serializable{
private static final long serialVersionUID = 1L;
static Logger logger = Logger.getLogger(GenericRepositoryImpl.class);
private final JpaEntityInformation<T, ?> entityInformation;
private final EntityManager em;
private final DefaultPersistenceProvider provider;
private Class<?> springDataRepositoryInterface;
public Class<?> getSpringDataRepositoryInterface() {
return springDataRepositoryInterface;
}
public void setSpringDataRepositoryInterface(
Class<?> springDataRepositoryInterface) {
this.springDataRepositoryInterface = springDataRepositoryInterface;
}
/**
* Creates a new {@link SimpleJpaRepository} to manage objects of the given
* {@link JpaEntityInformation}.
*
* @param entityInformation
* @param entityManager
*/
public GenericRepositoryImpl (JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager , Class<?> springDataRepositoryInterface) {
super(entityInformation, entityManager);
this.entityInformation = entityInformation;
this.em = entityManager;
this.provider = DefaultPersistenceProvider.fromEntityManager(entityManager);
this.springDataRepositoryInterface = springDataRepositoryInterface;
}
/**
* Creates a new {@link SimpleJpaRepository} to manage objects of the given
* domain type.
*
* @param domainClass
* @param em
*/
public GenericRepositoryImpl(Class<T> domainClass, EntityManager em) {
this(JpaEntityInformationSupport.getMetadata(domainClass, em), em, null);
}
public <S extends T> S save(S entity)
{
if (this.entityInformation.isNew(entity)) {
this.em.persist(entity);
flush();
return entity;
}
entity = this.em.merge(entity);
flush();
return entity;
}
public T saveWithoutFlush(T entity)
{
return
super.save(entity);
}
public List<T> saveWithoutFlush(Iterable<? extends T> entities)
{
List<T> result = new ArrayList<T>();
if (entities == null) {
return result;
}
for (T entity : entities) {
result.add(saveWithoutFlush(entity));
}
return result;
}
}
作为一个简单的示例,我只是覆盖了SimpleJPARepository的默认保存方法。 持久保存后,save方法的默认行为不会刷新。 我进行了修改,以使其在持久化后保持刷新状态。 另一方面,我添加了另一个名为saveWithoutFlush()的方法,以允许开发人员调用保存实体而无需刷新。
定义自定义存储库工厂bean
最后一步是创建一个工厂bean类和一个工厂类,以根据您自定义的基本存储库类来生成存储库。
public class DefaultRepositoryFactoryBean <T extends JpaRepository<S, ID>, S, ID extends Serializable>
extends JpaRepositoryFactoryBean<T, S, ID> {
/**
* Returns a {@link RepositoryFactorySupport}.
*
* @param entityManager
* @return
*/
protected RepositoryFactorySupport createRepositoryFactory(
EntityManager entityManager) {
return new DefaultRepositoryFactory(entityManager);
}
}
/**
*
* The purpose of this class is to override the default behaviour of the spring JpaRepositoryFactory class.
* It will produce a GenericRepositoryImpl object instead of SimpleJpaRepository.
*
*/
public class DefaultRepositoryFactory extends JpaRepositoryFactory{
private final EntityManager entityManager;
private final QueryExtractor extractor;
public DefaultRepositoryFactory(EntityManager entityManager) {
super(entityManager);
Assert.notNull(entityManager);
this.entityManager = entityManager;
this.extractor = DefaultPersistenceProvider.fromEntityManager(entityManager);
}
@SuppressWarnings({ 'unchecked', 'rawtypes' })
protected <T, ID extends Serializable> JpaRepository<?, ?> getTargetRepository(
RepositoryMetadata metadata, EntityManager entityManager) {
Class<?> repositoryInterface = metadata.getRepositoryInterface();
JpaEntityInformation<?, Serializable> entityInformation =
getEntityInformation(metadata.getDomainType());
if (isQueryDslExecutor(repositoryInterface)) {
return new QueryDslJpaRepository(entityInformation, entityManager);
} else {
return new GenericRepositoryImpl(entityInformation, entityManager, repositoryInterface); //custom implementation
}
}
@Override
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
if (isQueryDslExecutor(metadata.getRepositoryInterface())) {
return QueryDslJpaRepository.class;
} else {
return GenericRepositoryImpl.class;
}
}
/**
* Returns whether the given repository interface requires a QueryDsl
* specific implementation to be chosen.
*
* @param repositoryInterface
* @return
*/
private boolean isQueryDslExecutor(Class<?> repositoryInterface) {
return QUERY_DSL_PRESENT
&& QueryDslPredicateExecutor.class
.isAssignableFrom(repositoryInterface);
}
}
结论
现在,您可以向基础存储库类添加更多功能。 在您的程序中,您现在可以创建自己的存储库接口,以扩展GenericRepository而不是JpaRepository。
public interface MyRepository <T, ID extends Serializable>
extends GenericRepository <T, ID> {
void someCustomMethod(ID id);
}
在下一篇文章中,我将向您展示如何向此GenericRepository添加休眠过滤器功能。
参考: “ 编程和平”博客上的JCG合作伙伴 Boris Lam 自定义Spring Data JPA存储库 。
翻译自: https://www.javacodegeeks.com/2012/08/customizing-spring-data-jpa-repository.html