JPQL(Java 持久性查询语言)是一种面向对象的查询语言,用于对持久实体执行数据库操作。JPQL 不使用数据库表,而是使用实体对象模型来操作 SQL 查询。这里 JPA 的作用是将 JPQL 转换为 SQL。因此,它为开发人员提供了一个处理 SQL 任务的简单方式。
JPQL 是实体 JavaBeans 查询语言(EJBQL)的扩展,向其添加了以下重要功能:
它可以执行连接操作
它可以批量更新和删除数据
它可以使用排序和分组子句执行聚合函数
单值和多值结果类型
它是一种独立于平台的查询语言
它简单而强大
它可以用于任何类型的数据库,如:MySQL、Oracle
JPQL 查询可以静态地声明为元数据,也可以动态构建在代码中
下面将演示使用 JPQL 实现数据查询,实现用户信息查询。
(1)配置 persistence.xml,如下:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0"> <persistence-unit name="openJPA" transaction-type="RESOURCE_LOCAL"> <!-- JPA提供者 --> <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> <!-- 声明实体类 --> <class>com.hxstrive.openjpa.entity.User</class> <class>com.hxstrive.openjpa.entity.Book</class> <!-- 配置JPA数据库属性 --> <properties> <property name="openjpa.ConnectionURL" value="jdbc:mysql://localhost:3306/openjpa_learn?useSSL=false& serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8"/> <property name="openjpa.ConnectionDriverName" value="com.mysql.jdbc.Driver"/> <property name="openjpa.ConnectionUserName" value="root"/> <property name="openjpa.ConnectionPassword" value="aaaaaa"/> <property name="openjpa.Log" value="SQL=TRACE"/> <!-- 自动生成表 --> <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/> <!-- 不使用加载时强化和编译时强化,使用运行时Unenhanced(不能发挥OpenJPA的最大效能,所以也不推荐) --> <property name="openjpa.ClassLoadEnhancement" value="false"/> <property name="openjpa.DynamicEnhancementAgent" value="false"/> <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/> </properties> </persistence-unit> </persistence>
(2)用户表实体映射,其中使用 @OneToMany 指定一对多映射,一个用户拥有多本图书。代码如下:
@Data
@Entity
@Table
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column
private String name;
@Column
private Integer age;
@Column
private Float salary;
@OneToMany(cascade = CascadeType.ALL)
private List<Book> bookList;
}(3)图书表实体映射,代码如下:
@Data
@Entity
@Table
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column
private String name;
@Column
private float price;
}(4)客户端代码,使用 JPQL 实现用户信息查询。代码如下:
public class JPQLDemo1 {
/** 持久化单元名称 */
private static final String PERSISTENCE_NAME = "openJPA";
public static void main(String[] args) {
EntityManagerFactory factory = Persistence.createEntityManagerFactory(
PERSISTENCE_NAME, System.getProperties());
EntityManager em = factory.createEntityManager();
Query query = em.createQuery("select t from User t where t.id=?1");
query.setParameter(1, 1);
List<User> userList = query.getResultList();
for (User user : userList) {
System.out.println(user);
}
em.close();
factory.close();
System.out.println("finished.");
}
}上面代码中的 JPQL 语句如下:
select t from User t where t.id=?1
其中,User 不是指数据库表名称,而是我们使用 @Entity 定义的实体名称。执行上面代码,输出 SQL 如下:
-- 查询用户信息
SELECT t0.id, t0.age, t0.name, t0.salary FROM User t0 WHERE (t0.id = ?) [params=?]
-- 查询用户拥有的图书信息
SELECT t1.id, t1.name, t1.price FROM User_Book t0 INNER JOIN Book t1 ON t0.BOOKLIST_ID = t1.id WHERE t0.USER_ID = ? [params=?]
-- 用户信息
User{id=1, name='用户-0', age=56, salary=7251.132, bookList=[{"id":1,"name":"图书-用户-0-0","price":40.912487},{"id":2,"name":"图书-用户-0-1","price":25.45687},{"id":3,"name":"图书-用户-0-2","price":87.681984},{"id":4,"name":"图书-用户-0-3","price":94.50937}]}