框架学习之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. 【神经网络与深度学习】深度学习实战——caffe windows 下训练自己的网络模型

    1.相关准备 1.1 手写数字数据集 这篇博客上有.jpg格式的图片下载,附带标签信息,有需要的自行下载,博客附带百度云盘下载地址(手写数字.jpg 格式):http://blog.csdn.net/ ...

  2. [LeetCode]220. 存在重复元素 III

    题目链接:https://leetcode-cn.com/problems/contains-duplicate-iii/ 题目描述: 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使 ...

  3. 剑指offer-数值的整数次方-调整数组顺序使奇数位于偶数前面-代码的完整性-python

    题目描述 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方.   保证base和exponent不同时为0   思路 求base的expon ...

  4. 解决jenkins的Console Output中文乱码

    1.本地机器设置环境变量(设置后需要注销计算机才能生效) key: JAVA_TOOL_OPTIONS value:-Dfile.encoding=UTF- 2. 通过Jenkins全局设置的方式   ...

  5. Python操作Redis,你要的都在这了!

    Redis是一个基于内存的高效的键值型非关系型数据库,存取效率极高,而且支持多种存储数据结构,使用也非常简单.本节中,我们就来介绍一下Python的Redis操作,主要介绍RedisPy这个库的用法. ...

  6. 5月Linux市场Steam 份额在增长

    随着新的一个月的开始,Valve公布了上个月的软件/硬件调查数据.在2019年5月,Steam Linux的使用率按百分比略微上升. 上个月,运行Linux的Steam用户比例(根据有争议的Steam ...

  7. .NET Framework 2.0/3.0/3.5 以 v90 平台工具集为目标。请确保在计算机上安装了 Visual Studio 2008

    今天在Visual Studio2010下面开发C++应用的时候发现“.NET Framework 2.0/3.0/3.5 以 v90 平台工具集为目标.请确保在计算机上安装了 Visual Stud ...

  8. P1058 立体图题解

    小渊是个聪明的孩子,他经常会给周围的小朋友们将写自己认为有趣的内容.最近,他准备给小朋友们讲解立体图,请你帮他画出立体图. 小渊有一块面积为m \times nm×n的矩形区域,上面有m \times ...

  9. Lengauer-Tarjan算法的相关证明

    Lengauer-Tarjan算法的相关证明 0. 约定 为简单起见,下文中的路径均指简单路径(事实上非简单路径不会对结论造成影响). \(V\)代表图的点集,\(E\)代表图的边集,\(T\)代表图 ...

  10. Linux 性能测试工具Lmbench详解

    Linux 性能测试工具Lmbench详解 2010-06-04 16:07 佚名 评测中心 字号:T | T Lmbench 是一套简易可移植的,符合ANSI/C 标准为UNIX/POSIX 而制定 ...