![](/img/trans.png)
[英]Spring JPA using Specifications and CriteriaQuery on Joint Tables
[英]Get the query to be executed using JPA Specifications in Spring
我有一個 spring 項目,我需要將查詢結果集導出到 Excel 表中。 目前我正在使用JPA repository
從數據庫中獲取數據,並且我正在使用Apache POI
庫從這些數據中准備 excel 表。
// 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 秒內完成。
ResultSet resultSet = statement.executeQuery("select * from table where some_filters");
File file = writeResultsToCSVFile(resultSet);
我正在使用JPA specifications
在當前架構中構建查詢。 無論如何要獲取將要執行的查詢,以便我可以直接獲取結果集(而不是 POJO)並准備 csv 文件。
// I'm looking for something like follows:
ResultSet resultSet = statement.executeQuery(specifications.getQuery());
File file = writeResultsToCSVFile(resultSet);
有沒有辦法實現這樣的目標?
這有點棘手,因為您可以獲得這樣的非標准查詢:
select generatedAlias0 from Pets as generatedAlias0 where generatedAlias0.pet_name=:param0
您必須獲得查詢,然后您需要操作諸如請求字段和綁定參數之類的東西(管理它們的類型。請注意,在此示例中我只管理了字符串類型)。
因此,假設您正在使用 Hibernate,您可以執行以下操作:
/**
*
*/
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
實現導出
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.