3

我使用JpaSpecificationExecutor來創建自定義查詢。如何爲以下SQL創建規範?如何通過組合表使用JpaSpecificationExecutor創建規範?

select * from employee e, address a where e.id=23415 and e.name="Deepak" and a.city="Leeds"; 

的Java類:

public static Specification<Employee> searchEmployee(final Map<String,String> myMap) { 

    return new Specification<Employee>(){ 
     @Override 
     public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> query, CriteriaBuilder cb) { 

      //Need to query two tables Employee and Address 

      } 
     } 

回答

6

這是一個測試工作

@Test 
public void test1() { 

    repository.save(makeEmployee("billy", "London")); 
    repository.save(makeEmployee("noby", "London")); 
    repository.save(makeEmployee("fred", "London")); 

    assertEquals(3, repository.count()); 

    final Long id = 3l; 
    final String name = "noby"; 
    final String city = "London"; 

    Specification<Employee> specification = new Specification<Employee>() { 
     public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> query, CriteriaBuilder builder) { 
      List<Predicate> predicates = new ArrayList<Predicate>(); 
      predicates.add(builder.equal(root.get("id"), id)); 
      predicates.add(builder.equal(root.get("name"), name)); 
      predicates.add(builder.equal(root.get("address").get("city"), city)); 
      return builder.and(predicates.toArray(new Predicate[predicates.size()])); 
     } 
    }; 

    List<Employee> find = repository.findByIdAndNameAndAddressCity(id, name, city); 
    assertEquals(1, find.size()); 

    find = repository.findAll(specification); 
    assertEquals(1, find.size()); 
} 

private Employee makeEmployee(String name, String city) { 

    Address address = new Address(); 
    address.setCity(city); 

    Employee employee = new Employee(); 
    employee.setName(name); 
    employee.setAddress(address); 
    return employee; 
} 

}

庫看起來像是這樣

@Repository 
public interface EmployeeRepository extends JpaRepository<Employee, Long>, JpaSpecificationExecutor<Employee> { 

    List<Employee> findByIdAndNameAndAddressCity(Long id, String name, String city); 
} 

實體看起來像這樣

@Entity(name = "EMPLOYEE") 
public class Employee { 

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

    @Column(name = "NAME") 
    private String name; 

    @Column(name = "DATE_OF_BIRTH") 
    private Date dob; 

    @OneToOne(cascade=CascadeType.ALL) 
    @JoinColumn(name = "address_id", referencedColumnName = "id", nullable = false) 
    private Address address; 

希望這會有所幫助。

+0

我同意這完全適用於一個表。在上面的代碼中,您有一個表(EMPLOYEE)來保存員工和地址的詳細信息。但我有兩個表EMPLOYEE和ADDRESS表分開。我需要使用規範在兩個表上查詢。任何建議? – Deepak

+0

不理解這個問題,我已經糾正了答案。 –

+0

感謝它完美的作品! – Deepak