Kar*_*l S 11
对于Eclipselink:您可以通过以下方式提取SQL:
query.unwrap(EJBQueryImpl.class).getDatabaseQuery().getSQLString()
Run Code Online (Sandbox Code Playgroud)
它只在查询执行后才有效.
如果您只想知道如何将JPQL或Criteria Query转换为数据库的SQL方言,则可以在持久性xml中启用细粒度日志记录,然后查看日志文件.
属性名称和值取决于您的JPA实现.以下是EclipseLink 的persistence.xml相关部分的示例:
<properties>
<property name="eclipselink.logging.level" value="FINEST"/>
</properties>
Run Code Online (Sandbox Code Playgroud)
虽然没有标准的 JPA 功能来实现这个目标,但您仍然可以Query
使用 JPA 提供程序特定的 API从 JPQL 或 Criteria API 中提取 SQL 查询。
从 2.9.11 版本开始,Hibernate Types开源项目提供的SQLExtractor
实用程序允许您从任何 JPQL 或 Criteria API 查询中获取 SQL 查询,无论您使用的是 Hibernate 5.4、5.3、5.2、5.1、5.0, 4.3、4.2 或 4.1。
假设我们有以下 JPQL 查询:
Query jpql = entityManager.createQuery("""
select
YEAR(p.createdOn) as year,
count(p) as postCount
from
Post p
group by
YEAR(p.createdOn)
""", Tuple.class
);
Run Code Online (Sandbox Code Playgroud)
使用 Hibernate Types,提取 Hibernate 生成的 SQL 查询就这么简单:
String sql = SQLExtractor.from(jpql);
Run Code Online (Sandbox Code Playgroud)
而且,如果我们记录提取的 SQL 查询:
LOGGER.info("""
The JPQL query: [
{}
]
generates the following SQL query: [
{}
]
""",
jpql.unwrap(org.hibernate.query.Query.class).getQueryString(),
sql
);
Run Code Online (Sandbox Code Playgroud)
我们得到以下输出:
- The JPQL query: [
select
YEAR(p.createdOn) as year,
count(p) as postCount
from
Post p
group by
YEAR(p.createdOn)
]
generates the following SQL query: [
SELECT
extract(YEAR FROM sqlextract0_.created_on) AS col_0_0_,
count(sqlextract0_.id) AS col_1_0_
FROM
post p
GROUP BY
extract(YEAR FROM p.created_on)
]
Run Code Online (Sandbox Code Playgroud)
请注意,我们将 JPA 解包
Query
到 Hibernateorg.hibernate.query.Query
接口,该接口提供了getQueryString
我们可以用来记录关联的 JPQL 查询字符串的方法。
该SQLExtractor
不限于JPQL查询。您也可以将它与 Criteria API 查询一起使用,如以下示例所示:
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<PostComment> criteria = builder.createQuery(PostComment.class);
Root<PostComment> postComment = criteria.from(PostComment.class);
Join<PostComment, Post> post = postComment.join("post");
criteria.where(
builder.like(post.get("title"), "%Java%")
);
criteria.orderBy(
builder.asc(postComment.get("id"))
);
Query criteriaQuery = entityManager.createQuery(criteria);
String sql = SQLExtractor.from(criteriaQuery);
assertNotNull(sql);
LOGGER.info("""
The Criteria API, compiled to this JPQL query: [
{}
]
generates the following SQL query: [
{}
]
""",
jpql.unwrap(org.hibernate.query.Query.class).getQueryString(),
sql
);
Run Code Online (Sandbox Code Playgroud)
运行上述测试用例时,我们得到以下 SQL 查询:
- The Criteria API, compiled to this JPQL query: [
select
pc
from
PostComment as pc
inner join
pc.post as p
where
p.title like :param0
order by
pc.id asc
]
generates the following SQL query: [
SELECT
pc.id AS id1_1_,
pc.post_id AS post_id3_1_,
pc.review AS review2_1_
FROM
post_comment pc
INNER JOIN
post p ON pc.post_id=p.id
WHERE
p.title LIKE ?
ORDER BY
pc.id ASC
]
Run Code Online (Sandbox Code Playgroud)
Criteria API 首先编译为 JPQL 查询,如getQueryString()
方法调用所示。
中间 JPQL 查询进一步转换为 SQL 查询,该查询由SQLExtractor
实用程序正确解析。
归档时间: |
|
查看次数: |
32464 次 |
最近记录: |