JPQL语言,即 JavaPersistence Query Language 的简称。JPQL 是一种和 SQL 非常类似的中间性和对象化查询语言,它最终会被编译成针对不同底层数据库的 SQL 查询,从而屏蔽不同数据库的差异。JPQL语言的语句可以是 select 语句、update 语句或delete语句,它们都通过 Query接口封装执行


javax.persistence.Query

Query接口封装了执行数据库查询的相关方法。调用 EntityManager的 createQuerycreate NamedQuerycreateNativeQuery方法可以获得查询对象,进而可调用 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提供了以下一些内建函数,包括字符串处理函数、算术函数和日期函数。

字符串处理函数主要有:

concat(String s1, String s2):字符串合并/连接函数。

substring(String s, int start, int length):取字串函数。

trim([leading|trailing|both,] [char c,] String s):从字符串中去掉首/尾指定的字符或空格。

lower(String s):将字符串转换成小写形式。

upper(String s):将字符串转换成大写形式。

length(String s):求字符串的长度。

locate(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, "umgsai@126.com").setParameter(2, 7);
	query.executeUpdate();
}