JPQL-Query查询实例详解

前面学习了JPQL语言和Query接口。这里学习一下如果通过JPQL和Query接口进行数据的查询、更新和删除。

【1】普通查询

首先说明一下FROM子句和Select…FROM。

  • from 子句是查询语句的必选子句。

  • Select 用来指定查询返回的结果实体或实体的某些属性。

  • From 子句声明查询源实体类,并指定标识符变量(相当于SQL表的别名)。

如果不希望返回重复实体,可使用关键字 distinct 修饰。select、from 都是 JPQL 的关键字,通常全大写或全小写,建议不要大小写混用。

代码实例如下:

@Test
public void testHelloJPQL(){String jpql = "select c FROM Customer c WHERE c.age > ?";Query query = (Query) entityManager.createQuery(jpql);//占位符的索引是从 1 开始query.setParameter(1, 1);List<Customer> customers = query.getResultList();System.out.println(customers.size());
}

控制台输出如下:

这里写图片描述

可以看到就是一条普通的查询语句。

但是在写JPQL时,需要注意,这一切面向对象。即对象+属性相当于表+列,可以联想一下Hibernate的HQL语言。

如果不写 select 而是直接使用from子句,表明获取对象的全部属性。

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

需要注意的是查询一个对象的所有属性时,并不能像MySQL那样使用 * 号标志。下面语句是错误的,不符合JPQL的规范。

select * FROM Customer c WHERE c.age > ?

当然,你可以查询部分属性

默认情况下, 若只查询部分属性, 则将返回 Object[] 类型的结果. 或者 Object[] 类型的 List。
.
也可以在实体类中创建对应的构造器, 然后再 JPQL 语句中利用对应的构造器返回实体类的对象.

代码实例如下:

@Test
public void testPartlyProperties(){String jpql = "SELECT c.lastName, c.age FROM Customer c WHERE c.id > ?";List result = entityManager.createQuery(jpql).setParameter(1, 1).getResultList();System.out.println(result);Object[] objects = (Object[]) result.get(0);System.out.println(objects[0]);
}

控制台输出如下:

这里写图片描述

可以看到,获取到的list是一个list<object[]>,解析起来是比较麻烦的。故而,我们更希望使用如下方式:

@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);}

控制台输出如下:

这里写图片描述

这样获取到的是list<Customer>,这样解析起来就很友好了。

【2】createNamedQuery和createNativeQuery

① createNamedQuery 适用于在实体类前使用 @NamedQuery 标记的查询语句。

代码示例如下:

@NamedQuery(name="testNamedQuery", query="FROM Customer c WHERE c.id = ?")
@Cacheable(true)
@Table(name="jpa_cutomers")
@Entity
public class Customer {private Integer id;private String lastName;private String email;private int age;private Date createdTime;private Date birth;public Customer() {}
//...
}

测试代码实例如下:

@Test
public void testNamedQuery(){Query query = entityManager.createNamedQuery("testNamedQuery").setParameter(1, 3);Customer customer = (Customer) query.getSingleResult();System.out.println(customer);
}

控制台输出如下:

这里写图片描述

② createNativeQuery 适用于本地 SQL

即,你可以像MySQL那样写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);
}

控制台输出如下:

这里写图片描述

【3】(Hibernate)查询缓存

什么是查询缓存?参考博文Hibernate查询缓存应用实例

① 不使用查询缓存

多次查询同条语句,代码实例如下:

@Test
public void testQueryCache(){
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());query = entityManager.createQuery(jpql);
//占位符的索引是从 1 开始
query.setParameter(1, 1);
customers = query.getResultList();
System.out.println(customers.size());
}

控制台输出如下:

这里写图片描述

② 使用查询缓存

persistence.xml配置如下:

<!-- 二级缓存相关 -->
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory"/>
<!--  这里表明使用查询缓存 -->
<property name="hibernate.cache.use_query_cache" value="true"/>

代码实例如下:

@Test
public void testQueryCache(){String jpql = "FROM Customer c WHERE c.age > ?";// QueryHints.HINT_CACHEABLE设置为trueQuery 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());
}

