JPQL(JPA的查询语句)

一JPQL和SQL

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

二、JPQL书写规则

JPA的查询语言,类似于sql

  • 1.里面不能出现表名,列名,只能出现java的类名,属性名,区分大小写
  • 2.出现的sql关键字是一样的意思,关键字不区分大小写
  • 3.不能写select * 要写select 别名

三、JPQL的简单查询

package cn.itsource.test;

import cn.itsource.pojo.Department;
import cn.itsource.pojo.Employee;
import cn.itsource.pojo.Project;
import cn.itsource.utils.JpaUtils;
import org.junit.Test;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

public class JpqlTest {

    /**
     * 2.2.1.查询所有员工【查询实体类型】
     * @throws Exception
     */
    @Test
    public void test01() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //创建Query对象
        Query query = entityManager.createQuery("from Employee");

        query.getResultList().forEach(e -> System.out.println(e));

        JpaUtils.close(entityManager);
    }


    /**
     * 2.2.2.查询所有员工的姓名和所属部门名称【查询特定属性】
     * @throws Exception
     */
    @Test
    public void test02() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //创建Query对象
        //如果使用连表查询就不能使用逗号那种【不能使用隐式内连接】
        //String jpql = "select e.name,d.name from Employee e join e.department d";
        String jpql = "select e.name,e.department.name from Employee e";
        Query query = entityManager.createQuery(jpql);

        //当你查询的内容不是某个实体类中所有字段的时候,结果就不能封装成实体类对象,List的泛型不能写实体类类型,而是Object[]
        //java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to cn.itsource.pojo.Employee
        List list = query.getResultList();

        list.forEach(e -> System.out.println(Arrays.asList(e)));

        JpaUtils.close(entityManager);
    }

    /**
     * 查询出所有在成都和广州工作的员工【查询结果过滤】
     * @throws Exception
     */
    @Test
    public void test03() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //创建Query对象
        //如果使用连表查询就不能使用逗号那种【不能使用隐式内连接】
        //String jpql = "select e from Employee e where e.department.city = '成都' or e.department.city = '广州'";

        //String jpql = "select e from Employee e where e.department.city in ('成都','广州')";

        //查询条件不应该在这里直接写死,而是今后在项目是通过前端表单提交
        //String jpql = "select e from Employee e where e.department.city in (?,?)";

        //可以在问号后面跟一个整数,指定编号【推荐使用】
        String jpql = "select e from Employee e where e.department.city in (?1,?2)";

        //还支持使用:变量 方式代替 ? 来作为占位符,设置参数的时候就通过变量名称来设置[不常用,知道就行了]
        //String jpql = "select e from Employee e where e.department.city in (:city1,:city2)";


        Query query = entityManager.createQuery(jpql);
        //有问号必须设置参数【编号是从1开始,与JDBC的PreparedStatement不同】
        query = query.setParameter(1, "成都");
        query = query.setParameter(2, "广州");

        List list = query.getResultList();

        list.forEach(e -> System.out.println(e));

        JpaUtils.close(entityManager);
    }


    /**
     * 2.2.4.查询出所有员工信息,按照月薪排序【查询排序】
     * @throws Exception
     */
    @Test
    public void test04() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //创建Query对象[排序与SQL的排序没有任何区别]
        String jpql = "select e from Employee e order by e.salary desc";

        Query query = entityManager.createQuery(jpql);


        List list = query.getResultList();

        list.forEach(e -> System.out.println(e));

        JpaUtils.close(entityManager);
    }

    /**
     * 查询出所有员工信息,按照部门编号排序【使用关联对象的属性排序】
     * @throws Exception
     */
    @Test
    public void test05() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //创建Query对象[排序与SQL的排序没有任何区别]
        String jpql = "select e from Employee e order by e.department.sn asc";

        Query query = entityManager.createQuery(jpql);


        List list = query.getResultList();

        list.forEach(e -> System.out.println(e));

        JpaUtils.close(entityManager);
    }


    /**
     * 查询出在恩宁路和八宝街上班的员工信息【使用IN】
     * @throws Exception
     */
    @Test
    public void test06() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //创建Query对象[排序与SQL的排序没有任何区别]
        String jpql = "select e from Employee e where e.department.street in (?1, ?2)";

        Query query = entityManager.createQuery(jpql);

        //设置参数
        query = query.setParameter(1, "恩宁路").setParameter(2, "八宝街");

        List list = query.getResultList();

        list.forEach(e -> System.out.println(e));

        JpaUtils.close(entityManager);
    }


    /**
     * 2.2.7.查询出工资在5000-6000的员工【使用BETWEEN..AND..】
     * @throws Exception
     */
    @Test
    public void test07() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //创建Query对象[排序与SQL的排序没有任何区别]
        String jpql = "select e from Employee e where e.salary between ?1 and ?2";

        Query query = entityManager.createQuery(jpql);

        //设置参数[java.lang.IllegalArgumentException: Parameter value [5000] did not match expected type [java.math.BigDecimal]
        query = query.setParameter(1, new BigDecimal(5000)).setParameter(2, new BigDecimal(6000));

        List list = query.getResultList();

        list.forEach(e -> System.out.println(e));

        JpaUtils.close(entityManager);
    }

    /**
     * 查询出姓名包含er或者en的员工【使用LIKE】
     * @throws Exception
     */
    @Test
    public void test08() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //创建Query对象[排序与SQL的排序没有任何区别]
        String jpql = "select e from Employee e where e.name like ?1 or e.name like ?2";

        Query query = entityManager.createQuery(jpql);

        //设置参数[如果是模糊查询,不要加单引号]
        query = query.setParameter(1, "%er%").setParameter(2, "%en%");

        List list = query.getResultList();

        list.forEach(e -> System.out.println(e));

        JpaUtils.close(entityManager);
    }


    /**
     * 查询出有员工的部门【distinct】
     * @throws Exception
     */
    @Test
    public void test09() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //创建Query对象
        String jpql = "select distinct e.department.name from Employee e";

        Query query = entityManager.createQuery(jpql);

        List list = query.getResultList();

        list.forEach(e -> System.out.println(e));

        JpaUtils.close(entityManager);
    }


    /**
     * 查询出有员工的部门【size】
     *  1)只有集合变量才能使用size【双向多对多的两方、双向一对多/多对一的一方】
     *  2)size可以用来作为判断条件、可以用来排序、可以用作查询结果
     * @throws Exception
     */
    @Test
    public void test10() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //从员工去找部门,找到的部门就一定是有员工的部门
        //String jpql = "select distinct e.department from Employee e";

        //从部门找员工,判断该部门的员工人数大于0
        String jpql = "select d from Department d where d.employees.size > 0";

        Query query = entityManager.createQuery(jpql);

        List list = query.getResultList();

        list.forEach(e -> System.out.println(e));

        JpaUtils.close(entityManager);
    }

    /**
     * 查询出部门信息,按照部门的员工人数排序【使用函数排序】
     * @throws Exception
     */
    @Test
    public void test11() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

     
        String jpql = "select d from Department d order by d.employees.size";

        Query query = entityManager.createQuery(jpql);

        List list = query.getResultList();

        list.forEach(e -> System.out.println(e));

        JpaUtils.close(entityManager);
    }

    /**
     * 查询出没有员工参与的项目【对集合使用size】
     * @throws Exception
     */
    @Test
    public void test12() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //从部门找员工,判断该部门的员工人数大于0
        String jpql = "select p from Project p where p.employees.size = 0";

        Query query = entityManager.createQuery(jpql);

        List list = query.getResultList();

        list.forEach(e -> System.out.println(e));

        JpaUtils.close(entityManager);
    }


    /**
     * 查询每个部门名称以及员工人数【对集合使用size】
     * @throws Exception
     */
    @Test
    public void test13() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        String jpql = "select p.name, p.employees.size from Department p";

        Query query = entityManager.createQuery(jpql);

        List list = query.getResultList();

        list.forEach(e -> System.out.println(Arrays.asList(e)));

        JpaUtils.close(entityManager);
    }


    /**
     * 查询出所有员工姓名及部门名称【JOIN/LEFT JOIN】
     * @throws Exception
     */
    @Test
    public void test14() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //使用了隐式内连接
        //String jpql = "select e.name, e.department.name from Employee e";

        //使用显式内连接
        //String jpql = "select e.name, d.name from Employee e inner join e.department d";

        //使用左外连接
        //String jpql = "select e.name, d.name from Employee e left join e.department d";

        //使用右外连接
        String jpql = "select e.name, d.name from Department d right join d.employees e";


        Query query = entityManager.createQuery(jpql);

        List list = query.getResultList();

        list.forEach(e -> System.out.println(Arrays.asList(e)));

        JpaUtils.close(entityManager);
    }

    /**
     * 查询出市场部员工信息及电话
     * @throws Exception
     */
    @Test
    public void test15() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //JPQL中从某个实体类开始查询,然后通过该别名.属性.属性.属性....
        String jpql = "select p.employee.name, p.number from Phone p where p.employee.department.name = ?1";


        Query query = entityManager.createQuery(jpql);

        List list = query.setParameter(1, "市场部").getResultList();

        list.forEach(e -> System.out.println(Arrays.asList(e)));

        JpaUtils.close(entityManager);
    }


    /**
     * 各个  每个
     * 查询出每个部门员工的平均工资和最高工资【使用聚集函数】
     * @throws Exception
     */
    @Test
    public void test16() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //JPQL中从某个实体类开始查询,然后通过该别名.属性.属性.属性....
        String jpql = "select e.department.name, max(e.salary), avg(e.salary) from Employee e group by e.department.name";


        Query query = entityManager.createQuery(jpql);

        List list = query.getResultList();

        list.forEach(e -> System.out.println(Arrays.asList(e)));

        JpaUtils.close(entityManager);
    }


    /**
     * 查询出各个项目参与人数报表
     * @throws Exception
     */
    @Test
    public void test17() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //JPQL中从某个实体类开始查询,然后通过该别名.属性.属性.属性....
        //String jpql = "select p.name,p.employees.size from Project p";
        String jpql = "select p.name,count(e.name) from Project p left join p.employees e group by p.name";


        Query query = entityManager.createQuery(jpql);

        List list = query.getResultList();

        list.forEach(e -> System.out.println(Arrays.asList(e)));

        JpaUtils.close(entityManager);
    }


    /**
     * 子查询:查询出大于平均工资的员工信息
     * @throws Exception
     */
    @Test
    public void test18() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //JPQL中从某个实体类开始查询,然后通过该别名.属性.属性.属性....
        String jpql = "select e from Employee e where e.salary > (select avg(ee.salary) from Employee ee)";

        Query query = entityManager.createQuery(jpql);

        List list = query.getResultList();

        list.forEach(e -> System.out.println(e));

        JpaUtils.close(entityManager);
    }


    /**
     * 查员工,每页展示10行数据
     * @throws Exception
     */
    @Test
    public void test19() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //JPQL中从某个实体类开始查询,然后通过该别名.属性.属性.属性....
        String jpql = "select e from Employee e";

        Query query = entityManager.createQuery(jpql);

        /**
         * setFirstResult:相当于填写limit后面的第一个问号的值  (pageNo - 1) * pageSize
         * setMaxResults:相当于填写limit后面的第二个问号的值 pageSize
         * 支持所有数据库产品
         * pageNo和pageSize都需要你从前端请求中传递到Controller中,然后再传递到DAO层
         */
        query = query.setFirstResult(10).setMaxResults(10);


        List list = query.getResultList();

        list.forEach(e -> System.out.println(e));

        JpaUtils.close(entityManager);
    }


    /**
     * 查员工,每页展示10行数据--查总行数
     * @throws Exception
     */
    @Test
    public void test20() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        //JPQL中从某个实体类开始查询,然后通过该别名.属性.属性.属性....
        String jpql = "select count(e) from Employee e";

        Query query = entityManager.createQuery(jpql);

        //查询count()统计结果一定是单行单列值,需要使用getSingleResult来提取数据  Single表示单例
        //得到的结果就是一个Long类型整数
        Long total = (Long)query.getSingleResult();

        System.out.println("总共有 " + total + " 行数据");

        JpaUtils.close(entityManager);
    }


    /**
     * 执行原生SQL
     *  1)创建createNativeQuery
     *  2)可以指定查询结果的封装类型
     *  3)其他用法都与JPQL一致
     * @throws Exception
     */
    @Test
    public void test21() throws Exception {
        EntityManager entityManager = JpaUtils.getEntityManager();

        String sql = "select * from employee where name like ?1";

        //创建NativeQuery
        //Query nativeQuery = entityManager.createNativeQuery(sql);
        Query nativeQuery = entityManager.createNativeQuery(sql, Employee.class);

        //不加单引号
        nativeQuery.setParameter(1, "%en%");

        //查询的结果集,默认将每一行封装一个Object[]进行返回
        List list = nativeQuery.getResultList();

        list.forEach(e -> System.out.println(e));

        JpaUtils.close(entityManager);
    }

}

 
  

