如何使用Criteria Builder处理一对多关系中的空值。
我正在使用我的API中的标准生成器来获得结果。
我所面临的问题是当我传递的任何文本,这是在student_group
表中,我得到的结果。当我给null,所以我的lastRollResult是null在student
表中,我得到的结果,但当我传递的文本和null的组合,我没有得到结果。
我的API如下所示
http://本地主机:8080/学生?查询=成绩:5,上次滚动结果%40成功%23失败
在这种情况下,我可以获取数据
http://本地主机:8080/学生?查询=年级:5,上次滚动结果% null
在这种情况下,我无法获取数据
下面是我正在尝试的内容以及我的代码。
我的控制器。
控制器类别:
@RequestMapping(method = RequestMethod.GET)
public Page<StudentDTO> index(MySpecificationsBuilder builder,
@PageableDefault(value = 25, page = 0) Pageable pageable) {
Specification<Student> spec = builder.build();
Page<Student> stu = studentService.findAll(spec, pageable);
/** here some modification on retuen */
}
字符串
您可以注意到,在Controller中,我正在构建MySpecificationsBuilder,所有的条件都在这里设置。
public class MySpecificationsBuilder extends BaseSpecification<Student> {
public MySpecificationsBuilder(final SearchCriteria criteria) {
super(criteria);
}
@Override
protected Expression<String> getPath(SearchCriteria criteria, Root<Student> root) {
/** some other conditions */
if (criteria.getKey().equals("lastRollResult")) {
if (!"null".contains(criteria.getValue())) {
Join results = root.join("lastRoll", JoinType.INNER); // In case of text (JoinType.INNER is enum of Inner.
return results.get("result");
}else{
return root.get("lastRoll”); // in case of null
}
}
return root.get(criteria.getKey());
}
/** below toPredicate methods */
}
型
在MySpecificationsBuilder中,我正在进行一些其他的计算,作为resultConstant和toPredicate的结果。
在这里,你可以看到,对于文本,我在进行内部连接,但是对于null,我直接得到数据。所以,这就是我得到这个响应的原因。如何修正这个值。
这是我的表详细信息。
@Entity
@Data
@DiscriminatorFormula("case when entity_type is null then ‘Student’ else entity_type end")
@DiscriminatorValue("Student")
public class Student extends AbstractStudent {
@ManyToOne
@Fetch(value = FetchMode.SELECT)
@JoinColumn(name = "created_by_id", insertable = false, updatable = false)
@EqualsAndHashCode.Exclude
@ToString.Exclude
@NotFound(action = NotFoundAction.IGNORE)
User createdBy;
@Transient
private String name;
@Transient
private List<String> tags;
}
型
抽象学生
@RequiresAudit
@Log4j2
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Data
@Entity
@Table(name = "student_group")
@DiscriminatorColumn(name = "entity_type", discriminatorType = DiscriminatorType.STRING)
public class AbstractStudent extends BaseModel {
@OneToMany(mappedBy = "student", fetch = FetchType.LAZY)
@EqualsAndHashCode.Exclude
@ToString.Exclude
List<StudentMapping> studentMappings;
@OneToMany(mappedBy = "student", fetch = FetchType.LAZY)
@EqualsAndHashCode.Exclude
@ToString.Exclude
List<StudentDataMapping> studentDataMapping;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@AuditColumn
@Column(name = "last_roll_id")
private Long lastRollId;
@OneToMany(mappedBy = "student", fetch = FetchType.LAZY)
@EqualsAndHashCode.student
@ToString.Exclude
private Set<TagUse> tagUses;
@ManyToOne
@Fetch(value = FetchMode.SELECT)
@JoinColumn(name = "last_roll_id", referencedColumnName = "id", insertable = false, updatable = false)
@EqualsAndHashCode.Exclude
@ToString.Exclude
@NotFound(action = NotFoundAction.IGNORE)
private Result lastRoll;
/** some other column defination */
}
型
在“我的摘要”列中,可以有一对一的Map。
是否有任何解决方案,如组或任何where子句或任何其他东西,我可以俱乐部这两个参数,以获得结果的null以及文本。
1条答案
按热度按时间gywdnpxw1#
查询结果中的关系如何处理还不清楚,如果不管相关实体是否存在都想返回students数据,我觉得应该试试左联接:
字符串
也许你想实现这样的目标:
型
编辑:
如果此解决方案适用于您,则意味着您正在基于某些条件(可能包含也可能不包含相关实体
Result
)实现对实体Student
的搜索。要实现此目标,您可以基于现有条件输入动态地将LEFT
联接应用于条件。您可以始终返回连接结果,并且仍然可以正常工作,并且您可以为两个实体应用所有 predicate :
型
然而,在某些情况下,生成的SQL查询的性能会降低。如果你只在需要的时候处理连接包含,你会得到更好的查询和更好的性能,但是,你也需要动态地应用与
Result
实体相关的 predicate :型