控制台输出如下:

这里写图片描述

【4】更新和删除

JPQL的更新和删除主要 用的是query.executeUpdate()方法;

代码实例如下:

@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();
}

控制台输出如下:

这里写图片描述

删除同上。

【5】order by,group by 和having子句

JPQL是面向对象的,和hibernate一致。此外,像排序、分组等和普通MySQL并无差异。

group by 子句用于对查询结果分组统计,通常需要使用聚合函数。

常用的聚合函数主要有 AVG、SUM、COUNT、MAX、MIN 等,它们的含义与SQL相同。

例如:

select max(o.id) from Orders o

没有 group by 子句的查询是基于整个实体类的,使用聚合函数将返回单个结果值,可以使用Query.getSingleResult()得到查询结果。

例如:

Query query = entityManager.createQuery("select max(o.id) from Orders o");
Object result = query.getSingleResult();
Long max = (Long)result;

group by实例:

//查询 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);
}

Having 子句用于对 group by 分组设置约束条件,用法与where 子句基本相同。

不同是 where 子句作用于基表或视图,以便从中选择满足条件的记录;having 子句则作用于分组,用于选择满足条件的组,其条件表达式中通常会使用聚合函数。


order by 实例:

@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());
}

order by子句用于对查询结果集进行排序。和SQL的用法类似,可以用 “asc“ 和 "desc“ 指定升降序。

如果不显式注明,默认为升序。

【6】关联查询与Fetch

在JPQL中,很多时候都是通过在实体类中配置实体关联的类属性来实现隐含的关联(join)查询。

例如:

select o from Orders o where o.address.streetNumber=2000 

上述JPQL语句编译成以下SQL时就会自动包含关联,默认为左关联。

在某些情况下可能仍然需要对关联做精确的控制。为此,JPQL 也支持和 SQL 中类似的关联语法。

如:

left out join / left join 
inner join 
left join / inner join fetch 

其中,left join和left out join等义,都是允许符合条件的右边表达式中的实体为空。

左外连接实例如下:

@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, 7).getSingleResult();System.out.println(customer.getLastName());System.out.println(customer.getOrders().size());
}

控制台输出如下:

这里写图片描述

需要注意的是,这里JPQL用到了FETCH。如果不加FETCH呢?

代码实例如下:

@Test
public void testLeftOuterJoinFetch(){String jpql = "FROM Customer c LEFT OUTER JOIN  c.orders WHERE c.id = ?";List<Object[]> result = entityManager.createQuery(jpql).setParameter(1, 7).getResultList();System.out.println(result);
}

控制台输出如下:

这里写图片描述

“fetch”连接允许仅仅使用一个选择语句就将相关联的对象或一组值的集合随着他们的父对象的初始化而被初始化。

在默认的查询中,Entity中的集合属性默认不会被关联,集合属性默认是延迟加载( lazy-load )。那么,left fetch/left out fetch/inner join fetch提供了一种灵活的查询加载方式来提高查询的性能。

综上,在使用JPQL语言时 ,需要时刻记得和hibernate一致–面向对象。如果你使用的Query为createNativeQuery,才可以像使用普通MySQL一样进行数据操作。

【7】子查询

JPQL也支持子查询,在 where 或 having 子句中可以包含另一个查询。

当子查询返回多于 1 个结果集时,它常出现在 any、all、exist s表达式中用于集合匹配查询。

它们的用法与SQL语句基本相同。

子查询实例如下:

@Test
public void testSubQuery(){//查询所有 Customer 的 lastName 为 YY 的 OrderString 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());
}

控制台输出如下:

这里写图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/143488.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

JPQL和SQL的比较

前言 在JAVA EE中&#xff0c;JPQL是专门为Java 应用程序访问和导航实体实例设计的。Java Presistence Query Language(JPQL)&#xff0c;java持久性查询语言。它是JPA规范的重要组成部分&#xff0c;其实它就是一种查询语言&#xff0c;语法类似于SQL语法&#xff0c;但是有着…

