美文网首页
Spring JPA自定义Repository,以及遇到的问题

Spring JPA自定义Repository,以及遇到的问题

作者: 李逍遥JK | 来源:发表于2017-07-11 19:51 被阅读1034次

第一次在简书发文章,原来是在csdn,但是感觉csdn上的文章参差不齐,因此试试简书吧。最近两天在做新项目,用的是Spring-Boot。Dao层用的是Spring-JPA。下面就分享下做法和遇到的问题。
  先说说问题吧,在代码中我都注释了(用了注意:):

问题:1.继承JpaRepositoryFactoryBean出错。

原因:JpaRepositoryFactoryBean,因为子类的构造函数中默认的第一行有一条隐式语句super(),该语句会访问父类中的空参数构造函数,除非父类中没有空参数的构造函数,那么子类构造函数的第一行必须显式调用父类的构造函数,即super(int x,…) 。查看源码,确实父类JpaRepositoryFactoryBean确实没有空参数的构造函数

public class JpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends TransactionalRepositoryFactoryBeanSupport<T, S, ID> {
    private EntityManager entityManager;

   public JpaRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
        super(repositoryInterface);
    }

  @PersistenceContext
   public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

   public void setMappingContext(MappingContext<?, ?> mappingContext) {
        super.setMappingContext(mappingContext);
    }
   protected RepositoryFactorySupport doCreateRepositoryFactory() {
        return this.createRepositoryFactory(this.entityManager);
    }

   protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
        return new JpaRepositoryFactory(entityManager);
    }

   public void afterPropertiesSet() {
        Assert.notNull(this.entityManager, "EntityManager must not be null!");
        super.afterPropertiesSet();
    }
}

问题:2.编译时报错No property find found for type XX的问题。

(此处中的found只是的方法根据JPA规则去掉excute之后的关键词,比如你的方法名是excuteUpadte,则此处是find update)。百度下,发现网上的解决办法有很多,比如:修改Spring的validator,然后clean project再编译。试过没有用。在一本书上获得了解决办法:在入口类上加上注解 java @EnableJpaRepositories(repositoryFactoryBeanClass = CustomRepositoryFactoryBean.class)
具体如下:

@EnableJpaRepositories(repositoryFactoryBeanClass = CustomRepositoryFactoryBean.class)
@SpringBootApplication
public class SyngisMapApplication {

 //1.首先,定义自己的Repository类实现Repository借口:
/*
 * 定义自定义Repository接口
 * Created by Tomas on 2017/7/11.
 */
//@NoRepositoryBean指明当前接口不是我们领域类的接口(如PersonRepository)
@NoRepositoryBean
public interface CustomRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {//注释:1

   //简单的定义了一些除了curd之外的方法
    public void store(Object... item);
    public void update(Object... item);
    public int executeUpdate(String qlString, Object... values);
    public int executeUpdate(String qlString, Map<String, Object> params);
    public int executeUpdate(String qlString, List<Object> values);
}

1.我们自定义的接口实现PagingAndSortingRepository接口,使自定义具有分页功能
2.定义接口实现

/*
 * Created by Tomas on 2017/7/11.
 */
public class CustomRepositoryImpl <T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements CustomRepository<T, ID> {//注解:1


    private final EntityManager entityManager = null;</br>

    //让数据操作方法中可以使用entityManager
    //CustomRepositoryImpl构造函数,需要当前处理的领域模型和entitymanager作为构造函数参数
    public CustomRepositoryImpl(Class<T> domainClass, EntityManager entityManager){
        super(domainClass, entityManager);
    }

    //下面是一些数据操作方法
    @Override
    public void store(Object... item) {

    }

    @Override
    public void update(Object... item) {

    }

    @Override
    public int executeUpdate(String qlString, Object... values) {
        return 0;
    }

    @Override
    public int executeUpdate(String qlString, Map<String, Object> params) {
        return 0;
    }

    @Override
    public int executeUpdate(String qlString, List<Object> values) {
        return 0;
    }
}

注解
1.首先要实现CustomRepository接口,继承SimpleJpaRepository让我们可以使用其提供的方法
2.自定义RepositoryFactoryBean。自定义JpaRepositoryFactoryBean替代默认的RepositoryFactoryBean,我们会获得一个RepositoryFactory,它会注册我们自定义Repository的实现。

package com.wlw.dao;
RepositoryFactoryBean<T, S, ID> {

    //重写createRepositoryFactory方法,用当前的CustomRepositoryFactory创建实例
    @Override
    protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
        return new CustomRepositoryFactory (entityManager);
    }
    //创建CustomRepositoryFactory,并继承 JpaRepositoryFactory
    private static class CustomRepositoryFactory extends JpaRepositoryFactory{

        //参见问题1
        //注意:这里一定要写CustomRepositoryFactoryBean的构造函数,否则会报错。
        public CustomRepositoryFactory (EntityManager entityManager){
            super(entityManager);
        }
        //重写getTargetRepository方法并且获得当前自定义的Repository实现
        @Override
        protected <T, ID extends Serializable>SimpleJpaRepository<?, ?> getTargetRepository(RepositoryInformation information, EntityManager entityManager){
            return new CustomRepositoryImpl<T, ID>((Class<T>)information.getDomainType(), entityManager);
        }
      
        //重写getRepositoryBaseClas方法并且获得当前自定义的Repository的实现类型
        @Override
        protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata){
            return CustomRepositoryImpl.class;
        }
    }
}

4.使用时,我们只需要实现自定义的CustomRepository接口就能使用自定义的查询方法

/*
 * 查询RecArea数据Dao层借口
 * Created by Tomas on 2017/7/11.
 */
@Repository
public interface QueryRecAreaDao extends CustomRepository<SysUser,String>{
}

5.最后一定要注意CustomRepository和CustomRepositoryImpl的命名规则;今天先写到这,明天继续。。。
继续昨天的:
今天主要有几个问题,都是有关SpringBootJpa

相关文章

网友评论

      本文标题:Spring JPA自定义Repository,以及遇到的问题

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