我能够通过实现Custom Repositories,在该实现类中自动连接EntityManager,然后根据传递的参数构建最终的JPQL 来实现这一点。 Eugen 的blog 就是一个很好的例子。
以前我有以下结构
public interface EntityARepository extends JpaRepository<EntityA, Long> {
@Query(...)
List<EntityA> findAllBy(Date filterDate, Long amount, String name, Long projectId, Long divisionId);
}
public interface EntityAService {
List<Object[]> findAllBy(Date filterDate, Long amount, String name, Long projectId, Long divisionId);
}
@Service
public class EntityAServiceImpl implements EntityAService {
@Autowired
EntityARepository entityARepository;
@Override
public List<Object[]> findAllBy(Date filterDate, Long amount, String name, Long projectId, Long divisionId) {
...
...
...
}
}
通过使用自定义存储库,一切都变得像
public interface EntityACustomRepository {
List<Object[]> findAllBy(Date filterDate, Long amount, String name, Long projectId, Long divisionId);
}
public interface EntityARepository extends JpaRepository<EntityA, Long> {
//@Query(...)
//List<EntityA> findAllBy(Date filterDate, Long amount, String name, Long projectId, Long divisionId);
}
@Repository
public class EntityACustomRepositoryImpl implements EntityACustomRepository {
// autowiring entityManager helped to create and execute dynamic jpql
@Autowired
EntityManager entityManager;
public List<Object[]> findAllBy(Date filterDate, Long amount, String name, Long projectId, Long divisionId) {
String jpql = "SELECT " +
" ef, ed, ea " +
" FROM EntityA ea " +
" JOIN EntityB eb " +
" JOIN EntityC ec " +
" JOIN EntityD ed " +
" JOIN EntityE ee " +
" JOIN EntityF ef " +
" WHERE " +
" TRUNC(ee.date) = TRUNC(:date) "
;
//conditions based on screen filter parameters
if(amount!=null && amount>0L) {
jpql += " AND ef.amount = :amount ";
}
if(name!=null && name.trim().length()>0) {
jpql += " AND LOWER(ec.name) LIKE LOWER('%' || :name || '%') ";
}
if(projectId!=null && projectId>0L) {
jpql += " AND ec.projectId = :projectId ";
}
if(divisionId!=null && divisionId>0L) {
jpql += " AND ed.divisionId = :divisionId ";
}
Query query = entityManager.createQuery(jpql);
query.setParameter("date", filterDate);
if(amount!=null && amount>0L) {
query.setParameter("amount", amount);
}
if(name!=null && name.trim().length()>0) {
query.setParameter("name", name);
}
if(projectId!=null && projectId>0L) {
query.setParameter("projectId", projectId);
}
if(divisionId!=null && divisionId>0L) {
query.setParameter("divisionId", divisionId);
}
return query.getResultList();
}
}
public interface EntityAService {
List<Object[]> findAllBy(Date filterDate, Long amount, String name, Long projectId, Long divisionId);
}
@Service
public class EntityAServiceImpl implements EntityAService {
@Autowired
EntityARepository entityARepository;
@Override
public List<Object[]> findAllBy(Date filterDate, Long amount, String name, Long projectId, Long divisionId) {
return entityARepository.findAllBy(filterDate, amount, name, projectId, divisionId);
}
}