【JPQL】--JPQL和SQL的比较

前言 在JAVA EE中&#xff0c;JPQL是专门为Java 应用程序访问和导航实体实例设计的。Java Presistence Query Language(JPQL)&#xff0c;java持久性查询语言。它是JPA规范的重要组成部分&#xff0c;其实它就是一种查询语言&#xff0c;语法类似于SQL语法&#xff0c;但是有着…

JPQL

JPQL&#xff08;JavaPersistence Query Language&#xff09;&#xff0c;是基于实体的查询&#xff0c;所查询的内容都是实体或实体属性。 1、查询实体 SELECT c FROM Customer c JPQL语句与SQL基本类似&#xff0c;但它是基于实体的查询。在初次使用时&#xff0c;需要注…

JPQL查询

JPQL查询 1 jpql的介绍 sql&#xff1a;查询的是表和表中的字段。 jpql&#xff1a;查询的是实体类和类中的属性。 jpql和sql语句的语法相似。 JPQL全称Java Persistence Query Language 基于首次在EJB2.0中引入的EJB查询语言(EJB QL),Java持久化查询语言(JPQL)是一种可移植的…

JPQL详解

前提 最近在改bug的时候发现了自己的缺点&#xff0c;在改前端bug的时候非常顺利顺手。但是在改后端bug的时候如果遇到不是太难的问题还可以解决&#xff0c;但是一到难点感觉自己就懵逼&#xff01; 所以讲解了关于JPQl相关内容 JPA 在说jpql之前必须要说一下什么是JPA&…

JPA(4) JPQL一些简单的查询语法

JPQL --> JPA Query Language --> JPA的查询语句 (另外HQL:Hibernate的查询语句) JPQL本质&#xff1a;JPA通过antlr-2.7.7.jar将JPQL编译成sql并且封装执行的。 JPQL和SQL区别&#xff1f;&#xff1f; --> 它们查询的关键字都是一样的&#xff…

6月3号抖音显示服务器维护中,抖音搜索功能升级维护 期间无法进行用户搜索

这两天有很多小伙伴说抖音上的搜索功能搜不到人了&#xff0c;这是怎么回事呢&#xff1f;其实&#xff0c;这两天&#xff0c;抖音的搜索功能正在升级维护&#xff0c;所以导致搜索功能暂时无法使用。 类别&#xff1a;影音娱乐 大小&#xff1a;210.36M 语言&#xff1a…

java抖音获取用户信息失败_为什么抖音用id搜不到用户?抖音用id搜不到用户的原因与解决方法...

在抖音短视频上&#xff0c;网友可以通过抖音id来搜索指定的抖音用户&#xff0c;并添加为好友&#xff0c;不过&#xff0c;这几天&#xff0c;不断有网友反映一个问题&#xff0c;那就是&#xff1a;抖音用id搜不到用户&#xff0c;那么&#xff0c;为什么抖音用id搜不到用户…

【已解决】抖音如何取消关注已注销的账户

文章目录 1. 按2. 操作步骤 1. 按 我们有时候会发现自己的关注列表里有一些用户显示该用户已注销&#xff0c;这时我们想取消关注&#xff0c;但是却发现没有取消关注按钮&#xff0c;怎么办呢&#xff1f;其实我们可以记下这个账号的名字&#xff0c;然后到关注列表的最上方搜…

最近抖音上虚拟元宇宙项目-猜歌名,代码解析

介绍一下最近抖音上元宇宙虚拟项目猜歌名&#xff0c;直播游戏。用户互动猜歌名&#xff0c;30秒后自动切歌。 CSDN项目源码&#xff1a;https://download.csdn.net/download/u010978757/85326344 类似的弹幕互动游戏除了猜歌名&#xff0c;还有挤地铁、广场舞和舞厅蹦迪的&a…

抖音小店无货源是不是在割韭菜?

