SpringData组件之自定义Repository方法

为某一个 Repository 上添加自定义方法

1、定义一个接口: 声明要添加的, 并自实现的方法;

PersonDao.java

PersonDao.java
1
2
3
4
5
public interface PersonDao {
//自定义方法
void test();

}

2、提供该接口的实现类: 类名需在要声明的 Repository 后添加 Impl, 并实现方法;

PersonRepsotoryImpl.java

PersonRepsotoryImpl.java
1
2
3
4
5
6
7
8
9
10
11
//规约:命名必须符合声明使用的 Repsotory 接口名 +  Impl
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.java
1
2
3
public interface PersonRepsotory extends
JpaRepository<Person, Integer>,PersonDao {
}

Repository 上添加自定义方法

注意:默认情况下, Spring Data 会在 base-package 中查找 “接口名Impl” 作为实现类,也可以通过 repository-impl-postfix 声明后缀,如果有两个以上类名为PersonRepsotoryImpl的类,Spring Data Jpa会抛出错误。


为所有的 Repository 都添加自实现的方法

1、声明一个接口, 在该接口中声明需要自定义的方法, 且该接口需要继承 Spring Data 的 Repository;

CommonMethod.java

CommonMethod.java
1
2
3
4
5
6
@NoRepositoryBean
public interface CommonMethod<T, ID extends Serializable>
extends JpaRepository<T, ID> {

void method();
}

2、提供所声明的接口的实现类. 且继承 SimpleJpaRepository, 并提供方法的实现;

CommonMethodImpl.java

CommonMethodImpl.java
1
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.java
1
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.xml
1
2
3
4
5
6
7
8
9
...

<!-- base-package: 扫描 Repository Bean 所在的 package -->
<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。