JPQL语言,即 JavaPersistence Query Language 的简称。JPQL 是一种和 SQL 非常类似的中间性和对象化查询语言,它最终会被编译成针对不同底层数据库的 SQL 查询,从而屏蔽不同数据库的差异。JPQL语言的语句可以是 select 语句、update 语句或delete语句,它们都通过 Query接口封装执行
javax.persistence.Query
Query接口封装了执行数据库查询的相关方法。调用 EntityManager的 createQuery、create NamedQuery及 createNativeQuery方法可以获得查询对象,进而可调用 Query 接口的相关方法来执行查询操作。
@Test public void testHelloJPQL() { String jpql = "from Customer c where c.age > ?"; Query query = entityManager.createQuery(jpql); //占位符的索引从1开始 query.setParameter(1, 1); List<Customer> customers = query.getResultList(); System.out.println(customers.size()); }
查询部分属性
//默认情况下,若只查询部分属性,则返回Object[ ]类型的结果, 或者Object[ ]类型的List。 //也可以在实体类中创建对应的构造函数,然后在JPQL语句中用对应的构造函数返回实体类的对象 @Test public void testPartlyProperties() { String jpql = "select new Customer(c.lastName, c.age) from Customer c where c.id > ?"; List<Customer> result = entityManager.createQuery(jpql).setParameter(1, 1).getResultList(); System.out.println(result); }
对应的构造函数如下
public Customer(String lastName, int age) { super(); this.lastName = lastName; this.age = age; }
@NamedQuery注解
@Test public void testNamedQuery() { Query query = entityManager.createNamedQuery("testNamedQuery").setParameter(1, 1); User user = (User) query.getSingleResult(); System.out.println(user); }
在实体类前使用@NamedQuery注解
@NamedQuery(name="testNamedQuery", query="select u from User u where u.id = ?") @Cacheable(true) @Table(name = "jps_user") @Entity public class User { @GeneratedValue @Id private Integer id; private String username; private String password; //getter setter }
本地SQL
//本地SQL @Test public void testNativeQuery() { String sql = "select username from jps_user where id = ?"; Query query = entityManager.createNativeQuery(sql).setParameter(1, 1); Object result = query.getSingleResult(); System.out.println(result); }
JPQL查询缓存
@Test public void testQueryCache() { String jpql = "from User u where u.id > ?"; Query query = entityManager.createQuery(jpql).setParameter(1, 1); List<User> users = query.getResultList(); System.out.println(users); System.out.println("----------------");//默认情况下发送两条S QL查询语句 query = entityManager.createQuery(jpql).setParameter(1, 1); users = query.getResultList(); System.out.println(users); }
启用查询缓存
配置文件中配置
<property name="hibernate.cache.use_query_cache" value="true"/>
@Test public void testQueryCache() { String jpql = "from User u where u.id > ?"; Query query = entityManager.createQuery(jpql).setParameter(1, 1).setHint(QueryHints.HINT_CACHEABLE, true); List<User> users = query.getResultList(); System.out.println(users); System.out.println("----------------");//默认情况下发送两条SQL查询语句,开启查询缓存则只发送一次SQL语句 query = entityManager.createQuery(jpql).setParameter(1, 1).setHint(QueryHints.HINT_CACHEABLE, true); users = query.getResultList(); System.out.println(users); }
order by语句
@Test public void testOrderBy() { String jpql = "from User u where u.id > ? order by id desc"; Query query = entityManager.createQuery(jpql).setParameter(1, 1).setHint(QueryHints.HINT_CACHEABLE, true); List<User> users = query.getResultList(); System.out.println(users); }
group by
@Test public void testGroupBy() { String jpql = "select o.customer from Order o group by o.customer having count(o.id) > 1"; List<Customer> customers = entityManager.createQuery(jpql).getResultList(); System.out.println(customers); }
left outer join fetch
@Test public void testLeftOuterJoinFetch() { //一条查询语句即可。如果不写left outer join fetch则需要发送两条SQL语句。 String jpql = "from Customer c left outer join fetch c.orders where c.id = ?"; Customer customer = (Customer) entityManager.createQuery(jpql).setParameter(1, 3).getSingleResult(); System.out.println(customer.getOrders().size()); }
子查询
@Test public void testSubQuery() { //查询LashName是SS的用户的所有的order String jpql = "select o from Order o where o.customer = (select c from Customer c where c.lastName = ?)"; Query query = entityManager.createQuery(jpql).setParameter(1, "SS"); List<Order> orders = query.getResultList(); System.out.println(orders); }
JPQL函数
@Test public void testJPQLFucntion() { String jpql = "select upper(c.email) from Customer c"; List<Customer> customers = entityManager.createQuery(jpql).getResultList(); System.out.println(customers); }
JPQL提供了以下一些内建函数,包括字符串处理函数、算术函数和日期函数。
字符串处理函数主要有:
�Cconcat(String s1, String s2):字符串合并/连接函数。
�Csubstring(String s, int start, int length):取字串函数。
�Ctrim([leading|trailing|both,] [char c,] String s):从字符串中去掉首/尾指定的字符或空格。
�Clower(String s):将字符串转换成小写形式。
�Cupper(String s):将字符串转换成大写形式。
�Clength(String s):求字符串的长度。
�Clocate(String s1, String s2[, int start]):从第一个字符串中查找第二个字符串(子串)出现的位置。若未找到则返回0。
算术函数主要有 abs、mod、sqrt、size 等。Size 用于求集合的元素个数。
日期函数主要为三个,即 current_date、current_time、current_timestamp,它们不需要参数,返回服务器上的当前日期、时间和时戳。
update&delete操作
@Test public void testUpdate() { String jpql = "update Customer c set c.lastName = ? where c.id = ?"; Query query = entityManager.createQuery(jpql).setParameter(1, "[email protected]").setParameter(2, 7); query.executeUpdate(); }