哈喽&#xff0c;大家好&#xff0c;我是布丁。 最近很多小伙伴私信布丁&#xff0c;问抖音小店无货源是不是在割韭菜? 今天布丁腾出了些时间&#xff0c;来和小伙伴们分享一下抖音小店无货源。希望能帮助小伙伴解决问题。 抖音小店 抖音小店依托抖音&#xff0c;所以会获得…

抖音快手短视频如何快速上热门

抖音快手短视频怎么上热门?这是许多抖友的一个烦恼! 抖音快手短视频怎么上热门?这也是许多都有的一个梦想! 抖音快手短视频怎么火&#xff0c;抖音快手短视频怎么上热门&#xff0c;相信玩抖音快手短视频的人都想知道其中的技巧。今天我们就把最详细的教程分享给大家。 下面分…

抖音小店无货源怎么做?具体步骤讲解,经验分享

哈喽&#xff0c;大家好&#xff0c;我是布丁。 废话不多说&#xff0c;直接上干货。 抖音小店无货源是什么&#xff1f; 抖音小店就是在抖音上开一家小店&#xff0c;抖音小店是一个电商平台&#xff0c;无货源是一种操作模式。 无货源模式就是在网上采集其他店铺的商品&a…

抖音快手短视频剪辑工具

新媒体短视频运营中短视频制作是较为重要的一环&#xff0c;而短视频制作时选择一款适合的短视频剪辑工具会达到事半功倍的效果&#xff0c;你的短视频需要深入用户内心&#xff0c;契合短视频自身的特色和要求&#xff0c;否则吐血写的脚本、拍完视频信心满满准备剪视频打开电…

抖音快手短视频平台营销技巧

随着碎片化的加剧&#xff0c;短视频平台依靠其时长短、数据流量的优势持续吸引大量用户。而今年的疫情危机&#xff0c;给社会带来了非常大的影响。在这次疫情中&#xff0c;在承担社会责任的同时&#xff0c;抖音快手短视频平台的逆转营销也是做得很成功&#xff0c;这种平台…

抖音快手短视频推广方式

之前的快手短视频主要集中在三四线城市以及农村等消费力不强的用户群体上&#xff0c;没能有力的抓住主流用户的眼光;如今在一二线城市大放异彩的抖音短视频让厂商们再也无法无视短视频对于用户的吸引力。有了短视频这一全新渠道&#xff0c;怎么更为有效的利用渠道成了各级厂商…

抖音短视频运营指南

最初在中国的视频分享应用程序刚刚在全球激增&#xff0c;成为了2019年全球青年最热的地方。而且&#xff0c;在人群中&#xff0c;品牌营销人员紧跟它的步伐。但是抖音并不是您常规的即插即用营销平台&#xff0c;因为它的用户具有很高的洞察力&#xff0c;任何感觉不到“真实…

当年轻人开始拼命戒抖音

原创 | 开菠萝财经 作者 | 金玙璠 编辑 | 瑟曦 “再玩一次就戒掉抖音。” “戒抖音第X天。” “有没有戒掉抖音的好方法&#xff1f;我又‘复吸’了。” 就像不知道何时对抖音上瘾一样&#xff0c;不知道从什么时候起&#xff0c;越来越多年轻人开始寻求戒掉抖音的方法&#xf…

云媒易:抖音短视频推广小技巧汇总

很多企业和品牌做短视频推广的关键是提高自身形象和产品曝光度&#xff0c;让更多的消费者认识到自己的品牌和产品&#xff0c;甚至进一步将其转化为粉丝和客户。那怎么去做短视频推广&#xff0c;这些技巧请你先明白。 1、做短视频要有的3种心态。第一&#xff0c;all in心态&…

抖音直播新号怎么起号?抖音直播间不进人怎么办?

对于抖音直播新号起号来说&#xff0c;最大的困扰就是直播间不进人、人来了留不住、场观高但是没转化&#xff0c;那么如何才能让抖音直播间顺利渡过冷启动期呢&#xff1f;抖音直播间起号的3个小技巧看好了&#xff01; 1.快速打标签&#xff0c;找到精准目标人群 抖音标签是…