[英]Date comparision using CriteriaBuilder in java
我有當前date(date)
和friday(fridayOfTheWeek)
以及Monday(mondayOfTheWeek)
。 我想檢查日期是否介於星期一和星期五之間。
我嘗試使用謂詞和get方法,但無法實現它
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Star> criteriaQuery = builder.createQuery(Teacher.class);
Root<Teacher> root = criteriaQuery.from(Teacher.class);
Join<Teacher, B> join = root.join("department").join("team");
criteriaQuery.where(builder.equal(join.get("department"), "subject"));
//criteriaQuery.where(builder.between(root.get("date")), MondayOfTheWeek(), FridayOfTheWeek());
criteriaQuery.select(root);
Query<Teacher> query = session.createQuery(criteriaQuery);
第一種方法嘗試了這個
criteriaQuery.where(builder.between(builder.function("week", Integer.class, root.get("date")), MondayOfTheWeek(), FridayOfTheWeek()));
我在builder.between上遇到的錯誤是
Bound mismatch: The generic method between(Expression<? extends Y>, Y, Y) of type CriteriaBuilder is not applicable for the arguments (Expression<Integer>, Date, Date). The inferred type Object&Comparable<?>&Serializable is not a valid substitute for the bounded parameter <Y extends Comparable<? super Y>>
我嘗試的第二種方法是:
criteriaQuery.where(builder.between(root.get("date")), MondayOfTheWeek(), FridayOfTheWeek());
它之間給出錯誤
The method between(Expression<? extends Y>, Expression<? extends Y>, Expression<? extends Y>) in the type CriteriaBuilder is not applicable for the arguments (Path<Object>)
我嘗試的第三種方法是:
ParameterExpression<java.util.Date> parameter = builder.parameter(java.util.Date.class);
Predicate startPredicate = builder.greaterThanOrEqualTo(root.get(MondayOfTheWeek()), parameter);
Predicate endPredicate = builder.greaterThanOrEqualTo(root.get(FridayOfTheWeek()), parameter);
我得到的錯誤是:
The method get(SingularAttribute<? super Teacher,Y>) in the type Path<Teacher> is not applicable for the arguments (Date)
選項1.純Java
您需要自己實現FunctionExpression的實現。 下面是我的自定義“包含”功能的類(在Ms Sql Server中進行全文搜索)。 您需要用“%s和%s之間的datepart(wk,%s)”替換“ contains(%s,%s)”,並使用2個屬性“ Expression value”代替我的一個。 在數據庫文檔中查找“ datepart”描述。
import org.hibernate.query.criteria.internal.CriteriaBuilderImpl;
import org.hibernate.query.criteria.internal.ParameterContainer;
import org.hibernate.query.criteria.internal.ParameterRegistry;
import org.hibernate.query.criteria.internal.Renderable;
import org.hibernate.query.criteria.internal.compile.RenderingContext;
import org.hibernate.query.criteria.internal.expression.LiteralExpression;
import org.hibernate.query.criteria.internal.expression.function.BasicFunctionExpression;
import javax.persistence.criteria.Expression;
import java.io.Serializable;
/**
* Models a SQL <tt>CONTAINS</tt> expression.
*
* @author Steve Ebersole
*/
public class ContainsFunction extends BasicFunctionExpression<Boolean> implements Serializable {
private final Expression<String> field;
private final Expression<String> value;
public ContainsFunction(CriteriaBuilderImpl criteriaBuilder, Expression<String> field, Expression<String> value) {
super(criteriaBuilder, Boolean.class, "contains");
this.field = field;
this.value = value;
}
public ContainsFunction(
CriteriaBuilderImpl criteriaBuilder,
Expression<String> field,
String value) {
this(criteriaBuilder, field, new LiteralExpression<>(criteriaBuilder, value));
}
public Expression<String> getField() {
return field;
}
public Expression<String> getValue() {
return value;
}
public void registerParameters(ParameterRegistry registry) {
ParameterContainer.Helper.possibleParameter(getField(), registry);
ParameterContainer.Helper.possibleParameter(getValue(), registry);
}
@Override
public String render(RenderingContext renderingContext) {
return String.format("contains(%s,%s)=true"
, ((Renderable) getField()).render(renderingContext)
, ((Renderable) getValue()).render(renderingContext));
}
}
此自定義表達式的用法
query.where(new ContainsFunction((CriteriaBuilderImpl) builder, field, value))
選項2. Java + DB
您可以使用CirtiaBuilder#function方法,但不允許在SQL datepart函數中提供wk常量。 如果您的數據庫具有datapart(wk,{date})的內置模擬,例如week({date}),則可以編寫
query.where(builder.between(builder.function("week", Integer.class, root.get("dateField")), first, last));
它將轉換為SQL
week(yourTable.dateField) between ? and ?
如果數據庫沒有內置函數,則應創建用戶定義的函數。
解決方案是基礎知識:
criteriaQuery.select(root).where(
criteriaBuilder.greaterThanOrEqualTo(root.<Date>get("date"), MondayOfTheWeek()),
criteriaBuilder.lessThanOrEqualTo(root.<Date>get("date"), FridayOfTheWeek()));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.