Sha*_*ali 9 java spring jpa spring-data-jpa spring-boot
以下是扩展Spring PagingAndSortingRepository的示例Generic Repository实现,
@NoRepositoryBean
public interface GenericRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {
public List<T> findByNamedQuery( String name );
public List<T> findByNamedQueryAndParams( String name, Map<String, Object> params );
public T findOneByNamedQuery( String name );
public T findOneByNamedQueryAndParams( String name, Map<String, Object> params );
Run Code Online (Sandbox Code Playgroud)
}
工厂Bean类,
public class GenericRepositoryFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable> extends
JpaRepositoryFactoryBean<R, T, I> {
@SuppressWarnings( "rawtypes" )
protected RepositoryFactorySupport createRepositoryFactory( EntityManager em )
{
return new MyRepositoryFactory(em);
}
private static class MyRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory {
private final EntityManager em;
public MyRepositoryFactory( EntityManager em )
{
super(em);
this.em = em;
}
@SuppressWarnings( "unchecked" )
protected Object getTargetRepository( RepositoryMetadata metadata )
{
return new GenericRepositoryImpl<T, I>((Class<T>) metadata.getDomainType(), em);
}
protected Class<?> getRepositoryBaseClass( RepositoryMetadata metadata )
{
return GenericRepositoryImpl.class;
}
}
}
Run Code Online (Sandbox Code Playgroud)
实施班,
public final class GenericRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements
GenericRepository<T, ID> {
private final EntityManager em;
private final Class<T> domainClass;
public GenericRepositoryImpl( Class<T> domainClass, EntityManager entityManager )
{
super(domainClass, entityManager);
this.em = entityManager;
this.domainClass = domainClass;
}
@Override
public List<T> findByNamedQuery( final String name )
{
validate(name);
return this.em.createNamedQuery(name, domainClass).getResultList();
}
@Override
public T findOneByNamedQuery( String name )
{
validate(name);
return this.em.createNamedQuery(name, domainClass).getSingleResult();
}
@Override
public List<T> findByNamedQueryAndParams( String name, Map<String, Object> params )
{
validate(name, params);
final TypedQuery<T> query = this.em.createQuery(name, domainClass);
setParams(query, params);
return query.getResultList();
}
}
Run Code Online (Sandbox Code Playgroud)
因此,当我尝试将GenericRepository Autowire转换为不同类型的服务(如Customer.java,Message.java等)时,它需要至少一种bean类型的接口GenericRepository.如果我为客户和消息类型创建单独的存储库,这都有效.没有创建多个存储库,我无法实现这一点.
@Service
@Transactional( noRollbackFor = Exception.class )
public class CustomerService {
@Autowired
private GenericRepository<Customer, Serializable> cr; works fine with just one entity type
@Autowired
private GenericRepository<Message, Serializable> cr; throws exception
Run Code Online (Sandbox Code Playgroud)
如果有100个或更多实体类,那么我最终会创建100个存储库,这很糟糕.如果有更好的方法,请告诉我.
对于我所读到的内容,通过 @Query 注释告诉新的接口方法要做什么会更容易,并且不用为 BeanFactory 或 impl 烦恼。
@Repository
public interface GenericRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
@Query(value = "SELECT c FROM customers c WHERE c.name = :name")
public List<T> findByNamedQuery( String name );
...
}
Run Code Online (Sandbox Code Playgroud)
如果这不适用于您,并且您说您的代码适用于一个存储库,但在添加第二个存储库时失败,我的第一个想法是尝试将 bean 的范围设置为原型,但这只是一种猜测。如果我没有真正帮到你,我很抱歉,不要太恨我^^
| 归档时间: |
|
| 查看次数: |
6777 次 |
| 最近记录: |