JPQL --> JPA Query Language --> JPA的查询语句 (另外HQL:Hibernate的查询语句)
JPQL本质:JPA通过antlr-2.7.7.jar将JPQL编译成sql并且封装执行的。
JPQL和SQL区别?? --> 它们查询的关键字都是一样的,但JPQL是面向对象的(JPQL只能写java的类名和属性名)
JPQL书写规则
JPA的查询语言,类似于sql
①里面不能出现表名,列名,只能出现java的类名,属性名,区分大小写
②出现的sql关键字是一样的意思,不区分大小写
③不能写select * 要写select 别名
JPQL查询语法: ---(面向对象)
查询所有用户【查询实体类型】:
"select o from User o" --> User:类名 o:别名
查询所有用户的姓名和所属部门名称 【查询特定属性】
方式①:"select o.name,o.department.name from User o"
注意:此时接收数据 类型用Object[]数组 --(涉及到查询出多个类里面数据的时候一般都需要使用Object[]数组接收数据!)
ex:List<Object[]> resultList = query.getResultList();
方式②(new一个构造器):"select new User(o.name,o.department.name) from User o"
注意:此时User类里面需要加无参构造和下面
public User(String name, String departmentName) {
this.name = name;
this.department = new Department();
this.department.setName(departmentName);
}
查询出所有在成都和广州工作的人【查询结果过滤】:
方式①:"select o from User o where o.department.city='成都' or o.department.city='广州' "
--> User类里面关联着Department类,Department类里面有city字段
方式②:String jpql = "select o from User o where o.department.city=? or o.department.city=?"
Query query = entityManager.createQuery(jpql);
query.setParameter(1, "成都"); //为JPQL的?设置值 【注意:这里是从1开始计算的】
query.setParameter(2, "广州");
方式③:"select o from User o where o.department.city=?1 or o.department.city=?2"
Query query = entityManager.createQuery(jpql);
//query.setParameter(1, "成都");
//query.setParameter(2, "广州");
query.setParameter(1, "成都").setParameter(2, "广州");
方式④:"select o from User o where o.department.city=:city1 or o.department.city=:city2"
Query query = entityManager.createQuery(jpql);
query.setParameter(1, "成都").setParameter(2, "广州");
查询出所有人信息,按照月薪排序【查询排序】
"select o from User o order by o.salary desc" //desc降序 asc升序
查询出所有人信息,按照部门编号排序【使用关联对象属性排序】
"select o from User o order by o.department.sn"
--> User类里面关联着Department类,Department类里面有sn编号字段
查询出在春熙路和武侯街上班的用户信息【使用IN】
"select o from User o where o.department.street in(?1,?2)"
query.setParameter(1, "春熙路").setParameter(2, "武侯街");
查询出工资在5000-6000的人【使用BETWEEN..AND..】
"select o from User o where o.salary between ?1 and ?2"
查询出姓名包含er或者en的人【使用LIKE】
"select o from User o where o.name like ?1 or o.name like ?2"
query.setParameter(1, "er").setParameter(2, "en");
查询出有用户的部门【distinct去重】
"select distinct o.department from User o"
查询出有人的部门【size】 --注意:在JPQL,所有集合都有一个size属性
"select o from Department o where o.users.size>0"
--> Department类里面用list集合 private List<User> users = new ArrayList<>();
查询出部门信息,按照部门的用户人数排序【使用函数排序】
"select o from Department o order by o.users.size desc"
查询出没有人加入的部门【对集合使用size】
"select o from Department o where o.users.size=0"
查询所有人的姓名和所属部门名称【查询特定属性】
"select o.id,o.name,d.name from User o left join o.department d"
查询出市场部的人员信息及电话:
"select e,p from Phone p join p.user e join e.department d where d.name='市场部'"
查询出各个部门人员的平均工资和最高工资【使用聚集函数GROUP】
"select o.department.name,avg(o.salary),max(o.salary) from User o group by o.department.name"
查询出各个部门参与人数报表:
方式①:"select d,count(e) from Department d left join d.users u group by d"
方式②:"select d,d.users.size from Department d"
查询出大于平均工资的人员信息【子查询】
"select o from User o where o.salary > (select avg(salary) from User )"
注意事项:
①from后面的是一个类名
②如果涉及到查询出的几个值不是对象需要使用Object[]数组接收数据!
③jpql支持 select new User(..) from ...
④where条件传参时
?,? --> 从1开始计算
?1,?2 --> 自己定义顺序
:name1,:name2 --> 自己取名字
⑤ like的时候 ?1 --> query.setParameter(1, "er") --> "%er%"
⑥JPQL中所有集合都有 size属性
⑦JPQL关联(JOIN/LEFT JOIN)
sql:select * 表1 join 表2 on 条件
jpql:两个法则 --> 1.JPQL自己会消除笛卡尔积不写on子句 2.关联 --> 模型 模型的别名 join 写前面模型别名.对象属性
分页查询:
方式①: String jpql = "select o from User o"; Query query = entityManager.createQuery(jpql); //List<Employee> resultList = query.getResultList().subList(0, 5); // -->假分页:从第几条开始,到第几条结束 //query.setFirstResult(0); //从第几条开始 //query.setMaxResults(5); //第页查询多少条数据 query.setFirstResult(0).setMaxResults(5);//可理解为sql的 limit 0,5 -->真分页方式②: String jpql = "select count(o) from User o"; //它查询到的结果有且只有一个值 Query query = entityManager.createQuery(jpql); //System.out.println(query.getResultList()); //System.out.println(query.getResultList().get(0)); Long count = (Long) query.getSingleResult();