第二百七十二节 JPA教程 - JPA查询Is Empty示例

JPA教程 - JPA查询Is Empty示例

IS EMPTY运算符是IS NULL的逻辑等价物,但是对于集合。

查询可以使用IS EMPTY运算符或IS NOT EMPTY来检查集合关联路径是否解析为空集合或至少有一个值。

我们可以使用EMPTY来检查属性是否为空。

以下JPQL显示如何使用EMPTY获取员工withno项目。

Query unassignedQuery = 
    em.createQuery("SELECT e " +
                   "FROM Employee e " +
                   "WHERE e.projects IS EMPTY");

例子

下面的代码来自PersonDaoImpl.java。

package cn.w3cschool.common;

import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.transaction.annotation.Transactional;

@Transactional
public class PersonDaoImpl {
  public void test() {
    Employee emp = new Employee();
    emp.setName("Tom");
    emp.setSalary(123);
    emp.setStartDate(new Date());
    emp.setId(1);

    Project pro = new Project();
    pro.setName("Design");
    pro.getEmployees().add(emp);

    Department dept = new Department();
    dept.setName("Dept");
    dept.getEmployees().add(emp);

    emp.setDepartment(dept);
    emp.getProjects().add(pro);

    em.persist(dept);
    em.persist(pro);
    em.persist(emp);

    String deptName = "Dept";
    String empName = "Tom";

    Query unassignedQuery = 
        em.createQuery("SELECT e " +
                       "FROM Employee e " +
                       "WHERE e.projects IS EMPTY");

     List l =  unassignedQuery.getResultList();
     System.out.println(l);

  }
  public Collection<Employee> findAllEmployees() {
      return (Collection<Employee>) em.createQuery(
              "SELECT e FROM Employee e").getResultList();
  }
  @PersistenceContext
  private EntityManager em;
}

以下代码来自Employee.java。

package cn.w3cschool.common;



import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@NamedQueries({
  @NamedQuery(name="findEmployeesAboveSal",
              query="SELECT e " +
                    "FROM Employee e " +
                    "WHERE e.department = :dept AND " +
                    "      e.salary > :sal"),
  @NamedQuery(name="findHighestPaidByDepartment",
              query="SELECT e " +
                    "FROM Employee e " +
                    "WHERE e.department = :dept AND " +
                    "      e.salary = (SELECT MAX(e2.salary) " +
                    "                  FROM Employee e2 " +
                    "                  WHERE e2.department = :dept)")
})
public class Employee {
    @Id
    private int id;
    private String name;
    private long salary;
    @Temporal(TemporalType.DATE)
    private Date startDate;
    
    @ManyToOne
    private Employee manager;
    
    @OneToMany(mappedBy="manager")
    private Collection<Employee> directs;

    @ManyToOne
    private Department department;
    
    @ManyToMany 
    private Collection<Project> projects;

    public Employee() {
        projects = new ArrayList<Project>();
        directs = new ArrayList<Employee>();
    }

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

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

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

    public void setStartDate(Date startDate) {
      this.startDate = startDate;
    }

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

    public void setDirects(Collection<Employee> directs) {
      this.directs = directs;
    }

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

    public void setProjects(Collection<Project> projects) {
      this.projects = projects;
    }

    public int getId() {
        return id;
    }
    
    public String getName() {
        return name;
    }

    public long getSalary() {
        return salary;
    }

    public Date getStartDate() {
        return startDate;
    }
    
    public Department getDepartment() {
        return department;
    }
    
    public Collection<Employee> getDirects() {
        return directs;
    }
    
    public Employee getManager() {
        return manager;
    }

    public Collection<Project> getProjects() {
        return projects;
    }
    
    public String toString() {
        return "Employee " + getId() + 
               ": name: " + getName() +
               ", salary: " + getSalary() +
               ", dept: " + ((getDepartment() == null) ? null : getDepartment().getName());
    }
}

以下代码来自Project.java。

package cn.w3cschool.common;


import java.util.ArrayList;
import java.util.Collection;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

@Entity
public class Project {
    @Id
    protected int id;
    protected String name;
    @ManyToMany(mappedBy="projects")
    private Collection<Employee> employees;

    public Project() {
        employees = new ArrayList<Employee>();
    }

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

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

    public void setEmployees(Collection<Employee> employees) {
      this.employees = employees;
    }

    public int getId() {
        return id;
    }
    
    public String getName() {
        return name;
    }
    
    public Collection<Employee> getEmployees() {
        return employees;
    }
    
    public String toString() {
        return "Project id: " + getId() + ", name: " + getName();
    }
}

