Hãy xem xét mô hình JAVA sau đây để ngủ đông :
@Entity
@Table
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long id;
@Column
public String firstName;
@Column
public String lastName;
@Column
public Boolean active;
}
và mô hình sau đây cho tuần tự hóa API (sử dụng bộ điều khiển nghỉ khởi động mùa xuân ):
public class PersonVO {
public Long id;
public String fullName;
}
Điều tôi muốn là:
- Có một số bộ lọc được áp dụng tại Người (được xác định tĩnh)
- Có một số bộ lọc được áp dụng tại PersonVO (lấy từ @RequestParam)
Trong C # .NET tôi có thể thực hiện như sau:
IQueryable<Person> personsQuery = entityFrameworkDbContext.Persons;
// FIRST POINT - Here i could make some predefined filtering like 'only active', 'from the same city'... at the database model
personsQueryWithPreDefinedFilters = personsQuery.Where(person => person.active == true);
IQueryable<PersonVO> personsProjectedToVO = personsQueryWithPreDefinedFilters.Select(person => new PersonVO()
{
id = person.id,
fullName = person.firstName + " " + person.lastName
});
// SECOND POINT - At this point i could add more filtering based at PersonVO model
if (!String.IsNullOrWhiteSpace(fullNameRequestParameter)) {
personsProjectedToVO = personsProjectedToVO.Where(personVO => personVO.FullName == fullNameRequestParameter);
}
// The generated SQL at database is with both where (before and after projection)
List<PersonVO> personsToReturn = personsProjectedToVO.ToList();
Những gì tôi nhận được trong Java là:
CriteriaBuilder cb = this.entityManager.getCriteriaBuilder();
CriteriaQuery<PersonVO> cq = cb.createQuery(PersonVO.class);
Root<Person> root = cq.from(Person.class);
// FIRST POINT - Here i could make some predefined filtering like 'only active', 'from the same city'... at the database model
cq.where(cb.equal(root.get(Person_.active), true));
Expression<String> fullName = cb.concat(root.get(Person_.firstName), root.get(Person_.lastName));
cq.select(cb.construct(
PersonVO.class,
root.get(Person_.id),
fullName
));
// SECOND POINT - At this point i could add more filtering based at PersonVO model??? HOW???
if (fullNameRequestParameter != null) {
cq.where(cb.equal(fullName, fullNameRequestParameter));
// i only could use based at the fullName expression used, but could i make a Predicate based only on PersonVO model without knowing or having the expression?
}
Tôi muốn tách "phép chiếu sang mô hình VO" khỏi "biểu thức nơi" được áp dụng cho nó, nhưng nó được áp dụng gián tiếp nếu sử dụng một cột được chiếu (như fullName).
Điều này có thể có trong Java không? Dùng cái gì? Tiêu chí? Truy vấn? Suối? (không nhất thiết phải dính vào mẫu java)
stream()
để truy vấn cơ sở dữ liệu. Tôi nghĩ rằng điều này có thể trả lời một phần câu hỏi của tôi. Nhưng tôi sẽ giữ cho nó mở để xem ai đó có thể trả lời điều đó với một ví dụ cụ thể (tốt nhất là sử dụng ngủ đông như orm).
Stream
bạn có thể đã làm một cái gì đó như -personList.stream().filter(p -> p.active).map(p -> new PersonV0(p.id, p.firstName + " " + p.lastName)).filter(pv -> pv.fullName.equals(fullNameRequestParameter)).collect(Collectors.toList());
nơi mà việcPredicate
sử dụngfilter
saumap
ping được dựa trênPersonV0