RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1351806
Accepted
unkn0wn
unkn0wn
Asked:2022-04-20 00:48:29 +0000 UTC2022-04-20 00:48:29 +0000 UTC 2022-04-20 00:48:29 +0000 UTC

如何使用 Criteriq Query 编写查询?

  • 772

有表:

  1. gift_certificate(礼券)
  2. tag(标签)
  3. gift_certificate_to_tag_relation(对于礼券和标签之间的多对多关系,包含ID) 在此处输入图像描述

如何使用 Criteria Query 查询具有特定标签集的礼券。标签被传递给Set<String> tagNames.

Java 实体:

  1. GiftCertificate.class:
private Long id;
@Column(nullable = false, unique = true)
private String name;

@Column(nullable = false)
private String description;

@Column(nullable = false)
private BigDecimal price;

@Column(nullable = false)
private Integer duration;

@Column(nullable = false)
private LocalDateTime createDate;

@Column(nullable = false)
private LocalDateTime lastUpdateDate;
  1. Tag.class:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(nullable = false, unique = true)
private String name;
  1. GiftCertificateToTagRelation.class:
@Id
@ManyToOne
@JoinColumn(name = DatabaseColumnName.GIFT_CERTIFICATE_ID)
private GiftCertificate giftCertificate;

@Id
@ManyToOne
@JoinColumn(name = DatabaseColumnName.TAG_ID)
private Tag tag;

我正在尝试什么:

Set<String> tagNames = ...

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<GiftCertificate> criteriaQuery = builder.createQuery(GiftCertificate.class);
Root<GiftCertificate> root = criteriaQuery.from(GiftCertificate.class);
Root<GiftCertificateToTagRelation> relationRoot = criteriaQuery.from(GiftCertificateToTagRelation.class);
Join<GiftCertificateToTagRelation, Tag> tagJoin = relationRoot.join("tag");
Predicate condition = tagJoin.get("name").in(tagNames);
criteriaQuery.where(condition)
    .groupBy(root)
    .having(builder.count(root).in(tagNames.size()));

作为这个查询的结果Hibernate,它会生成一个 SQL 查询(在传递两个标签名称的情况下):

select *
from gift_certificate gc
         cross join gift_certificate_to_tag_relation relation
         inner join tag tag3_ on relation.tag_id = tag3_.id
where tag3_.name in ('tag1', 'tag2')
group by gc.id
having count(gc.id) in (2)
order by gc.id;

但是这个 SQL 代码返回一个空结果。我发现如果你在 line 中cross join添加一个条件 on gc.id = relation.gift_certificate_id,结果就是想要的结果:

select *
from gift_certificate gc
         cross join gift_certificate_to_tag_relation relation on gc.id = relation.gift_certificate_id
         inner join tag tag3_ on relation.tag_id = tag3_.id
where tag3_.name in ('tag1', 'tag2')
group by gc.id
having count(gc.id) in (2)
order by gc.id;

我知道条件ON是在Join<?, ?>. 但是 c 如何使用 Criteria Query 来设置这个词ON(on gc.id = relation.gift_certificate_id)?

sql
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    unkn0wn
    2022-04-26T20:31:27Z2022-04-26T20:31:27Z

    由于转换的结果如下所示:

    select *
    from gift_certificate gc
             cross join gift_certificate_to_tag_relation relation
             inner join tag tag3_ on relation.tag_id = tag3_.id
    where tag3_.name in ('tag1', 'tag2')
    group by gc.id
    having count(gc.id) in (2)
    order by gc.id;
    

    在这里,该行cross join gift_certificate_to_tag_relation relation缺少 condition ON,添加后该行将采用以下形式:

    cross join gift_certificate_to_tag_relation relation on gc.id = relation.gift_certificate_id
    

    为了解决这个问题,CriteriaQuery你需要在字符串中添加这个条件inner join tag tag3_ on relation.tag_id = tag3_.id,那么最终的 SQL 查询会是这样的:

    select *
    from gift_certificate gc
             cross join gift_certificate_to_tag_relation relation 
             inner join tag tag3_ on relation.tag_id = tag3_.id AND gc.id = relation.gift_certificate_id
    where tag3_.name in ('tag1', 'tag2')
    group by gc.id
    having count(gc.id) in (2)
    order by gc.id;
    

    我们将其翻译成CriteriaQuery:

    Root<GiftCertificateToTagRelation> relation = query.from(GiftCertificateToTagRelation.class);
    Join<GiftCertificateToTagRelation, Tag> rel = relation.join(ParameterName.TAG);
    Predicate on = builder.equal(root, relation.get(ParameterName.GIFT_CERTIFICATE));
    rel.on(on); // inner join tag t on rel.tag_id = t.id and (gc.id = rel.gift_certificate_id)
    Predicate condition = rel.get(ParameterName.NAME).in(tagNames);
    
    • 0

相关问题

  • 通过 OUT 参数从过程结果输出

  • ON 关键字附近的语法错误 - SQL

  • 多表查询中的 Count() 聚合函数

  • 根据时间更改单元格中的日期

  • phpMyAdmin 中的错误 #1064 SQL 查询

  • Qt:包含变量的数据库查询

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5