顾名思义:即根据主键查询一个实体。在 JPA 中提供了两个方法。分别是:
find(Class entityClass,Object id);
getReference(Class entityClass,Object id);
他们的区别是:
查询的时机不一样:
find 的方法是立即加载,只要一调用方法就马上发起查询。
getReference 方法是延迟加载,只有真正用到数据时才发起查 询。(按需加载)
返回的结果不一样:
find 方法返回的是实体类对象。
getReference 方法返回的是实体类的代理对象。
示例
//查询一个
//立即加载
@Test
public void testFindOne() {
EntityManager em = JPAUtil.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Customer c = em.find(Customer.class, 1);
System.out.println(c);
tx.commit();
em.close();
}
//查询一个
//懒加载(延迟加载)
@Test
public void testFindOne2() {
EntityManager em = JPAUtil.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Customer c = em.getReference(Customer.class, 1);
System.out.println(c.toString());
tx.commit();
em.close();
}
此种查询方式,是根据已知实体,调用该实体中的 getXXX 方法获取到关联对象的信息。
例如:
Customer 对象中有一个 LinkMan 的集合属性,并生成了 get 和 set 方法。
我们就可以通过 getLinkMans()得到该客户下的所有联系人信息。
要求:
两个实体必须有关联关系,才能使用此种查询方式。
示例:
/**
* 根据客户导航查询联系人
*/
@Test
public void test() {
// 定义对象
EntityManager em = null;
EntityTransaction tx = null;
try {
// 获取实体管理对象
em = JpaUtil.getEntityManager();
// 获取事务对象
tx = em.getTransaction();
// 开启事务
tx.begin();
// 执行操作
Customer c1 = em.find(Customer.class, 26L);
System.out.println(c1); // 输出查询对象
Set linkMans = c1.getLinkMans();
for (LinkMan linkMan : linkMans) {
System.out.println(linkMan);
}
// 提交事务
tx.commit();
} catch (Exception e) {
// 回滚事务
tx.rollback();
e.printStackTrace();
} finally {
// 释放资源
em.close();
}
}
/**
* 根据联系人导航查询客户
*/
@Test
public void test2() {
// 定义对象
EntityManager em = null;
EntityTransaction tx = null;
try {
// 获取实体管理对象
em = JpaUtil.getEntityManager();
// 获取事务对象
tx = em.getTransaction();
// 开启事务
tx.begin();
// 执行操作
LinkMan linkMan = em.find(LinkMan.class, 35L);
System.out.println(linkMan); // 输出查询对象
Customer customer = linkMan.getCustomer();
System.out.println(customer); //输入导航查询结果
// 提交事务
tx.commit();
} catch (Exception e) {
// 回滚事务
tx.rollback();
e.printStackTrace();
} finally {
// 释放资源
em.close();
}
}
此种方式是使用 JPQL 语句查询。全称是 Java Persistence Query Language。JPQL 语句是 JPA 中定义的一种查询语言。此种语言的用意是让开发者忽略数据库表和表中的字段,而关注实体类及实体类中的属性。更加契合操作实体类就相当于操作数据库表的 ORM 思想。但是又不完全脱离 SQL 语句,例如:
排序,仍然使用 order 关键字。
聚合函数:在 JPQL 中也可以是使用。
它的写法是:
把查询的表名换成实体类名称,把表中的字段名换成实体类的属性名称。
注意:
此处我们必须明确,实体类属性名称指的是 get/set 方法后面的部分,且首字母改小写。而非私
有类成员变量。只不过我们的 get/set 方法都是通过工具生成的,所以可以直接写私有成员变量名称。
/**
* 根据id查询
*/
@Test
public void test() {
// 定义对象
EntityManager em = null;
EntityTransaction tx = null;
try {
// 获取实体管理对象
em = JpaUtil.getEntityManager();
// 获取事务对象
tx = em.getTransaction();
// 开启事务
tx.begin();
//JPQL创建查询语句
//Query query = em.createQuery("select c from Customer c where c.id = ?");
//也可以胜率select c
Query query = em.createQuery(" from Customer where custId = ?");
query.setParameter(1, 26L);
// 执行操作
List list = query.getResultList();
for (Object object : list) {
System.out.println(object);
}
// 提交事务
tx.commit();
} catch (Exception e) {
// 回滚事务
tx.rollback();
e.printStackTrace();
} finally {
// 释放资源
em.close();
}
}
此种方式是使用原生SQL语句查询数据库。采用此种方式查询,我们可以在数据库可视化编译器中先把语句写好,然后粘到代码中。
注意:
一般采用 ORM 框架作为持久层解决方案时,很少使用原生 SQL 语句。(特定情况除外:例如统计分析的语句,一般用于复杂查询)
/**
* 根据id查询
*/
@Test
public void test() {
// 定义对象
EntityManager em = null;
EntityTransaction tx = null;
try {
// 获取实体管理对象
em = JpaUtil.getEntityManager();
// 获取事务对象
tx = em.getTransaction();
// 开启事务
tx.begin();
Query query = em.createNativeQuery(
"select * from cst_customer", Customer.class);
// 执行操作
List list = query.getResultList();
for (Customer cust : list) {
System.out.println(cust);
}
// 提交事务
tx.commit();
} catch (Exception e) {
// 回滚事务
tx.rollback();
e.printStackTrace();
} finally {
// 释放资源
em.close();
}
}
QBC 全称是 Query By Criteria。此种方式是一种更加面向对象的查询方式。并且可扩展条件查询 API,通过它完全不需要考虑数据库底层如何实现,以及 SQL 语句如何编写。
细节:
JPQL 能查的,QBC 都能查,反之亦然。
/**
*
* 5、查询所有客户
*/
@Test
public void findAll() {
EntityManager em = null;
EntityTransaction tx = null;
// 1.获取 JPA 的操作数据库对象
em = JpaUtil.getEntityManager();
// 3.开启事务
tx = em.getTransaction();
tx.begin();
// 4.创建 CriteriaBuilder(条件构建)对象,该对象中定义着查询条件涉及的方法,通过该对象设置查询条件
CriteriaBuilder cb = em.getCriteriaBuilder();
// 5.获取 QBC 的查询的对象 CriteriaQuery.
// 它可以加一些 SQL 的子句例如:where/group by/order by/having 等等。
CriteriaQuery cq = cb.createQuery(Customer.class);
// 6.获取实体类对象的封装对象,有此对象之后,所有实体类都可以看成此类型
Root root = cq.from(Customer.class);
// 7.创建条件对象
Predicate p1 = cb.like(root.get("custName"), "%天%");
Predicate p2 = cb.equal(root.get("custLevel"), "VIP 客户");
Predicate p3 = cb.between(root.get("custId"), 10, 20);
// 8.构建排序条件,并获取构建排序后的QBC 的查询对象
Order o = cb.desc(root.get("custId"));
CriteriaQuery cq1 = cq.orderBy(o);
// 9.给查询对象设置查询条件
cq1.where(p1, p2, p3);
TypedQuery createQuery = em.createQuery(cq1);
// 10.执行查询,获取结果
List list = createQuery.getResultList(); // 得到集合返回类型
for (Object object : list) {
System.out.println(object);
}
// 提交事物
tx.commit();
// 释放资源
em.close();
}