конфигурация
Вы должны добавить следующую конфигурацию в файл конфигурации Spring Beans. Вы должны указать новый класс фабрики хранилища. Мы разработаем класс позже.
| 
 1 
2 
 | 
<jpa:repositories base-package='example.borislam.dao'factory-class='example.borislam.data.springData.DefaultRepositoryFactoryBean/> | 
Просто разработайте интерфейс, расширяющий JpaRepository. Вы должны помнить, чтобы аннотировать это с @NoRepositoryBean.
| 
 1 
2 
3 
4 
 | 
@NoRepositoryBeanpublic interface GenericRepository <T, ID extends Serializable>  extends JpaRepository<T, ID> {    } | 
Определить пользовательский базовый класс реализации репозитория
Следующим шагом является разработка настроенного базового класса репозитория. Вы можете видеть, что у меня есть только одно свойство (т.е. springDataRepositoryInterface) внутри этого настраиваемого базового репозитория. Я просто хочу получить больше контроля над поведением настраиваемого поведения интерфейса репозитория. Я покажу, как добавить больше возможностей этого базового класса репозитория в следующем посте.
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
 | 
@SuppressWarnings('unchecked')@NoRepositoryBeanpublic 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. Поведение по умолчанию метода сохранения не сбрасывается после сохранения. Я изменил, чтобы сделать его флеш после сохранения. С другой стороны, я добавляю еще один метод с именем saveWithoutFlush (), чтобы позволить разработчику вызывать сохранение объекта без сброса.
Определить пользовательский репозиторий фабричного компонента
Последний шаг — создание класса фабричного компонента и класса фабрики для создания хранилища на основе настроенного вами базового класса хранилища.
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
 | 
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.
| 
 1 
2 
3 
4 
 | 
public interface MyRepository <T, ID extends Serializable>  extends GenericRepository <T, ID> {   void someCustomMethod(ID id);  } | 
В следующем посте я покажу вам, как добавить функции фильтра гибернации в этот GenericRepository.
Ссылка: Настройка репозитория Spring Data JPA от нашего партнера JCG Бориса Лама в блоге Programming Peaceful .