框架学习之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. oracle 11g sqlplus和plsql developer 乱码解决方案

    ----------------------------------华丽的分隔符---------------------------------- 在cmd终端下运行            中文的话 ...

  2. java读取文件完整版

    public static void readFileByBytes(String fileName) { File file = new File(fileName); InputStream in ...

  3. spring boot 数据源配置YAML格式

    spring: datasource: url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf- ...

  4. [转帖]小米手环采用RISC-V 指令集芯片

    小米手环4或用“黄山一号”芯片,雷军再回前线,未来走向如何 静心科技 06-1111:19 忘记来源地址了 不过国内的很多东西都是有中国特色的 比如飞腾 比如麒麟(银河麒麟 还有华为的麒麟 980) ...

  5. Fescar使用(资料)

    fescar源码走读1:业务调用方 https://zhuanlan.zhihu.com/p/54659540   fescar源码走读2:fescar服务端 https://zhuanlan.zhi ...

  6. Oracle精讲视频课程【价值1.67万】

    ke程链接 https://edu.51cto.com/center/course/lesson/index?id=14443 课程大纲: 0_Oracle学习路线分析(Oracle学习必读)[免费试 ...

  7. C++:string操作函数

    要想使用标准C++中string类,必须要包含 #include <string>// 注意是<string>,不是<string.h>,带.h的是C语言中的头文件 ...

  8. 洛谷 P3386 二分图匹配 题解

    题面 这道题虽然是练习匈牙利算法的,但可以用网络流来切掉它: 我们可以建立一个超级源和一个超级汇,超级源连接左部分点,超级汇连接右部分点: 然后在该图上跑最大流就可以了: PS:我设的超级源是2001 ...

  9. vmware中的虚拟linux配置多块网卡

    在使用vm上运行多个linux系统,来模拟LVS负载均衡实验中.需要在lvs服务器中设置两块网卡,发现可以在vm给虚拟机添加任意多个网卡. 方法: 不要启动Linux,在上面的菜单项中选择: “VM— ...

  10. Executor框架(转)

    摘要:        Executor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相 ...