spring 如何获取特定的EntityManager?

ddrv8njm  于 2022-10-30  发布在  Spring
关注(0)|答案(1)|浏览(115)

我有一个实体有~70个变量。我想做一些自定义查询搜索过滤,使用不同的组合,而不必创建10 000个查找方法,然后应用一些逻辑来选择正确的一个使用。

@PersistenceContext
EntityManager entityManager;

private CriteriaBuilder criteriaBuilder;

public PageImpl<TClaimModel> findAllWithFilters(TClaimModelSearchCriteria filters){
    if (criteriaBuilder == null) criteriaBuilder = entityManager.getCriteriaBuilder();
    CriteriaQuery<TClaimModel> criteriaQuery = criteriaBuilder.createQuery(TClaimModel.class);
    Root<TClaimModel> claimRoot = criteriaQuery.from(TClaimModel.class);
    Predicate predicate = getPredicate(filters, claimRoot);
    criteriaQuery.where(predicate);

    if(filters.getSortDirection().equals(Sort.Direction.ASC)) 
        criteriaQuery.orderBy(criteriaBuilder.asc(claimRoot.get(filters.getSort())));
    else
        criteriaQuery.orderBy(criteriaBuilder.desc(claimRoot.get(filters.getSort())));

    TypedQuery<TClaimModel> typedQuery = entityManager.createQuery(criteriaQuery);
    typedQuery.setFirstResult(filters.getPage() * filters.getPageSize());
    typedQuery.setMaxResults(filters.getPageSize());
    long claimsCount = getClaimsCount(predicate);

    return new PageImpl<>(typedQuery.getResultList(), filters.getPageable(), claimsCount);
}

private Predicate getPredicate(TClaimModelSearchCriteria filters, Root<TClaimModel> claimRoot) {
    List<Predicate> predicates = new ArrayList<>();
    if (Objects.nonNull(filters.getClaimNum()))
        predicates.add(criteriaBuilder.like(claimRoot.get("claimNum"), "%" + filters.getClaimNum() + "%"));
    if (Objects.nonNull(filters.getClaimDate()))
        predicates.add(criteriaBuilder.equal(claimRoot.get("claimDate"), filters.getClaimDate()));
    if (Objects.nonNull(filters.getStartSearchDate())) {
        if (Objects.nonNull(filters.getEndSearchDate()))
            predicates.add(criteriaBuilder.between(claimRoot.get("claimDate"), filters.getStartSearchDate(), filters.getEndSearchDate()));
        else
            predicates.add(criteriaBuilder.greaterThanOrEqualTo(claimRoot.get("claimDate"), filters.getStartSearchDate()));
    } else if (Objects.nonNull(filters.getEndSearchDate()))
        predicates.add(criteriaBuilder.lessThanOrEqualTo(claimRoot.get("claimDate"), filters.getEndSearchDate()));
    // repeat for each possible filter;
    return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
}

private long getClaimsCount(Predicate predicate) {
    CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class);
    Root<TClaimModel> countRoot = countQuery.from(TClaimModel.class);
    countQuery.select(criteriaBuilder.count(countRoot)).where(predicate);
    return entityManager.createQuery(countQuery).getSingleResult();
}

到目前为止,这是我的过滤代码,但是我得到一个错误“不是实体:在阅读到这个错误后,我发现我不能使用@PersistenceContext来获取实体管理器。那么,我该如何获取实体管理器呢?我可以自动连接一个实体管理器工厂,但它没有createQuery方法。
编辑:这个项目使用了2个数据库。在EntityManager上使用@Autowire也不起作用,因为我得到:
com.activiti.repository.alfresco.TClaimCriteriaRepository中的字段实体管理器需要一个bean,但找到了2个:共享实体管理器创建者#0:由null中的方法“创建共享实体管理器”定义- org.springframework.orm.jpa.SharedEntityManagerCreator#1:由方法“createSharedEntityManager”定义,为空

yruzcnhs

yruzcnhs1#

作为一种解决方法,我手动构建了请求...

@Autowired
protected DataSourceService dataSourceService;

public Map<String, Object> findAllWithFilters(TClaimModelSearchCriteria filters){

    Map<String, Object> response = new HashMap<>();
    try {
        List<DataSource> dataSources = dataSourceService.getDataSourcesForTenant(SecurityUtils.getCurrentUserObject().getTenantId());
        CommonJdbcTemplate commonJdbcTemplate = new CommonJdbcTemplate();
        if (dataSources.size() > 0) {
            JdbcTemplate jdbcTemplate = commonJdbcTemplate.getJdbcTemplate(dataSources.get(0));
            String sql = buildRequestSql(filters);
            List<Map<String, Object>> data = jdbcTemplate.queryForList(sql);
            String counter = buildCountRequestSql(filters);
            Long count = (Long) jdbcTemplate.queryForList(counter).get(0).get("count");
            response.put("total", count);
            response.put("data", data);
            return response;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

private String buildRequestSql(TClaimModelSearchCriteria filters) {
    StringBuilder sql = new StringBuilder();
    sql.append("select * from t_claim");
    getWhere(sql, filters);
    sql.append(" order by " + filters.getSort());
    if (filters.getSortDirection() == Sort.Direction.DESC)
        sql.append(" desc");
    if (filters.getPage() != 0) {
        sql.append(" offset " + filters.getPage() * filters.getPageSize());
    }
    sql.append(" fetch first " + filters.getPageSize() + " row only");
    return sql.toString();
}

private String buildCountRequestSql(TClaimModelSearchCriteria filters) {
    StringBuilder sql = new StringBuilder();
    sql.append("select count(*) from t_claim");
    getWhere(sql, filters);
    return sql.toString();
}

...

但我还是想知道正确的方法:P

相关问题