SpringBoot使用JPA自定义Query多表动态查询

PageCount.java (分页构建)

public class PageCount<T> {
    private final int page; //当前页
    private final int size; //页大小
    private long total; //总记录数
    private List<?> data; //数据
    private final Class<T> tClass; //查询的类

    public PageCount(int page, int size, Class<T> tClass) {
        this.page = page;
        this.size = size;
        this.tClass = tClass;
    }

    @JsonIgnore
    public Class<T> getTClass() {
        return tClass;
    }

    //获取当前页首条记录下标
    public int first() {
        return (page - 1) * size;
    }

    //获取当前页末条记录下标
    public int max() {
        return page * size;
    }

    // Getter... Data和Total的Setter...
}

CountExecutor.java (异步执行count语句)

@Component
public class CountExecutor {

    @Async
    public CompletableFuture<Long> count(TypedQuery<Long> query){
       return CompletableFuture.completedFuture(query.getSingleResult());
    }

}

QueryExecutor.java (执行查询并封装分页数据)

@Component
public class QueryExecutor {
    @PersistenceContext
    private EntityManager entityManager;
    private CountExecutor countExecutor;

    @Autowired
    public void setCountExecutor(CountExecutor countExecutor) {
        this.countExecutor = countExecutor;
    }

    /**
     * @param hql     查询语句
     * @param params  查询条件 key是字段 value是字段的值
     * @return
     */
    public <T> PageCount<T> queryPage(PageCount<T> pageCount, String hql, Map<String, Object> params) {
        String countHql = "select count(1)" + hql.substring(hql.indexOf(" from "));
        TypedQuery<?> query = entityManager.createQuery(hql, pageCount.getTClass())
                .setFirstResult(pageCount.first()).setMaxResults(pageCount.max());
        TypedQuery<Long> countQuery = entityManager.createQuery(countHql, Long.class);
        params.forEach((k, v) -> {
            query.setParameter(k, v);
            countQuery.setParameter(k, v);
        });
        try {
            pageCount.setTotal(countExecutor.count(countQuery).get());
        } catch (Exception e) {
            e.printStackTrace();
        }
        pageCount.setData(query.getResultList());
        return pageCount;
    }

}

查询用的相关实体类与这篇文章一致

StorageService.java (service层构建查询语句)

@Service
public class StorageService {
    private QueryExecutor queryExecutor;
    @Autowired
    public void setQueryExecutor(QueryExecutor queryExecutor) {
        this.queryExecutor = queryExecutor;
    }

    public PageCount<StFileVo> testQuery(PageCount<StFileVo> pageCount, String dirName,Integer fileUpdateYear){
        Map<String,Object> params = new HashMap<>();
        String hql = "select new com.example.jpademo.result.StFileVo(a.fileName,a.fileUpdateTime,b.dirName,b.dirDeep,c.pathNode,c.pathValue) from " +
                "StorageFile a inner join StorageDir b on a.dirId=b.dirId inner join StoragePath c on a.pathId=c.pathId where 1=1 ";
        if (StringUtils.hasText(dirName)){
            hql += "and b.dirName=:dirName ";
            params.put("dirName",dirName);
        }
        if (fileUpdateYear != null){
            hql += "and year(a.fileUpdateTime)=:fileUpdateYear ";
            params.put("fileUpdateYear",fileUpdateYear);
        }
        return queryExecutor.queryPage(pageCount,hql,params);
    }

}
@RestController
@RequestMapping("/test")
public class StorageController {
    private StorageService storageService;
    @Autowired
    public void setStorageService(StorageService storageService) {
        this.storageService = storageService;
    }

    @RequestMapping("/test")
    public PageCount<StFileVo> test() {
        return storageService.testQuery(new PageCount<>(1, 10, StFileVo.class),"测试目录",2021);
    }
}

测试结果

控制台打印的count语句↓↓↓↓
SpringBoot使用JPA自定义Query多表动态查询
控制打印的查询语句↓↓↓↓
SpringBoot使用JPA自定义Query多表动态查询

上一篇:【Python】函数


下一篇:使用element 在线预览pdf