JPA我爱编程

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

2018-04-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添加了自定义的方法。

上一篇下一篇

猜你喜欢

热点阅读