框架学习之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. 【Qt开发】QScrollArea添加布局后没有出现滚动条的解决方法

    [Qt开发]QScrollArea添加布局后没有出现滚动条的解决方法 标签:[Qt开发] 说明:尝试利用滚动区域显示多张图片,为了能够动态地往滚动区域贴图,为滚动区域设置了布局,然后通过布局来添加wi ...

  2. tableau单机版安装

    参考: https://help.tableau.com/current/server-linux/zh-cn/requ.htm   先将服务器防火墙80级8850端口打开 临时关闭SELinux/防 ...

  3. 小记---------FLUM负载均衡配置

    sink group允许组织多个sink到一个实体上,sink processors能够提供在组内所有sink之间实现负载均衡的能力,而且在失败的情况下能够进行故障转移从一个sink到另一个sink, ...

  4. FTP服务器的搭建(CentOS 7)

    注意ip地址为: 虚拟机ip设置 TYPE="Ethernet"BOOTPROTO="static"NAME="enp0s3"DEVICE= ...

  5. [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash)

    [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash) 题面 扔很多次硬币后,用H表示正面朝上,用T表示反面朝上,会得到一个硬币序列.比如HTT表示第一次正面朝上, ...

  6. frame的处理

    自动化测试时,有时会定位不到某些元素,是因为这些元素在frame中,所以必须先进入到frame中,才能再去定位要定位的元素. frame是页面的框架,即在一个浏览器的窗口显示多个页面,可以是水平框架和 ...

  7. Longest Subsequence CodeForces - 632D (lcm)

    大意: 给定序列$a$, 求选出最长的一个子序列, 使得lcm不超过m. 刚开始想复杂了, 想着枚举gcd然后背包, 这样复杂度就是$O(\sum\limits_{i=1}^m \frac{m\sig ...

  8. 利用aopc创建schema失败

    执行neo4j-graph-algorithms的例子,运行以下代码报错: CALL apoc.schema.assert( {Category:['name']}, {Business:['id'] ...

  9. RabbitMQ入门教程(十四):RabbitMQ单机集群搭建

    原文:RabbitMQ入门教程(十四):RabbitMQ单机集群搭建 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://b ...

  10. Jquery复习(六)之remove()易忘点和trigger()

    过滤被删除的元素 jQuery remove() 方法也可接受一个参数,允许您对被删元素进行过滤. 该参数可以是任何 jQuery 选择器的语法. 下面的例子删除 class="italic ...