pojo:
Department.java

package cn.itsource.pojo;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name="department")
public class Department {


    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private String provice;//省
    private String city;//城市
    private String street;

    //多个部门被同一个部门经理管理【单向多对一】
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="manager_id")
    private Employee manager;//经理

    private String sn;//序列号

    //当前部门下的员工集合
    @OneToMany(fetch = FetchType.LAZY,mappedBy = "department")//放弃维护关系
    private List employees = new ArrayList<>();

    public List getEmployees() {
        return employees;
    }

    public void setEmployees(List employees) {
        this.employees = employees;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getProvice() {
        return provice;
    }

    public void setProvice(String provice) {
        this.provice = provice;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public Employee getManager() {
        return manager;
    }

    public void setManager(Employee manager) {
        this.manager = manager;
    }

    public String getSn() {
        return sn;
    }

    public void setSn(String sn) {
        this.sn = sn;
    }

    @Override
    public String toString() {
        return "Department{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", provice='" + provice + '\'' +
                ", city='" + city + '\'' +
                ", street='" + street + '\'' +
                ", sn='" + sn + '\'' +
                '}';
    }
}

Employee.java

package cn.itsource.pojo;

import javax.persistence.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Entity
@Table(name="employee")
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;

    //多个员工属于同一个部门【单向多对一】
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="department_id")
    private Department department;

    private BigDecimal salary;//薪水
    private Date hireDate;//雇佣日期

    //一个项目有多个开发人员,一个开发人员开发多个项目【单向多对多】
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name="project_employee",
        joinColumns = {@JoinColumn(name="EMPLOYEE_ID")},
        inverseJoinColumns = {@JoinColumn(name="PROJECT_ID")}
    )
    private List projects = new ArrayList<>();

    public List getProjects() {
        return projects;
    }

    public void setProjects(List projects) {
        this.projects = projects;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    public BigDecimal getSalary() {
        return salary;
    }

    public void setSalary(BigDecimal salary) {
        this.salary = salary;
    }

    public Date getHireDate() {
        return hireDate;
    }

    public void setHireDate(Date hireDate) {
        this.hireDate = hireDate;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", salary=" + salary +
                ", hireDate=" + hireDate +
                ", department_id=" + department.getSn() +
                '}';
    }
}

Phone.java

package cn.itsource.pojo;

import javax.persistence.*;

@Entity
@Table(name="phone")
public class Phone {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String types;//类型
    private String number;

    //多个电话属于同一个员工【单向多对一】
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="employee_id")
    private Employee employee;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTypes() {
        return types;
    }

    public void setTypes(String types) {
        this.types = types;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public Employee getEmployee() {
        return employee;
    }

    public void setEmployee(Employee employee) {
        this.employee = employee;
    }
}

Project.java

package cn.itsource.pojo;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name="project")
public class Project {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;

    //多个项目被同一个项目经理管理【单向多对一】
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="manager_id")
    private Employee manager;

    @ManyToMany(fetch = FetchType.LAZY,mappedBy = "projects")
    private List employees = new ArrayList<>();

    public List getEmployees() {
        return employees;
    }

    public void setEmployees(List employees) {
        this.employees = employees;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Employee getManager() {
        return manager;
    }

    public void setManager(Employee manager) {
        this.manager = manager;
    }

    @Override
    public String toString() {
        return "Project{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

你可能感兴趣的:(学习)