面向对象的SQL语句——JPQL
文章目录
- Day39 JPQL
- jpql概念
- JPQL书写规则
- 案例
- 事务并发(乐观锁)
- 事务4个特性
- 事务并发
- 隔离机制
- 事务并发带来的问题
- 第一类丢失更新:(在秒杀场景会出现问题)
- 脏读
- 虚读(幻读)
- 不可重复读
- 第二类丢失更新
- 数据库的隔离级别
Day39 JPQL
jpql概念
JPQL语句是面向对象的查询语言
- JPQL和SQL很像,查询关键字都是一样的
- 唯一的区别是:JPQL是面向对象的
JPQL书写规则
JPA的查询语言,类似于sql
里面不能出现表名,列名,只能出现java的类名,属性名,区分大小写
出现的sql关键字是一样的意思,不区分大小写
不能写select * 要写select 别名
SELECT o[o.property,o.property*] FROM Entity o
[WHERE conditions]
[GROUP BY conditions]
[HAVING conditions]
[ORDER BY o.property[ASC|DESC]]
案例
查询所有员工【查询实体类型】
String jpql = "from Employee";
相当于
String jpql = "select o from Employee o";
和String jpql = "select o from cn.itsource.jpa.domain.Employee o";
查询所有员工的姓名和所属部门名称【查询特定属性】
**注意: **在jpql语句中,查询数据的时候,如果查询的数据结果值不能和domain中的属性一一对应,那返回的集合元素应该是Object[]- 集合元素: Obejct[]
String jpql = "select o.name,o.department.name from Employee o";
- 集合元素:对象
String jpql = "select new Employee(o.name,o.department.name) from Employee o";
- 集合元素: Obejct[]
查询出所有在成都和广州工作的员工【查询结果过滤】
String jpql = "select o from Employee o where o.department.city=? or o.department.city=?";
查询出所有员工信息,按照月薪排序【查询排序】
String jpql = "select o from Employee o order by o.salary desc ";
查询出所有员工信息,按照部门编号排序【使用关联对象属性排序】
String jpql = "select o from Employee o order by o.department.id desc ";
查询出在恩宁路和八宝街上班的员工信息【使用IN】
String jpql = "select o from Employee o where o.department.street in(?,?) ";
查询出工资在5000-6000的员工【使用BETWEEN…AND…】
String jpql = "select o from Employee o where o.salary between ? and ?";
查询出姓名包含er或者en的员工【使用LIKE】
String jpql = "select o from Employee o where o.name like ? or o.name like ?";
查询出有员工的部门【distinct】
- 仅仅返回部门名
String jpql = "select distinct o.department.name from Employee o ";
- 返回部门对象
String jpql = "select distinct o.department from Employee o ";
- 仅仅返回部门名
查询出有员工的部门【size】
**注意:**如果你要使用size来查,必须对象中拥有集合 因为对象是没有size的
String jpql = "select o from Department o where o.employees.size>0";
查询出部门信息,按照部门的员工人数排序
String jpql = "select o from Department o order by o.employees.size";
查询出没有员工参与的项目【对集合使用size】
String jpql = "select o from Project o where o.employees.size=0";
查询出所有员工及部门名称【JOIN/LEFT JOIN】
- 多表查询,在jpa中多表查询默认使用是内连接,没有外连接
- 如果你要使用外连接,必须手动的编写sql语句
- 在jpa中多表查询注意事项:
- 如果要连接多表,并不是连接多个domain,而是连接的属性
- 不需要使用on消除笛卡尔积,因为在jpa中它会自动消除笛卡尔积
String jpql = "select o,d.name from Employee o join o.department d";
查询出市场部员工信息及电话
String jpql = "select e,p.number from Phone p join p.employee e join e.department d where d.name=?";
查询出各个部门员工的平均工资和最高工资【使用聚集函数】
- 聚合函数
- sum
- count
- avg
- min
- max
String jpql = "select o.department.name,avg(o.salary),max(o.salary) from Employee o group by o.department.name";
- 聚合函数
查询出各个项目参与人数报表
String jpql = "select p.name,count(e) from Project p left join p.employees e group by p.name";
查询出大于平均工资的员工信息
String jpql = "select o from Employee o where o.salary>(select avg(salary) from Employee)";
分页查询
public void test20(){String jpql = "from Employee";EntityManager entityManager = JPAUtil.openEntityManager();Query query = entityManager.createQuery(jpql);//开始位置 开始条数 = (currentPage-1)*pageSize;query.setFirstResult(5);//每页展示多好条query.setMaxResults(5);//分页查询的列表List<Employee> resultList = query.getResultList();for (Employee employee : resultList) {System.out.println(employee);}String countJpql = "select count(o) from Employee o ";Query query1 = entityManager.createQuery(countJpql);//获取总条数Long count = (Long)query1.getSingleResult();System.out.println(count);}
事务并发(乐观锁)
事务4个特性
- 原子性(atomic),事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行(事务不能被分割,要么都成功要么都失败)
- 一致性(consistent),事务在完成时,必须使所有的数据都保持一致状态。
- 隔离性(insulation),由事务并发所作的修改必须与任何其它并发事务所作的修改隔离。
- 持久性(Duration),事务完成之后,它对于系统的影响是永久性的。
事务并发
通常为了获得更好的运行性能,各种数据库都允许多个事务同时运行,这就是事务并发
隔离机制
当并发的事务访问或修改数据库中相同的数据(同一行同一列)时,通常需要采取必要的隔离机制。
解决并发问题的途径是什么?答案是:采取有效的隔离机制。
怎样实现事务的隔离呢?隔离机制的实现必须使用锁
事务并发带来的问题
JPA只能处理第一、二类丢失更新,其他3种必须由数据库自己处理
第一类丢失更新:(在秒杀场景会出现问题)
库存是1件
当事务A和事务B同时修改某行的值,
1.事务A将数值改为0并提交,购买了一件
2.事务B将数值改为0并提交,也购买了一件。这时数据的值为0,事务A所做的更新将会丢失。(相当于就卖出去2件商品)
解决办法:对行加锁,只允许并发一个更新事务。(JPA中的悲观锁,乐观锁)
脏读
1.张三的原工资为4000, 财务人员将张三的工资改为了8000(但未提交事务)
2.张三读取自己的工资 ,发现自己的工资变为了8000,欢天喜地!(在缓存中读取)
3.而财务发现操作有误,回滚了事务,张三的工资又变为了4000 像这样,张三记取的工资数8000是一个脏数据。
解决办法:如果在第一个事务提交前,任何其他事务不可读取其修改过的值,则可以避免该问题。
虚读(幻读)
目前工资为4000的员工有10人。
1.事务1,读取所有工资为4000的员工。
2.这时事务2向employee表插入了一条员工记录,工资也为4000
3.事务1再次读取所有工资为4000的员工共读取到了11条记录,
解决办法:如果在操作事务完成数据处理之前,任何其他事务都不可以添加新数据,则可避免该问题。
不可重复读
在一个事务中前后两次读取的结果并不致,导致了不可重复读。
1.在事务1中,Mary 读取了自己的工资为1000,操作并没有完成
2.在事务2中,这时财务人员修改了Mary的工资为2000,并提交了事务.
3.在事务1中,Mary 再次读取自己的工资时,工资变为了2000
解决办法:如果只有在修改事务完全提交之后才可以读取数据,则可以避免该问题。
第二类丢失更新
多个事务同时读取相同数据,并完成各自的事务提交,导致最后一个事务提交会覆盖前面所有事务对数据的改变
数据库的隔离级别
MySql默认隔离级别为:Repeatable Read(可能会出现虚读)
Oracle 支持READ COMMITTED 和 SERIALIZABLE这两种事务隔离级别
默认隔离级别为READ COMMITTED
READ UNCOMMITTED 幻想读、不可重复读和脏读都允许。
READ COMMITTED 允许幻想读,不可重复读,不允许脏读
REPEATABLE READ 允许幻想读,不允许不可重复读和脏读
SERIALIZABLE 幻想读、不可重复读和脏读都不允许
面向对象的SQL语句——JPQL相关推荐
- 配置郭神的LitePal(面向对象一样操作sqlite数据库,不再使用SQL语句)
配置郭神的LitePal(面向对象一样操作sqlite数据库,不再使用SQL语句) 配置过程可见: https://github.com/guolindev/LitePal 但是我要补充一个小问题 然 ...
- SQL HQL JPQL CQL的对比
sql(Structured Query Language)是关系数据库查询语言,面对的数据库;而hql是Hibernate这样的数据库持久化框架提供的内置查询语言,虽然他们的目的都是为了从数据库查询 ...
- 后端必备:15000 字的 SQL 语句大全
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | cnblogs.com/liuqifeng/p ...
- 从痴迷数据库SQL语句逐渐走进面向对象化(系统的核心以处理对象为主、淡化数据库概念)...
几年前写信息管理系统都要设计很多很多表,每个表都是自己建立的,然后喜欢用高 性能.高超的SQL语句搞定很多复杂的商业逻辑问题,那SQL语句又长又复杂,一般人 还读不懂,但是代码很少.性能很高, ...
- 多对多关联查询sql语句
1.student,score,coure的实体关联定义如下: -------------------------------------------------------------------- ...
- java存储过程与sql语句_存储过程与SQL语句怎么选择
应用存储过程的优点: 1.具有更好的性能 存储过程是预编译的,只在创建时进行编译,以后每次执行存储过程都不需再重新编译, 而一般 SQL 语句每执行一次就编译一次,因此使用存储过程可以提高数据库执行速 ...
- navicat循环执行上下两行相减sql语句_SQL太难?你离完全理解SQL就差这10步!
- 点击上方"中国统计网"设置⭐星标不迷路!- 很多程序员视 SQL 为洪水猛兽.SQL 是一种为数不多的声明性语言,它的运行方式完全不同于我们所熟知的命令行语言.面向对象的程序语 ...
- oracle sql语句大全
ORACLE支持五种类型的完整性约束NOT NULL (非空)--防止NULL值进入指定的列,在单列基础上定义,默认情况下,ORACLE允许在任何列中有NULL值.CHECK (检查)--检查在约束中 ...
- 把Python函数转换成能在SQL语句中调用的函数
感谢中国传媒大学胡凤国老师提供的案例和第一版代码! 问题描述:把Python函数转换为能在SQLite数据库SQL语句中调用的函数,这样可以大幅度扩展SQL语句的功能. 演示代码: 运行结果: 今天公 ...
最新文章
- confluence 卡顿原因总结
- boost::mpl模块实现copy_if相关的测试程序
- 人工智能+大数据 首个自动驾驶平台诞生
- 在Java 8中使用Stream API列出ZIP文件的内容
- jQUery中closest和parents的主要区别是
- python面向对象编程的语言_怎么使用python面向对象编程
- Kali Linux 秘籍 第七章 权限提升
- 【Elasticsearch】 es GZIP造成JAVA Native Memory泄漏案例
- 特征提取与检测(三) --- ORB算法
- 数组的顺序存储和实现
- IOS 创建渐变图层
- 计算机基础毕业论文排版教程,计算机应用基础Word高级应用—排版毕业论文PPT课件.ppt...
- 共享打印机无法连接的解决办法
- linux下增加宋体 仿宋 字体
- 推荐几个好用的pdf翻译工具
- 逐帧动画案例(奔跑的小人)
- tp5 微信新版本商家转到到零钱,v3秘钥,平台证书和平台证书序列号
- 文本 去除重复行(sublime Text3 ,正则表达式)
- 什么模式下不可使用曝光补偿_摄影从零到入门 曝光模式与测光方法详解
- 何先振第1期:Java编程入门计算机介绍
热门文章
- Python圆面积的计算、简单的人名对话、同切圆的绘制、日期和时间的输出。
- 软工实践第四次作业-团队展示
- android nfc 配对蓝牙 开发,NFC和蓝牙两种配对方式_配件评测-中关村在线
- 雪球产品期权价值蒙特卡洛模拟(2)
- hortonworks-registry-0.5.4 : Memory: 4k page, physical 3880928k(308720k free), swap 0k(0k free)
- 浅谈对C#-lock()的理解
- char 数组java_Java 将char数组复制到另一个char数组
- 链表笔记 (前插法 后插法 头插法 尾插法)
- ELK安装IK分词器
- JAVA利用多线程和Socket制作GUI界面的在线聊天室