文章目录

  • Day39 JPQL
    • jpql概念
      • JPQL书写规则
    • 案例
    • 事务并发(乐观锁)
      • 事务4个特性
      • 事务并发
      • 隔离机制
      • 事务并发带来的问题
        • 第一类丢失更新:(在秒杀场景会出现问题)
        • 脏读
        • 虚读(幻读)
        • 不可重复读
        • 第二类丢失更新
      • 数据库的隔离级别

Day39 JPQL

jpql概念

JPQL语句是面向对象的查询语言

  1. JPQL和SQL很像,查询关键字都是一样的
  2. 唯一的区别是:JPQL是面向对象的

JPQL书写规则

JPA的查询语言,类似于sql

  1. 里面不能出现表名,列名,只能出现java的类名,属性名,区分大小写

  2. 出现的sql关键字是一样的意思,不区分大小写

  3. 不能写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";

  • 查询出所有在成都和广州工作的员工【查询结果过滤】
    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中多表查询注意事项:
      1. 如果要连接多表,并不是连接多个domain,而是连接的属性
      2. 不需要使用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=?";

  • 查询出各个部门员工的平均工资和最高工资【使用聚集函数】

    • 聚合函数

      1. sum
      2. count
      3. avg
      4. min
      5. 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相关推荐

  1. 配置郭神的LitePal(面向对象一样操作sqlite数据库,不再使用SQL语句)

    配置郭神的LitePal(面向对象一样操作sqlite数据库,不再使用SQL语句) 配置过程可见: https://github.com/guolindev/LitePal 但是我要补充一个小问题 然 ...

  2. SQL HQL JPQL CQL的对比

    sql(Structured Query Language)是关系数据库查询语言,面对的数据库;而hql是Hibernate这样的数据库持久化框架提供的内置查询语言,虽然他们的目的都是为了从数据库查询 ...

  3. 后端必备:15000 字的 SQL 语句大全

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | cnblogs.com/liuqifeng/p ...

  4. 从痴迷数据库SQL语句逐渐走进面向对象化(系统的核心以处理对象为主、淡化数据库概念)...

    几年前写信息管理系统都要设计很多很多表,每个表都是自己建立的,然后喜欢用高   性能.高超的SQL语句搞定很多复杂的商业逻辑问题,那SQL语句又长又复杂,一般人   还读不懂,但是代码很少.性能很高, ...

  5. 多对多关联查询sql语句

    1.student,score,coure的实体关联定义如下: -------------------------------------------------------------------- ...

  6. java存储过程与sql语句_存储过程与SQL语句怎么选择

    应用存储过程的优点: 1.具有更好的性能 存储过程是预编译的,只在创建时进行编译,以后每次执行存储过程都不需再重新编译, 而一般 SQL 语句每执行一次就编译一次,因此使用存储过程可以提高数据库执行速 ...

  7. navicat循环执行上下两行相减sql语句_SQL太难?你离完全理解SQL就差这10步!

    - 点击上方"中国统计网"设置⭐星标不迷路!- 很多程序员视 SQL 为洪水猛兽.SQL 是一种为数不多的声明性语言,它的运行方式完全不同于我们所熟知的命令行语言.面向对象的程序语 ...

  8. oracle sql语句大全

    ORACLE支持五种类型的完整性约束NOT NULL (非空)--防止NULL值进入指定的列,在单列基础上定义,默认情况下,ORACLE允许在任何列中有NULL值.CHECK (检查)--检查在约束中 ...

  9. 把Python函数转换成能在SQL语句中调用的函数

    感谢中国传媒大学胡凤国老师提供的案例和第一版代码! 问题描述:把Python函数转换为能在SQLite数据库SQL语句中调用的函数,这样可以大幅度扩展SQL语句的功能. 演示代码: 运行结果: 今天公 ...

最新文章

  1. confluence 卡顿原因总结
  2. boost::mpl模块实现copy_if相关的测试程序
  3. 人工智能+大数据 首个自动驾驶平台诞生
  4. 在Java 8中使用Stream API列出ZIP文件的内容
  5. jQUery中closest和parents的主要区别是
  6. python面向对象编程的语言_怎么使用python面向对象编程
  7. Kali Linux 秘籍 第七章 权限提升
  8. 【Elasticsearch】 es GZIP造成JAVA Native Memory泄漏案例
  9. 特征提取与检测(三) --- ORB算法
  10. 数组的顺序存储和实现
  11. IOS 创建渐变图层
  12. 计算机基础毕业论文排版教程,计算机应用基础Word高级应用—排版毕业论文PPT课件.ppt...
  13. 共享打印机无法连接的解决办法
  14. linux下增加宋体 仿宋 字体
  15. 推荐几个好用的pdf翻译工具
  16. 逐帧动画案例(奔跑的小人)
  17. tp5 微信新版本商家转到到零钱,v3秘钥,平台证书和平台证书序列号
  18. 文本 去除重复行(sublime Text3 ,正则表达式)
  19. 什么模式下不可使用曝光补偿_摄影从零到入门 曝光模式与测光方法详解
  20. 何先振第1期:Java编程入门计算机介绍

热门文章

  1. Python圆面积的计算、简单的人名对话、同切圆的绘制、日期和时间的输出。
  2. 软工实践第四次作业-团队展示
  3. android nfc 配对蓝牙 开发,NFC和蓝牙两种配对方式_配件评测-中关村在线
  4. 雪球产品期权价值蒙特卡洛模拟(2)
  5. hortonworks-registry-0.5.4 : Memory: 4k page, physical 3880928k(308720k free), swap 0k(0k free)
  6. 浅谈对C#-lock()的理解
  7. char 数组java_Java 将char数组复制到另一个char数组
  8. 链表笔记 (前插法 后插法 头插法 尾插法)
  9. ELK安装IK分词器
  10. JAVA利用多线程和Socket制作GUI界面的在线聊天室