框架学习之JPA(六)

JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。

Sun引入新的JPA ORM规范出于两个原因:其一,简化现有Java EE和Java SE应用开发工作;其二,Sun希望整合ORM技术,实现天下归一。

学习视频:尚硅谷框架jpa学习(有兴趣的同学留言邮箱)

使用软件:eclipse

Java版本:jdk8

本节目录

六、JPA_JPQL

1.HelloWorld

2.使用Hibernate的查询缓存

3.ORDER BY 和GROUP BY

4.关联查询

5.子查询和内建函数

6.UPDATE和DELETE

六、JPA_JPQL

JPQL语言

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

javax.persistence.Query

  • Query接口封装了执行数据库查询的相关方法。调用 EntityManager 的 createQuery、create NamedQuery 及 createNativeQuery 方法可以获得查询对象,进而可调用 Query 接口的相关方法来执行查询操作。

Query接口的主要方法

  • int executeUpdate()

    • 用于执行update或delete语句。
  • List getResultList()
    • 用于执行select语句并返回结果集实体列表。
  • Object getSingleResult()
    • 用于执行只返回单个结果实体的select语句。
  • Query setFirstResult(int startPosition)
    • 用于设置从哪个实体记录开始返回查询结果。
  • Query setMaxResults(int maxResult)
    • 用于设置返回结果实体的最大数。与setFirstResult结合使用可实现分页查询。
  • Query setFlushMode(FlushModeType flushMode)
    • 设置查询对象的Flush模式。参数可以取2个枚举值:FlushModeType.AUTO 为自动更新数据库记录,FlushMode Type.COMMIT 为直到提交事务时才更新数据库记录。
  • setHint(String hintName, Object value)
    • 设置与查询对象相关的特定供应商参数或提示信息。参数名及其取值需要参考特定 JPA 实现库提供商的文档。如果第二个参数无效将抛出IllegalArgumentException异常。
  • setParameter(int position, Object value)
    • 为查询语句的指定位置参数赋值。Position 指定参数序号,value 为赋给参数的值。
  • setParameter(int position, Date d, TemporalType type)
    • 为查询语句的指定位置参数赋 Date 值。Position 指定参数序号,value 为赋给参数的值,temporalType 取 TemporalType 的枚举常量,包括 DATE、TIME 及 TIMESTAMP 三个,,用于将 Java 的 Date 型值临时转换为数据库支持的日期时间类型(java.sql.Date、java.sql.Time及java.sql.Timestamp)。
  • setParameter(int position, Calendar c, TemporalType type)
    • 为查询语句的指定位置参数赋 Calenda r值。position 指定参数序号,value 为赋给参数的值,temporalType 的含义及取舍同前。
  • setParameter(String name, Object value)
    • 为查询语句的指定名称参数赋值。
  • setParameter(String name, Date d, TemporalType type)
    • 为查询语句的指定名称参数赋 Date 值。用法同前。
  • setParameter(String name, Calendar c, TemporalType type)
    • 为查询语句的指定名称参数设置Calendar值。name为参数名,其它同前。该方法调用时如果参数位置或参数名不正确,或者所赋的参数值类型不匹配,将抛出 IllegalArgumentException 异常。

1.HelloWorld

  • 按照条件获取一个List列表,没有SELECT开头,占位符索引从1开始
@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());

}
  • 获取部分属性,需要在对应的model中创建构造函数
//默认情况下, 若只查询部分属性, 则将返回 Object[] 类型的结果. 或者 Object[] 类型的 List.

//也可以在实体类中创建对应的构造器, 然后再 JPQL 语句中利用对应的构造器返回实体类的对象.

@Test

public void testPartlyProperties(){

String jpql = "SELECT new Customer(c.lastName, c.age) FROM Customer c WHERE c.id > ?";

List result = entityManager.createQuery(jpql).setParameter(1, 1).getResultList();

System.out.println(result);

}
  • 在Customer类开头加入一个@NameQuery标签,然后进行测试,此时报错不用管
//createNamedQuery 适用于在实体类前使用 @NamedQuery 标记的查询语句

@Test

public void testNamedQuery(){

Query query = entityManager.createNamedQuery("testNamedQuery").setParameter(1, 3);

Customer customer = (Customer) query.getSingleResult();

System.out.println(customer);

}
  • 本地SQL语句
