- JPQL全称Java Persistence Query Language
- 基于首次在EJB2.0中引入的EJB查询语言(EJBQL),Java持久化查询语言(JPQL)是一种可移植的查询语言,旨在以面向对象表达式语言的表达式,将SQL语法和简单查询语义绑定在一起·使用这种语言编写的查询是可移植的,可以被编译成所有主流数据库服务器上的SQL。
- 其特征与原生SQL语句类似,并且完全面向对象,通过类名和属性访问,而不是表名和表的属性。
getResultList getSingleResult executeUpdate
setHint(String,Object):Query
setParameter(Parameter&Ts,)Query
setParameter(Parameter<Calendar>,Calendar,Tempor setParameter(Parameter<Date>,Date,TemporalType)
setParameter(String,Object):Query
setParameter(String,Calendar,TemporalType):Query setParameter(String,Date,TemporalType):Query
setParameter(int,Object):Query
setParameter(int,Calendar,TemporalType):Query setParameter(int Date TemporalTypel)
增
@Test
public void testAdd() {
// 定义对象
Customer c = new Customer();
c.setCustLevel("VIP客户");
c.setCustSource("网络");
EntityManager em = null;
EntityTransaction tx = null;
try {
// 获取实体管理对象
em = JPAUtil.getEntityManager();
// 获取事务对象
tx = em.getTransaction();
// 开启事务
tx.begin();
// 执行操作
em.persist(c);
// 提交事务
tx.commit();
} catch (Exception e) {
// 回滚事务
tx.rollback();
e.printStackTrace();
} finally {
// 释放资源
em.close();
}
}
修
- 如果数据库中没有这个对象,直接发出一条insert语句
- 如果写了一个不存在的id.它会先查询,然后在insert
public void testMerge(){
//定义对象
EntityManager em=null;
EntityTransaction tx=null;
try{
//获取实体管理对象
em=JPAUtil.getEntityManager();
//获取事务对象
tx=em.getTransaction();
//开启事务
tx.begin();
//执行操作
Customer c1 = em.find(Customer.class, 6L);
em.clear();//把c1对象从缓存中清除出去
em.merge(c1);
//提交事务
tx.commit();
}catch(Exception e){
//回滚事务
tx.rollback();
e.printStackTrace();
}finally{
//释放资源
em.close();
}
删
public void testRemove() {
// 定义对象
EntityManager em = null;
EntityTransaction tx = null;
try {
// 获取实体管理对象
em = JPAUtil.getEntityManager();
// 获取事务对象
tx = em.getTransaction();
// 开启事务
tx.begin();
// 执行操作
Customer c1 = em.find(Customer.class, 6L);
em.remove(c1);
// 提交事务
tx.commit();
} catch (Exception e) {
// 回滚事务
tx.rollback();
e.printStackTrace();
} finally {
// 释放资源
em.close();
}
}
查
立即加载的策略
public void testGetOne() {
// 定义对象
EntityManager em = null;
EntityTransaction tx = null;
try {
// 获取实体管理对象
em = JPAUtil.getEntityManager();
// 获取事务对象
tx = em.getTransaction();
// 开启事务
tx.begin();
// 执行操作
Customer c1 = em.find(Customer.class, 1L);
// 提交事务
tx.commit();
System.out.println(c1); // 输出查询对象
} catch (Exception e) {
// 回滚事务
tx.rollback();
e.printStackTrace();
} finally {
// 释放资源
em.close();
}
}
查询实体的缓存问题
public void testGetOne() {
// 定义对象
EntityManager em = null;
EntityTransaction tx = null;
try {
// 获取实体管理对象
em = JPAUtil.getEntityManager();
// 获取事务对象
tx = em.getTransaction();
// 开启事务
tx.begin();
// 执行操作
Customer c1 = em.find(Customer.class, 1L);
Customer c2 = em.find(Customer.class, 1L);
System.out.println(c1 == c2);// 输出结果是true,EntityManager也有缓存
// 提交事务
tx.commit();
System.out.println(c1);
} catch (Exception e) {
// 回滚事务
tx.rollback();
e.printStackTrace();
} finally {
// 释放资源
em.close();
}
}
延迟加载策略
public void testLoadOne() {
// 定义对象
EntityManager em = null;
EntityTransaction tx = null;
try {
// 获取实体管理对象
em = JPAUtil.getEntityManager();
// 获取事务对象
tx = em.getTransaction();
// 开启事务
tx.begin();
// 执行操作
Customer c1 = em.getReference(Customer.class, 1L);
// 提交事务
tx.commit();
System.out.println(c1);
} catch (Exception e) {
// 回滚事务
tx.rollback();
e.printStackTrace();
} finally {
// 释放资源
em.close();
}
}
createNativeQuery
@SpringBootTest
public class HQLTest {
@Autowired
private EntityManager entityManager;
@Test
public void test() {
Query selectAccountFromTsUser = entityManager.createNativeQuery("select ACCOUNT from ts_user");
List resultList = selectAccountFromTsUser.getResultList();
}
}
@NamedQuery
import org.hibernate.annotations.NamedQuery;
查询示例
查询全部
String jpql = "from Customer";
Query query = em.createQuery(jpql);
List list = query.getResultList();
分页查询
//创建query对象
String jpql = "from Customer";
Query query = em.createQuery(jpql);
//起始索引
query.setFirstResult(0);
//每页显示条数
query.setMaxResults(2);
//查询并得到返回结果
List list = query.getResultList(); //得到集合返回类型
条件查询
String jpql = "from Customer where custName like ? ";
Query query = em.createQuery(jpql);
query.setParameter(1, "xxx%");
Object object = query.getSingleResult();
统计
String jpql = "select count(custId) from Customer";
Query query = em.createQuery(jpql);
// 2.查询并得到返回结果
Object count = query.getSingleResult(); // 得到集合返回类型
多表
@Entity @Table(name = "CUSTOMER") public class Customer { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List<Order> orders; // Getters and setters } @Entity @Table(name = "ORDER") public class Order { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "CUSTOMER_ID") private Customer customer; @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List<OrderItem> items; // Getters and setters } @Entity @Table(name = "ORDER_ITEM") public class OrderItem { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "ORDER_ID") private Order order; private String productName; private int quantity; // Getters and setters }
使用JOIN FETCH加载关联数据
如果你想在一次查询中加载Customer及其所有的Order和OrderItem,可以使用JOIN FETCH:
public List<Customer> loadCustomersWithOrdersAndItems() { EntityManager em = getEntityManager(); TypedQuery<Customer> query = em.createQuery( "SELECT c FROM Customer c " + "JOIN FETCH c.orders o " + "JOIN FETCH o.items i", Customer.class ); return query.getResultList(); }
在这个查询中,JOIN FETCH c.orders o将立即加载每个Customer的所有Order,而JOIN FETCH o.items i将立即加载每个Order的所有OrderItem。这样,你就可以在查询结果中直接访问这些关联的数据,而不需要担心懒加载的问题。
注意事项
使用JOIN FETCH会增加查询的复杂度和潜在的性能开销,因为它可能需要执行更复杂的SQL查询。在数据量大时,应谨慎使用。
如果只是需要统计或聚合数据,而不是加载所有关联数据,可能不需要使用JOIN FETCH,而是考虑使用更简单的查询或SQL聚合函数。
通过使用JOIN FETCH,你可以在JPQL查询中控制何时加载关联的数据,这对于需要立即获取完整数据集的场景非常有用。