首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Spring中的JPA规范获取要执行的查询

问使用Spring中的JPA规范获取要执行的查询
EN

Stack Overflow用户
提问于 2019-06-18 21:43:52
回答 1查看 1.2K关注 0票数 1

我有一个spring项目,需要将查询结果集导出到excel工作表中。目前,我使用JPA repository从数据库中获取数据,并使用Apache POI库从这些数据中准备excel工作表。

代码语言:javascript
复制
// Get data from DB using jpaRepository
Page<MyPOJO> data = myPOJOJpaRepository.findAll(specifications, pageRequest);

// Prepare Excel Sheet from the data object using POI libraries

现在,问题是以Java POJO的形式获取数据花费了太多的时间(几乎60秒),并且使用POI库准备excel工作表也花费了大约60秒。

当我尝试使用结果集(而不是java POJO)导出csv文件时,它在10秒内完成。

代码语言:javascript
复制
 ResultSet resultSet = statement.executeQuery("select * from table where some_filters");
 File file = writeResultsToCSVFile(resultSet);

我使用JPA specifications在当前架构中构建查询。有没有办法获得将要执行的查询,这样我就可以直接获得结果集(而不是POJO)并准备csv文件。

代码语言:javascript
复制
// I'm looking for something like follows:
ResultSet resultSet = statement.executeQuery(specifications.getQuery());
File file = writeResultsToCSVFile(resultSet);

有什么办法可以实现这样的事情吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-25 23:16:49

这有点棘手,因为您可以获得如下所示的非标准查询:

代码语言:javascript
复制
select generatedAlias0 from Pets as generatedAlias0 where generatedAlias0.pet_name=:param0

你必须获得查询,然后你需要操作一些东西,比如请求字段和绑定参数(管理它们的类型。请注意,在本例中,我只管理字符串类型)。

所以假设你在使用Hibernate,你可以这样做:

代码语言:javascript
复制
/**
 *
 */
public static Specification<Pets> findByCriteria() {

    return new Specification<Pets>() {

        @Override
        public Predicate toPredicate(Root<Pets> root, CriteriaQuery<?> query, CriteriaBuilder cb) {

            List<Predicate> predicates = new ArrayList<Predicate>();

            // solo attivita attive
            predicates.add(cb.equal(root.get("pet_name"), "Chelsea"));

            return cb.and(predicates.toArray(new Predicate[]{}));
        }
    };
}

/**
 * TODO MANAGE VARIOUS TYPES
 */
private String createParam(Parameter<?> p, Query<?> q) {

    Class<?> clz = p.getParameterType();
    if (clz == String.class) {
        return "'" + q.getParameterValue(p.getName()) + "'";
    }
    return "";
}


/**
 *
 */
public void getEnterprisesAdmin() {

    Specification<Pets> spec = this.findByCriteria();

    CriteriaBuilder builder = this.em.getCriteriaBuilder();
    CriteriaQuery<Pets> query = builder.createQuery(Pets.class);

    Root<Pets> root = query.from(Pets.class);

    Predicate predicate = spec.toPredicate(root, query, builder);
    query.where(predicate);

    TypedQuery<Pets> findAllBooks = em.createQuery(query);
    Query<Pets> q = findAllBooks.unwrap(Query.class);

    String strQuery = q.getQueryString();

    strQuery = Pattern.compile("(.*?)select \\w*").matcher(strQuery).replaceFirst("SELECT *");

    Set<Parameter<?>> pList = q.getParameters();
    Iterator<Parameter<?>> iter = pList.iterator();
    for (int i=0; i<pList.size(); i++) {
        Parameter<?> p = iter.next();
        strQuery = strQuery.replace(":" + p.getName(), this.createParam(p, q));
    }

    try {
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mempoi?useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC", "root", "");
        Statement stmt = conn.createStatement();
        ResultSet resultSet = stmt.executeQuery(strQuery);

        resultSet.next();
        System.out.println("PET NAME: " + resultSet.getString("pet_name"));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

您为我的库MemPOI (专为管理您的案例而设计)中实现的下一个特性提供了一个很好的想法,它为Apache POI提供了一个抽象层。我将直接从Specification实现导出

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56650630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档