为某一个 Repository 上添加自定义方法
1、定义一个接口: 声明要添加的, 并自实现的方法;
PersonDao.java
PersonDao.java1 2 3 4 5
| public interface PersonDao { void test();
}
|
2、提供该接口的实现类: 类名需在要声明的 Repository 后添加 Impl, 并实现方法;
PersonRepsotoryImpl.java
PersonRepsotoryImpl.java1 2 3 4 5 6 7 8 9 10 11
| public class PersonRepsotoryImpl implements PersonDao { @PersistenceContext private EntityManager entityManager;
@Override public void test() { Person person = entityManager.find(Person.class, 11); System.out.println("-->" + person); } }
|
3、声明 Repository 接口, 并继承自定义的接口;
PersonRepsotory.java
PersonRepsotory.java1 2 3
| public interface PersonRepsotory extends JpaRepository<Person, Integer>,PersonDao { }
|
注意:默认情况下, Spring Data 会在 base-package 中查找 “接口名Impl” 作为实现类,也可以通过 repository-impl-postfix 声明后缀,如果有两个以上类名为PersonRepsotoryImpl的类,Spring Data Jpa会抛出错误。
为所有的 Repository 都添加自实现的方法
1、声明一个接口, 在该接口中声明需要自定义的方法, 且该接口需要继承 Spring Data 的 Repository;
CommonMethod.java
CommonMethod.java1 2 3 4 5 6
| @NoRepositoryBean public interface CommonMethod<T, ID extends Serializable> extends JpaRepository<T, ID> {
void method(); }
|
2、提供所声明的接口的实现类. 且继承 SimpleJpaRepository, 并提供方法的实现;
CommonMethodImpl.java
CommonMethodImpl.java1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @NoRepositoryBean CommonMethodImpl.java public class CommonMethodImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements CommonMethod<T, ID> {
public CommonMethodImpl(Class<T> domainClass, EntityManager em) { super(domainClass, em); }
@Override public void method() { System.out.println("...METHOD TEST..."); }
}
|
3、定义 JpaRepositoryFactoryBean 的实现类, 使其生成 1) 定义的接口实现类的对象;
CommonJpaRepositoryFactoryBean.java
CommonJpaRepositoryFactoryBean.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class CommonJpaRepositoryFactoryBean <T extends Repository<S, ID>, S, ID extends Serializable> extends JpaRepositoryFactoryBean<T, S, ID> {
protected RepositoryFactorySupport createRepositoryFactory( EntityManager entityManager) { return new CommonRepositoryFactory(entityManager); }
private static class CommonRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory {
private EntityManager entityManager;
public CommonRepositoryFactory(EntityManager entityManager) { super(entityManager); this.entityManager = entityManager; }
protected Object getTargetRepository(RepositoryMetadata metadata) { return new CommonMethodImpl<T, I>( (Class<T>) metadata.getDomainType(), entityManager); }
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) { return CommonMethod.class; } } }
|
4、修改applicationContext.xml文件 <jpa:repositories/> 节点的 factory-class 属性指向CommonJpaRepositoryFactoryBean.java 的全类名;
applicationContext.xml
applicationContext.xml1 2 3 4 5 6 7 8 9
| ...
<jpa:repositories base-package="com.syshlang" entity-manager-factory-ref="entityManagerFactory" factory-class="com.syshlang.repository.common.impl.CommonJpaRepositoryFactoryBean"> </jpa:repositories>
...
|
注意:全局的扩展实现类不要用 Imp 作为后缀名, 或为全局扩展接口添加 @NoRepositoryBean 注解告知 Spring Data: Spring Data 不把其作为 Repository。