java—使用criteria builder api实现本机sql查询

rjee0c15  于 2021-07-26  发布在  Java
关注(0)|答案(0)|浏览(251)

我要使用criteria builder api编写的查询:

SELECT concert.*FROM concert JOIN event e ON concert.id=e.event_id WHERE TIMESTAMPDIFF(MINUTE,e.begin,e.end)>=?AND TIMESTAMPDIFF(MINUTE,e.begin,e.end)<=?AND name like GROUP BY concert.id

我是如何实现的:

public List<Concert> test(Concert concert, Pageable p, Integer duration) {
        CriteriaBuilder cb = this.em.getCriteriaBuilder();
        CriteriaQuery<Concert> cq = cb.createQuery(Concert.class);
        Root<Concert> concert = cq.from(Concert.class);
        Root<Event> event = cq.from(Event.class);

        // SELECT concert.*FROM concert JOIN event e ON concert.id=e.event_id
        cq.select(concert);
        cq.where(cb.equal(concert.get("id"), event.get("event_id")));

            int offset = 30;
            Expression<String> minute = new UnitExpression(null, String.class, "MINUTE");
            Expression<Integer> timeDiff = cb.function(
                "TIMESTAMPDIFF",
                Integer.class,
                minute,
                event.<Timestamp>get("begin"),
                event.<Timestamp>get("end"));
            List<Predicate> conditions = new ArrayList<>();

            conditions.add(cb.greaterThanOrEqualTo(timeDiff, (duration + offset)));
            conditions.add(cb.lessThanOrEqualTo(timeDiff, (duration - offset)));
            // WHERE TIMESTAMPDIFF(MINUTE,e.begin,e.end)>=?AND TIMESTAMPDIFF(MINUTE,e.begin,e.end)<=?
            cq.where(conditions.toArray(new Predicate[]{}));

        if(concert.getName() != null) {
            // AND name like
            cq.where(cb.and(cb.like(cb.lower(concert.get("name")), ("%" + concert.getName() + "%").toLowerCase())));
        }
        cq.groupBy(concert.get("id"));
        TypedQuery<Concert> query = em.createQuery(cq);
        return concerts = query.getResultList();
    }

我添加了一个注解,将查询添加到criteria builder和 UnitExpression 类如下所示:

class UnitExpression extends BasicFunctionExpression<String> implements Serializable {

    public UnitExpression(CriteriaBuilderImpl criteriaBuilder, Class<String> javaType, String functionName) {
        super(criteriaBuilder, javaType, functionName);
    }

    @Override
    public String render(RenderingContext renderingContext) {
        return getFunctionName();
    }
}

本地人 SQL 查询返回正确的实体并正确执行。我的criteria builder api实现只执行 SELECT concert.*FROM concert JOIN event e ON concert.id=e.event_id 当我打开 show-sql: true 在我的 .yml 文件。
为什么我的criteria builder api只执行连接部分?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题