簡體   English   中英

在Java中使用CriteriaBuilder進行日期比較

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM