框架学习之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. 创建可执行bin安装文件

    [应用场景] 简化操作,对于有些安装操作而言,需要包含安装脚本和脚本需要的文件两部分,封装成可执行bin文件之后就只有一个安装包了. 代码保护,在很多情况下,我们并不希望用户可以直接接触到代码部分,这 ...

  2. ucloud自动创建instance

    用terrform for ucloud: https://www.terraform.io/docs/providers/ucloud/index.html https://docs.ucloud. ...

  3. 解决Linux下SSH超时自动断开

    title: 解决Linux下SSH超时自动断开 comments: false date: 2019-08-19 19:22:55 description: Linux 下 SSH 超时自动断开?? ...

  4. jstat命令使用

    jstat命令使用 jstat是JDK自带的一个轻量级小工具,全称"Java Virtual Machine statistics monitoring tool",它位于java ...

  5. 请求转发forward()和URL重定向redirect()的区别

  6. grunt接触

    grunt使用 以下内容均为已经安装好grunt,具体grunt的安装过程不述,可以参考grunt的相关资料. 1.项目初始化grunt 在项目文件夹的根目录下面,打开命令行grunt init,执行 ...

  7. 84. Largest Rectangle in Histogram (JAVA)

    Given n non-negative integers representing the histogram's bar height where the width of each bar is ...

  8. linux 生成密钥和公钥,实现免密登录

    1. 在相应的用户根目录下生成密钥公钥,输入如下命令: ssh-keygen -t rsa 2. 直接三次回车:会生成两个文件:id_rsa / id_rsa.pub,分别为密钥和公钥 3.  打开公 ...

  9. linux 文件查找 find命令详解

    一,从索引库查找文件:locate 索引库:操作系统会周期性的遍历根文件系统,然后生成索引库 手动更新索引库:updatedb 语法:locate [OPTION]... PATTERN... 只匹配 ...

  10. 调试dcc 试图将u-boot放入ocm运行碰到的问题

    1. 起因: gd->mon_len = (ulong)&__bss_end - (ulong)_start; 在u-boot.map中查找,发现__bss_end并不是u-boot.b ...