伤心客 发表于 2024-10-6 00:15:24

原生的JPA-JPQL


[*]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查询中控制何时加载关联的数据,这对于必要立即获取完整数据集的场景非常有用。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 原生的JPA-JPQL