max*_*yme 2 specifications jpa-2.0 spring-data spring-data-jpa
假设我正在上以下课:(简化为极端)
@Entity
@Table(name = "USER")
public class User {
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
private BillingAddress billingAddress;
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
private ShippingAddress shippingAddress; // This one CAN be null
}
Run Code Online (Sandbox Code Playgroud)
并且都*Address继承自此摘要:(再次简化了)
public abstract class Address {
@OneToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "USER_ID")
private User user;
@NotEmpty
@Size(max = 32)
@Column(name = "ADDR_TOWN")
private String town;
}
Run Code Online (Sandbox Code Playgroud)
我尝试了JPA规范,如Spring的博客文章所述:
/**
* User specifications.
*
* @see <a href="https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl">Advanced Spring Data JPA - Specifications and Querydsl</a>
*/
public class UserSpecifications {
public static Specification<User> likeTown(String town) {
return new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.like(cb.lower(root.get("billingAddress").get("town")), '%' + StringUtils.lowerCase(town) + '%');
}
};
}
Run Code Online (Sandbox Code Playgroud)
使用此“规范”如下:
List<User> users = userRepository.findAll(UserSpecifications.likeTown(myTown));
Run Code Online (Sandbox Code Playgroud)
但是现在,我也想在城镇中搜索shippingAddress,该地址可能不存在。我尝试将两者合并cb.like,cb.or但是结果SQL查询对shippingAddress具有一个INNER JOIN,这是不正确的,因为如上所述,它可能为null,所以我想要一个LEFT JOIN。
怎么做?
谢谢。
指定联接类型:
town = '%' + StringUtils.lowerCase(town) + '%';
return cb.or(
cb.like(cb.lower(root.join("billingAddress", JoinType.LEFT).get("town")), town),
cb.like(cb.lower(root.join("shippingAddress", JoinType.LEFT).get("town")), town));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5166 次 |
| 最近记录: |