天天看点

Spring Data JPA: 实现自定义Repository 生活不止眼前的bug,还有诗和远方。。。

  由于项目中的 实体(entity)默认都是继承一个父类(包含一些公共的属性,比如创建时间,修改时间,是否删除,主键id)。为了实现逻辑删除,一般会自己实现RepositoryFactoryBean 和 Repository。但是由于多个团队开发的结果,表的结构没有同一,也就是会出现有的表没有基础父类对应的字段,这样就会导致自定义的jpa repository操作这些表就会出错。

  默认父类

Spring Data JPA: 实现自定义Repository 生活不止眼前的bug,还有诗和远方。。。
Spring Data JPA: 实现自定义Repository 生活不止眼前的bug,还有诗和远方。。。

View Code

  自定义Repository接口

添加BaseDao接口

BaseDao继承了JpaSpecificationExecutor、CrudRepository,这样可以保证所有Repository都有基本的增删改查以及分页等方法。

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

Spring Data JPA: 实现自定义Repository 生活不止眼前的bug,还有诗和远方。。。
Spring Data JPA: 实现自定义Repository 生活不止眼前的bug,还有诗和远方。。。

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

  实现BaseRepository

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

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

  我们发现Repository有两个构造函数:

SimpleJpaRepository(JpaEntityInformation entityInformation, EntityManager entityManager)

SimpleJpaRepository(Class domainClass, EntityManager em)

  这里我们实现第二个构造函数,拿到<code>domainClass</code>和<code>EntityManager</code>两个对象。因为我们要实现的是知道某个Repository是否支持某个领域对象的类型,因此在实现构造函数时我们将<code>domainClass</code>的信息保留下来。

Spring Data JPA: 实现自定义Repository 生活不止眼前的bug,还有诗和远方。。。
Spring Data JPA: 实现自定义Repository 生活不止眼前的bug,还有诗和远方。。。

  RepositoryFactoryBean 实现

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

Spring Data JPA: 实现自定义Repository 生活不止眼前的bug,还有诗和远方。。。
Spring Data JPA: 实现自定义Repository 生活不止眼前的bug,还有诗和远方。。。

  jpa 配置文件

  由于有的表没有默认父类AbsIdEntity对应的字段,导致生成 Repository 在操作表的时候会报错。需要修改的就是RepositoryFactoryBean的实现逻辑。对于继承了AbsIdEntity的实体类,返回自定义的BaseRepository(也就是BaseDaoImpl),否则就返回SimpleJpaRepository。注意自定义RepositoryFactoryBean的泛型也做了修改。

Spring Data JPA: 实现自定义Repository 生活不止眼前的bug,还有诗和远方。。。
Spring Data JPA: 实现自定义Repository 生活不止眼前的bug,还有诗和远方。。。

  至此,完成了适配。