美文网首页JPA我爱编程
Spring Data JPA: 如何实现自定义方法

Spring Data JPA: 如何实现自定义方法

作者: 人要不怕开水烫 | 来源:发表于2018-04-15 18:15 被阅读240次

    Spring Data JPA中通过Repository接口自动实现了基本的ORM层操作,但在很多时候,仅仅基本的方法是不够的。经过对比网上的方法及源码,实现了Repository添加自定义方法的办法。

    首先我们来添加一个自定义的接口:

    添加BaseRepository接口

    BaseRepository继承了JpaRepository、JpaSpecificationExecutor,这样可以保证所有Repository都有基本的增删改查以及条件查询等方法。

    在BaseRepository上添加@NoRepositoryBean标注,这样Spring Data Jpa在启动时就不会去实例化BaseRepository这个接口

    添加logicDelete(ID id);方法,表示该Repository的逻辑删除功能

    @NoRepositoryBean

    public interface BaseRepository <T, ID extends Serializable> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T>

    {

        T logicDelete(ID id);

    }

    然后,使所有Repository接口都继承BaseRepository

    实现BaseRepository接口

    定义好自定义的方法后,我们现在通过一个基本的Repository类来实现该方法:

    首先添加BaseRepositoryImpl类,继承SimpleJpaRepository类,使其拥有Jpa Repository的基本方法。

    再实现logicDelete方法,其参数是领域对象的类型,将其和domainClass对比,如果相等,则该Repository支持该类型的领域对象:

    public class BaseRepositoryImpl<T, ID extends Serializable> 

        extends SimpleJpaRepository<T, ID>

        implements BaseRepository<T, ID> {

    public BaseRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {

        super(entityInformation, entityManager);

    }

    public BaseRepositoryImpl(Class<T> domainClass, EntityManager em) {

        this(JpaEntityInformationSupport.getEntityInformation(domainClass, em), em);

    }

    private void setDeleteStatus(T entity) {

            setStatus(entity, Dictionary.BUSINESS_STATUS_DELETE);

    }

    @Override

    @Transactional(rollbackFor = Throwable.class)

    public T logicDelete(ID id) {

            T entity = findOne(id);

            setDeleteStatus(entity);

            return save(entity);

    }

    }

    创建自定义RepositoryFactoryBean

    接下来我们来创建一个自定义的RepositoryFactoryBean来代替默认的RepositoryFactoryBean。RepositoryFactoryBean负责返回一个RepositoryFactory,Spring Data Jpa 将使用RepositoryFactory来创建Repository具体实现,这里我们用BaseRepositoryImpl代替SimpleJpaRepository作为Repository接口的实现。这样我们就能够达到为所有Repository添加自定义方法的目的。

    public class BaseRepositoryFactoryBean, T, I extends Serializable>

        extends JpaRepositoryFactoryBean {

        @Override

        protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) {

            return new MyRepositoryFactory(em);

        }

        private static class MyRepositoryFactory extends JpaRepositoryFactory {

            private final EntityManager em;

            public MyRepositoryFactory(EntityManager em) {

                super(em);

                this.em = em;

            }

            @Override

            protected Object getTargetRepository(RepositoryInformation information) {

                return new BaseRepositoryImpl((Class) information.getDomainType(), em);

            }

            @Override

            protected Class getRepositoryBaseClass(RepositoryMetadata metadata) {

                return BaseRepositoryImpl.class;

            }

        }

    }

    配置Jpa factory class

    最后,我们需要配置Jpa使用我们自定义的BaseRepositoryFactoryBean。Spring支持使用标注进行配置,我们在com.xxx.Application中添加标注@EnableJpaRepositories,repositoryFactoryBeanClass指定Repository的工厂类, basePackages用于配置扫描Repositories所在的package及子package:

    @SpringBootApplication

    @EnableJpaRepositories(repositoryFactoryBeanClass = BaseRepositoryFactoryBean.class, basePackages ="com.xxx.xxx.repository")

    @EnableTransactionManagement

    public class Application {

        public static void main( String[] args ){

            SpringApplication.run(Application.class, args);

        }

    }

    这样我们就为所有Repository添加了自定义的方法。

    相关文章

      网友评论

        本文标题:Spring Data JPA: 如何实现自定义方法

        本文链接:https://www.haomeiwen.com/subject/shuxkxtx.html