//createNativeQuery 适用于本地 SQL

@Test

public void testNativeQuery(){

String sql = "SELECT age FROM jpa_cutomers WHERE id = ?";

Query query = entityManager.createNativeQuery(sql).setParameter(1, 3);

Object result = query.getSingleResult();

System.out.println(result);

}

2.使用Hibernate的查询缓存

  • 查询相同的语句只需要提交一次SQL语句查询,之前已经配置过一次查询缓存配置文件,此处不用重复配置
//使用 hibernate 的查询缓存.

@Test

public void testQueryCache(){

String jpql = "FROM Customer c WHERE c.age > ?";

Query query = entityManager.createQuery(jpql).setHint(QueryHints.HINT_CACHEABLE, true);

//占位符的索引是从 1 开始

query.setParameter(1, 1);

List<Customer> customers = query.getResultList();

System.out.println(customers.size());

query = entityManager.createQuery(jpql).setHint(QueryHints.HINT_CACHEABLE, true);

//占位符的索引是从 1 开始

query.setParameter(1, 1);

customers = query.getResultList();

System.out.println(customers.size());

}

3.ORDER BY 和GROUP BY

  • Order by(和SQL一样正常用)
@Test

public void testOrderBy(){

String jpql = "FROM Customer c WHERE c.age > ? ORDER BY c.age DESC";

Query query = entityManager.createQuery(jpql).setHint(QueryHints.HINT_CACHEABLE, true);

//占位符的索引是从 1 开始

query.setParameter(1, 1);

List<Customer> customers = query.getResultList();

System.out.println(customers.size());

}
  • Grope by(和SQL一样正常用)
//查询 order 数量大于 2 的那些 Customer

@Test

public void testGroupBy(){

String jpql = "SELECT o.customer FROM Order o "

+ "GROUP BY o.customer "

+ "HAVING count(o.id) >= 2";

List<Customer> customers = entityManager.createQuery(jpql).getResultList();

System.out.println(customers);

}

 

4.关联查询

注:左外连接语句中的fetch,表示迫切。即迫切左外连接。

什么叫迫切左外连接?

个人理解:

若将(迫切)左外连接左边的对象称为“主对象“,右边的对象称为”附属对象“。

则使用左外连接时,查询出来的对象结构是主对象和附属对象组成的组成的一个对象数组,形如:

Object[主对象,附属对象]。

而使用迫切左外连接时,查询出来的对象结构是一个主对象,而附属对象作为住对象的一个属性值嵌在其中,形如:

主对象

其他属性……

.

.

.

对应属性名:附属对象

.

.

.

其他属性……

  • 关联查询,建议加上FETCH
/**

 * JPQL 的关联查询同 HQL 的关联查询.

 */

@Test

public void testLeftOuterJoinFetch(){

String jpql = "FROM Customer c LEFT OUTER JOIN FETCH c.orders WHERE c.id = ?";

Customer customer =

(Customer) entityManager.createQuery(jpql).setParameter(1, 12).getSingleResult();

System.out.println(customer.getLastName());

System.out.println(customer.getOrders().size());

// List<Object[]> result = entityManager.createQuery(jpql).setParameter(1, 12).getResultList();

// System.out.println(result);

}

5.子查询和内建函数

  • 子查询
@Test

public void testSubQuery(){

//查询所有 Customer 的 lastName 为 YY 的 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, "YY");

List<Order> orders = query.getResultList();

System.out.println(orders.size());

}
  • 内建函数
    • 字符串处理函数主要有:

      • 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。
  • n 算术函数主要有 abs、mod、sqrt、size 等。Size 用于求集合的元素个数。
  • n 日期函数主要为三个,即 current_date、current_time、current_timestamp,它们不需要参数,返回服务器上的当前日期、时间和时戳。

测试:

//使用 jpql 内建的函数

@Test

public void testJpqlFunction(){

String jpql = "SELECT lower(c.email) FROM Customer c";

List<String> emails = entityManager.createQuery(jpql).getResultList();

System.out.println(emails);

}

  

6.UPDATE和DELETE

//可以使用 JPQL 完成 UPDATE 和 DELETE 操作.

@Test

public void testExecuteUpdate(){

String jpql = "UPDATE Customer c SET c.lastName = ? WHERE c.id = ?";

Query query = entityManager.createQuery(jpql).setParameter(1, "YYY").setParameter(2, 12);

query.executeUpdate();

}

  

