第一次在简书发文章,原来是在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
网友评论