下面的代码来自Department.java。

package cn.w3cschool.common;


import java.util.ArrayList;
import java.util.Collection;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;

@Entity
public class Department {
    @Id
    private int id;
    private String name;
    @OneToMany(mappedBy="department")
    private Collection<Employee> employees;

    public Department() {
        employees = new ArrayList<Employee>();
    }
    
    public void setId(int id) {
      this.id = id;
    }

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

    public void setEmployees(Collection<Employee> employees) {
      this.employees = employees;
    }

    public int getId() {
        return id;
    }
    
    public String getName() {
        return name;
    }
    
    public Collection<Employee> getEmployees() {
        return employees;
    }

    public String toString() {
        return "Department no: " + getId() + 
               ", name: " + getName();
    }
}

上面的代码生成以下结果。

以下是数据库转储。

Table Name: DEPARTMENT
 Row:
    Column Name: ID,
    Column Type: INTEGER:
    Column Value: 0

    Column Name: NAME,
    Column Type: VARCHAR:
    Column Value: Dept





Table Name: EMPLOYEE
 Row:
    Column Name: ID,
    Column Type: INTEGER:
    Column Value: 1

    Column Name: NAME,
    Column Type: VARCHAR:
    Column Value: Tom

    Column Name: SALARY,
    Column Type: BIGINT:
    Column Value: 123

    Column Name: STARTDATE,
    Column Type: DATE:
    Column Value: 2014-12-29

    Column Name: DEPARTMENT_ID,
    Column Type: INTEGER:
    Column Value: 0

    Column Name: MANAGER_ID,
    Column Type: INTEGER:
    Column Value: null





Table Name: EMPLOYEE_PROJECT
 Row:
    Column Name: EMPLOYEES_ID,
    Column Type: INTEGER:
    Column Value: 1

    Column Name: PROJECTS_ID,
    Column Type: INTEGER:
    Column Value: 0





Table Name: PROJECT
 Row:
    Column Name: ID,
    Column Type: INTEGER:
    Column Value: 0

    Column Name: NAME,
    Column Type: VARCHAR:
    Column Value: Design

好的,请您稍等,我正在为您编写示例代码。 首先,假设我们有一个实体类User和一个Dto类UserDto,它们都有一个set属性roles,表示用户的角色。 User实体类定义如下: ```java @Entity public class User { @Id private Long id; private String name; @ManyToMany private Set<Role> roles; // getters and setters } ``` UserDto类定义如下: ```java public class UserDto { private Long id; private String name; private Set<RoleDto> roles; // getters and setters } ``` 其中,Role和RoleDto类分别表示用户的角色和角色的数据传输对象(DTO),这里为了简化代码省略了它们的定义。 现在,我们想要使用entityManager构建SQL查询,返回一个List<UserDto>,其中包含用户的姓名和角色列表。具体的示例代码如下: ```java public List<UserDto> getUsersWithRoles(EntityManager entityManager) { // 构建查询 CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<UserDto> query = cb.createQuery(UserDto.class); Root<User> root = query.from(User.class); Join<Object, Object> roles = (Join<Object, Object>) root.fetch("roles", JoinType.LEFT); // 查询字段 query.multiselect( root.get(User_.id), root.get(User_.name), cb.selectCase() .when(cb.isNotEmpty(roles), cb.literal(getRoleDtos(roles))) .otherwise(cb.literal(Collections.emptySet())) ); // 执行查询 TypedQuery<UserDto> typedQuery = entityManager.createQuery(query); return typedQuery.getResultList(); } private Set<RoleDto> getRoleDtos(Join<Object, Object> roles) { return roles.getOn().getJavaType().equals(RoleDto.class) ? roles.<RoleDto>get("roleDto") : roles.<Role>get("role").stream().map(RoleDto::from).collect(Collectors.toSet()); } ``` 这个查询使用了JPA的Criteria API,从User表中查询出用户的id、name和roles,其中roles使用了左外连接(LEFT JOIN)。 在查询中,我们将用于构建UserDto的三个字段都放在multiselect子句中,同时使用了一个selectCase函数,它会在roles不为空时返回角色列表,否则返回一个空集合。 最后,我们使用TypedQuery执行查询,并返回查询结果的List<UserDto>。 需要注意的是,这里我们使用了一个getRoleDtos方法,它的作用是根据roles的类型选择构建RoleDto还是Role对象。由于User实体类中定义的roles属性是一个Set,具体的实现可能因JPA的实现而异。这里我们假设当roles集合中的第一个元素为RoleDto时,roles的类型就是RoleDto,否则就是Role。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值