Có thể thực hiện Truy vấn Tiêu chí JPA bằng cách sử dụng câu lệnh chứa của Oracle Text không, và nếu như vậy thì sao?Truy vấn Tiêu chuẩn Văn bản của Oracle trong JPA
Trả lời
Nghi ngờ điều đó. API có trên tất cả RDBMS và cung cấp một số cấu trúc như "LIKE"/"SUBSTRING" có thể được ánh xạ tới biểu mẫu đó khi được sử dụng trên Oracle cho cột TEXT, nhưng sau đó lại có thể chỉ sử dụng tiêu chuẩn SQL. Không có cách nào tuân thủ tiêu chuẩn để nhấn mạnh rằng
Tôi vừa viết một OracleTextDictionary cho openjpa, chuyển đổi toán tử 'like' thành các toán tử 'contains', khi đối số được đặt trước bằng dấu "huyền diệu".
Bằng cách này, bạn có thể sử dụng QueryDSL hoặc Ngôn ngữ tiêu chí (hoặc JPQL) với văn bản Oracle.
Từ điển phát hiện các câu lệnh LIKE với một điểm đánh dấu ma thuật trong đối số và viết lại SQL để sử dụng lệnh gọi CTX CONTAINS.
Một nhược điểm là điểm không thể truy cập theo cách đơn giản, nhưng có thể tăng cường trình điều khiển theo thứ tự theo điểm số. Vui lòng chỉnh sửa mã :-)
Tôi cho rằng có thể chuyển sang chế độ ngủ đông, giả sử có cơ chế tương tự để điều chỉnh truy vấn cơ sở dữ liệu cho một db cụ thể.
package se.grynna.dict;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.sql.OracleDictionary;
import org.apache.openjpa.jdbc.sql.SQLBuffer;
import org.apache.openjpa.jdbc.sql.Select;
public class OracleTextDictionary extends OracleDictionary {
public static final String CTX_MAGIC_MARKER = "@[email protected]";
final static Pattern likePattern = Pattern
.compile("t(\\d+)\\.(\\S+) LIKE (\\?)");
@Override
protected SQLBuffer toSelect(SQLBuffer select,
JDBCFetchConfiguration fetch, SQLBuffer tables, SQLBuffer where,
SQLBuffer group, SQLBuffer having, SQLBuffer order,
boolean distinct, boolean forUpdate, long start, long end,Select sel) {
SQLBuffer sqlBuffer = super.toSelect(select, fetch, tables, where,
group, having, order, distinct, forUpdate, start, end, sel);
SQLBuffer tmpBuf = sqlBuffer;
String sql = tmpBuf.getSQL();
int label = 1;
for (Matcher m = likePattern.matcher(sql); m.find(); sql = tmpBuf.getSQL()) {
int argPos = m.start(3);
int argIdx = findArgIdx(sql, argPos);
Object o = tmpBuf.getParameters().get(argIdx);
if(o == null) break;
String arg = o.toString();
if (arg.startsWith(CTX_MAGIC_MARKER)) {
if (tmpBuf == sqlBuffer) {
tmpBuf = new SQLBuffer(sqlBuffer);
}
arg = arg.substring(CTX_MAGIC_MARKER.length());
setParameter(tmpBuf, argIdx, arg);
String aliasNo = m.group(1);
String colName = m.group(2);
}
String replace = String.format("(CONTAINS(t%s.%s,?,%d)>0)",
aliasNo, colName, label++);
tmpBuf.replaceSqlString(m.start(), m.end(), replace);
m.reset(tmpBuf.getSQL());
}
}
return tmpBuf;
}
@SuppressWarnings("unchecked")
private void setParameter(SQLBuffer tmpBuf, int argIdx, String arg) {
tmpBuf.getParameters().set(argIdx, arg);
}
private int findArgIdx(String sql, int argPos) {
int count = -1;
for (int i = 0; i <= argPos; i++) {
char c = sql.charAt(i);
if (c == '?') {
count++;
}
}
return count;
}
}
Ví dụ: Sau đây (rõ ràng là giả tạo) đầu vào sản xuất được gọi với các thông số:
:1 "@[email protected] near ponies"
:2 "@[email protected]"
:3 "@[email protected]%"
:4 "abc1%" <-- an ordinary like :-)
:5 "@[email protected]%"
JPQL
select distinct customer
from Customer customer
where customer.custName like :a1 and customer.custName like :a2 and customer.custName like :a1 and customer.custId in (select d.custId
from Customer d
where d.custName like :a3 or d.custName like :a1)
SQL
SELECT t0.custId,
t0.custName
FROM Customer t0
WHERE ((CONTAINS(t0.custName,?,1)>1)
AND (CONTAINS(t0.custName,?,2) >1)
AND (CONTAINS(t0.custName,?,3) >1)
AND t0.custId IN
(SELECT t1.custId
FROM Customer t1
WHERE (t1.custName LIKE ? <---- the like survives....
OR (CONTAINS(t1.custName,?,1)>1))
))
AND ROWNUM <= ?
Như một mặt lưu ý : QueryDsl thực sự có một toán tử ´contains ', được cho là phụ trợ Lucene, trong đó các chương trình phụ trợ của jpa và sql tạo ra một câu lệnh' like '.
Tôi chưa tìm ra cách để quá tải toán tử chứa, để nó có thể được sử dụng. (Khác với viết lại mã, mà tôi không thể làm được vì tôi đang sử dụng phiên bản đi kèm với WebSphere.)
Vì vậy, tôi sử dụng phương pháp tĩnh nhỏ để làm cho nó trông đẹp khi sử dụng QuertyDSL.
// x.where(c.custName.like(CTX.contains("omg near ponies"))));
Nó sẽ càng đẹp hơn nếu JPQL có thể cung cấp một số trừu tượng (hoặc bổ sung) cho công cụ tìm kiếm toàn văn ...
Tiêu chuẩn hỗ trợ API function() cho phép một hàm cơ sở dữ liệu được gọi bằng Tên.
qb.gt(qb.function("CONTAINS", root.get("name"), qb.parameter("name"), qb.literal(1)), 1)
EclipseLink cũng hỗ trợ điều này trong JPQL bằng từ khóa FUNC.
- 1. Tiêu chuẩn JPA truy vấn riêng biệt
- 2. Hướng dẫn Tiêu chuẩn JPA
- 3. Oracle cách xuất truy vấn sang tệp văn bản/csv
- 4. Ví dụ sử dụng countDistinct trong một JPA truy vấn Tiêu chuẩn API
- 5. JPA/Tiêu chuẩn API - Giống như & vấn đề bình đẳng
- 6. Subquery trong chọn khoản với API JPA Tiêu chuẩn
- 7. JPA 2 + API tiêu chí - Xác định truy vấn phụ
- 8. Tiêu chí/Tiêu chí kiểu JPA Các truy vấn xây dựng từ Hibernate Session
- 9. JPA 2 Câu hỏi Tiêu chí Truy vấn
- 10. Truy vấn được đặt tên JPA và API tiêu chí?
- 11. Truy vấn phức tạp với trình tạo tiêu chí JPA
- 12. Cách viết truy vấn này bằng truy vấn Tiêu chí JPA?
- 13. Truy vấn cột dấu ngoặc nhọn oracle
- 14. JPA - Tiêu chuẩn Query - Tìm kiếm Integer sử dụng "like"
- 15. Truy vấn Bảng tính Google: cách thay thế văn bản trong tiêu đề cột?
- 16. Dữ liệu JPA Spring "OR" truy vấn
- 17. Truy vấn SQLite để khớp chuỗi văn bản trong cột
- 18. Chuẩn bị() vs truy vấn() mysqli
- 19. Hibernate Truy vấn Gợi ý cho JPA
- 20. Đặt văn bản tiêu đề của một tiêu đề QTreeView
- 21. Chức năng truy vấn JPA MONTH/YEAR
- 22. Truy vấn JPA để chọn dựa trên tiêu chí cùng với việc phân trang
- 23. Tiêu chuẩn thay thế cho CONNECT BY?
- 24. Xác định tiến trình của truy vấn (Oracle PL/SQL)
- 25. Truy vấn cập nhật Oracle với chọn
- 26. Tìm kiếm văn bản oracle blob
- 27. chọn "tất cả các cột" với "nhóm theo" trong truy vấn tiêu chuẩn ngủ đông
- 28. JPA 2.0 bản địa kết quả truy vấn dưới dạng bản đồ
- 29. TypedQuery thay vì truy vấn bình thường trong JPA
- 30. API truy vấn tiêu chí JPA và đặt hàng theo hai cột
Vì vậy, tôi đoán tôi phải sử dụng truy vấn gốc JPA bằng cách sử dụng chuỗi nối và an toàn loại bỏ. Ouch. – Ryan