我当前有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)
答案 0 :(得分:0)
选项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 ?
如果数据库没有内置函数,则应创建用户定义的函数。
答案 1 :(得分:0)
解决方案是基础知识
criteriaQuery.select(root).where(
criteriaBuilder.greaterThanOrEqualTo(root.<Date>get("date"), MondayOfTheWeek()),
criteriaBuilder.lessThanOrEqualTo(root.<Date>get("date"), FridayOfTheWeek()));