使用注释创建有条件运行的条件运行hibernate



我正在创建一个REST服务,它将允许我提供所有对象或一个过滤的子集。我的界面是基于一个我无法更改的设计。
到目前为止:我已经使用Spring创建了控制器:

@RequestMapping(path = "/designs", method = GET)
public ResponseEntity<CommonResponse> getDesigns(
@RequestHeader(name = "authenticationToken", required = AUTHENTICATION_TOKEN_REQUIRED) String authenticationToken
, @RequestParam(name = "title", required = false) String title
, @RequestParam(name = "designCategory", required = false) String designCategory
, @RequestParam(name = "epic", required = false) String epic
) {
return designService.get(title, designCategory, epic);
}

A服务:

@Transactional
@Override
public ResponseEntity<CommonResponse> get(String title, String designCategory, String epic) {
try {
if(title == null && designCategory == null && epic == null) {
commonResponse.setDesigns(designRepository.findAll());
} else {
commonResponse.setDesigns(designRepository.findByTitleAndDesignCategoryAndJiraEpicNumber(title, designCategory, epic));
}
checkForNoResults(commonResponse.getDesigns());
} catch (NoResultsFoundException e) {
return ResponseEntity.status(e.getStatus()).body(e.getResponse());
}
return ResponseEntity.ok(commonResponse);
}

A型号:

@Entity(name = "design")
public class DesignModel extends BaseModel {
@Column
private String title;
@Column
private LocalDate createdDate;
@Column
private LocalDate updatedDate;
@OneToOne
@JoinColumn(name = "design_category_id")
private DesignCategoryModel designCategory;
@Column
private String documentUrl;
@Column
private String featureHomeUrl;
@Column
private String jiraEpicNumber;
@Column
private String description;
//Getters and setters... etc.
}

还有一个存储库:

@Repository
public interface DesignRepository extends CrudRepository<DesignModel, Integer> {
ArrayList<DesignModel> findAll();
ArrayList<DesignModel> findByTitleAndDesignCategoryAndJiraEpicNumber(String title, String designCategory, String epic);
}

这很好,但是:
如果我只想按标题过滤,而不提供其他值,我的查询就什么都不提供。我在这里简要介绍了CriteriaBuilder:https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/但我需要访问我的会话对象才能创建CriteraBuilder(鉴于我从未创建过Hibernate Utils类,我不知道如何获取会话(

如何创建这些"条件条件"?

虽然这感觉应该很容易,但看起来你需要使用谓词和Querydsl

https://www.baeldung.com/rest-api-search-language-spring-data-querydsl

但以下是的基本原理

设置您的回收以获取PredicateExecutitor

public interface MyUserRepository extends JpaRepository<MyUser, Long>, 
QuerydslPredicateExecutor<MyUser>, QuerydslBinderCustomizer<QMyUser> {
@Override
default public void customize(
QuerydslBindings bindings, QMyUser root) {
bindings.bind(String.class)
.first((SingleValueBinding<StringPath, String>) StringExpression::containsIgnoreCase);
bindings.excluding(root.email);
}
}

然后一个客户谓词来获取您的参数列表

public class MyUserPredicate {
private SearchCriteria criteria;
public BooleanExpression getPredicate() {
PathBuilder<MyUser> entityPath = new PathBuilder<>(MyUser.class, "user");
if (isNumeric(criteria.getValue().toString())) {
NumberPath<Integer> path = entityPath.getNumber(criteria.getKey(), Integer.class);
int value = Integer.parseInt(criteria.getValue().toString());
switch (criteria.getOperation()) {
case ":":
return path.eq(value);
case ">":
return path.goe(value);
case "<":
return path.loe(value);
}
} 
else {
StringPath path = entityPath.getString(criteria.getKey());
if (criteria.getOperation().equalsIgnoreCase(":")) {
return path.containsIgnoreCase(criteria.getValue().toString());
}
}
return null;
}
}

将它们封装在SearchCriteria 中

public class SearchCriteria {
private String key;
private String operation;
private Object value;
}

最后,你需要一个构建器来动态创建你的标准

public class MyUserPredicatesBuilder {
private List<SearchCriteria> params;
public MyUserPredicatesBuilder() {
params = new ArrayList<>();
}
public MyUserPredicatesBuilder with(
String key, String operation, Object value) {
params.add(new SearchCriteria(key, operation, value));
return this;
}
public BooleanExpression build() {
if (params.size() == 0) {
return null;
}
List predicates = params.stream().map(param -> {
MyUserPredicate predicate = new MyUserPredicate(param);
return predicate.getPredicate();
}).filter(Objects::nonNull).collect(Collectors.toList());
BooleanExpression result = Expressions.asBoolean(true).isTrue();
for (BooleanExpression predicate : predicates) {
result = result.and(predicate);
}        
return result;
}
}

这是控制器的例子-你需要对此进行调整,因为这不是正确的REST,而是有点古怪的

@Controller
public class UserController {
@Autowired
private MyUserRepository myUserRepository;
@RequestMapping(method = RequestMethod.GET, value = "/myusers")
@ResponseBody
public Iterable<MyUser> search(@RequestParam(value = "search") String search) {
MyUserPredicatesBuilder builder = new MyUserPredicatesBuilder();
if (search != null) {
Pattern pattern = Pattern.compile("(w+?)(:|<|>)(w+?),");
Matcher matcher = pattern.matcher(search + ",");
while (matcher.find()) {
builder.with(matcher.group(1), matcher.group(2), matcher.group(3));
}
}
BooleanExpression exp = builder.build();
return myUserRepository.findAll(exp);
}
}

最新更新