JPA学习(六、JPA_JPQL)的更多相关文章

  1. JPA学习(二、JPA_基本注解)

    框架学习之JPA(二) JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中 ...

  2. JPA学习---第一节:JPA详解

    一.详解 JPA JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据.他的出现主要是 ...

  3. Hbase深入学习(六) Java操作HBase

    Hbase深入学习(六) ―― Java操作HBase 本文讲述如何用hbase shell命令和hbase java api对hbase服务器进行操作. 先看以下读取一行记录hbase是如何进行工作 ...

  4. TweenMax动画库学习(六)

    目录            TweenMax动画库学习(一)            TweenMax动画库学习(二)            TweenMax动画库学习(三)            Tw ...

  5. Spring学习---JPA学习笔记

    用了一段时间的Spring,到现在也只是处于会用的状态,对于深入一点的东西都不太了解.所以决定开始深入学习Spring. 本文主要记录JPA学习.在学习JPA之前,需要了解一些ORM的概念. ORM概 ...

  6. SVG 学习<六> SVG的transform

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  7. JPA学习笔记(8)——映射一对多关联关系

    一对多关联关系 本文有很多和多对一是一样的,因此不会写得非常具体. 有看不懂的.能够參考JPA学习笔记(7)--映射多对一关联关系 Order实体类 package com.jpa.helloworl ...

  8. C#多线程学习(六) 互斥对象

    如何控制好多个线程相互之间的联系,不产生冲突和重复,这需要用到互斥对象,即:System.Threading 命名空间中的 Mutex 类. 我们可以把Mutex看作一个出租车,乘客看作线程.乘客首先 ...

  9. Unity学习(六)5.x依赖打包

    http://blog.sina.com.cn/s/blog_89d90b7c0102w2ox.html unity5已经封装好了接口,所以依赖打包并没有那么神秘和复杂了. 打包: 1.定义好资源的a ...

随机推荐

  1. 微信小程序开发(二)----- 云开发

    1.概念 微信小程序的云开发是腾讯云与微信团队深度合作推出的一个全新的小程序的解决方案,它提供了云函数.云数据库与云存储这三大基础能力支持,随着云开发的出现,小程序的开发者可以将服务端的部署和运营的环 ...

  2. Python 爬取SeeBug poc

    #!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2017-08-24 21:42:52 # @Author : EnderZhou (z ...

  3. [转帖]「白帽黑客成长记」Windows提权基本原理(下)

    「白帽黑客成长记」Windows提权基本原理(下) https://www.cnblogs.com/ichunqiu/p/10968674.html 提权.. 之前还在想 为什么 我的 sqlserv ...

  4. MyBatis按时间排序

    测试代码 ActivityReadExample readExample = new ActivityReadExample(); readExample.setOrderByClause(" ...

  5. Maven出错的问题处理

    1:使用Maven部署dubbox.jar包到maven本地仓库 由于Dubbox的jar包并没有部署到Maven的中央仓库中,大家在Maven的中央仓库中可以查找到Dubbo的最终版本是2.5.3 ...

  6. ORA-00979: 不是 GROUP BY 表达式

    在oracle数据库中,sql语句中group by子句报错,原因是select 存在列字段,而group by中不存在.

  7. oracle函数nvl,nvl2的区别,nullif函数,coalesce函数

    在oracle中用nvl和nvl2函数来解决为空的情况,例如,如果奖金为空,则为它指定一个数.也就是nvl(奖金字段,指定的奖金),但是两个的类型要一致. 1)nvl()函数 SQL> sele ...

  8. P多行溢出省略号的处理

    因为-webkit-line-clamp: 2不兼容火狐或IE,采用判断浏览器的方式来启用哪个方式 先判断是什么浏览器 //判断是否是谷歌浏览器 if (!stripos($_SERVER[" ...

  9. node端口被占用

    Error: listen EADDRINUSE :::8000 at Object._errnoException (util.js:992:11) at _exceptionWithHostPor ...

  10. [转载]一个支持Verilog的Vim插件——AutoDef

    原文地址:一个支持Verilog的Vim插件--AutoDef作者:hover 支持一下四种类型的变量声明: 1)时序always块中的寄存器变量reg 2)组合always块中的组合reg变量reg ...