使用 GORM 基于 3 个表进行 4 路过滤

Doing 4 way filter based on 3 tables using GORM

我一直在尝试实现基于 4 tables“Offers”、“UserPaymentMethods”和定义为 table“OffersUserPaymentMethods”的 4 种方法 join/filter下面;

所以我想根据 payment_method_id 过滤“优惠”,因为 offer_id 居住在 offers_user_payment_methods 这使得它有点棘手。前端将发送 payment_method_id,我需要根据 payment_method_id 过滤报价。

CREATE TABLE `offers_user_payment_methods` (
  `offer_id` bigint(20) unsigned NOT NULL,
  `user_payment_method_id` bigint(20) unsigned NOT NULL
)
CREATE TABLE `offers` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `user_uid` longtext NOT NULL,
  `base` varchar(20) NOT NULL,
  `quote` varchar(20) NOT NULL,
  `side` longtext NOT NULL,
  `price` decimal(32,16) NOT NULL,
  `origin_amount` decimal(32,16) NOT NULL,
  `available_amount` decimal(32,16) NOT NULL,
  `min_order_amount` decimal(32,16) NOT NULL,
  `max_order_amount` decimal(32,16) NOT NULL,
  `payment_time_limit` bigint(20) unsigned NOT NULL,
  `state` longtext NOT NULL,
  `created_at` datetime(3) DEFAULT NULL,
  `updated_at` datetime(3) DEFAULT NULL
)
CREATE TABLE `user_payment_methods` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `user_uid` longtext NOT NULL,
  `payment_method_id` bigint(20) unsigned DEFAULT NULL,
  `data` json DEFAULT NULL,
  `created_at` datetime(3) DEFAULT NULL,
  `updated_at` datetime(3) DEFAULT NULL,
)
CREATE TABLE `payment_methods` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `type` longtext NOT NULL,
  `bank_name` longtext NOT NULL,
  `logo` longtext NOT NULL,
  `options` json DEFAULT NULL,
  `enabled` tinyint(1) NOT NULL,
  `created_at` datetime(3) DEFAULT NULL,
  `updated_at` datetime(3) DEFAULT NULL
)

使用 Gorm,您将很难高效且完全地完成此操作。 Preloading/associations 没有在 Gorm 和 there is no way to filter based on them 中使用 joins 完成。我看到两个可能的选择:

1。使用 joins 编写您自己的查询并扫描结果

您可以使用 Gorm 进行查询和执行,但老实说,我只是避免所有反射等需求,而只是定义一个结构并直接扫描它。

结果将包含重复数据,因此您必须手动转置结果并构建对象。

3。执行两个查询,一个用于查找报价的 ID,一个用于查找报价

第一个查询相当于:

SELECT offers_user_payment_methods.offer_id FROM offers_user_payment_methods
INNER JOIN user_payment_methods ON offers_user_payment_methods. user_payment_method_id = user_payment_methods.id
WHERE user_payment_methods.payment_method_id = ?

如果将这些结果扫描成var offerIDs []int,就可以使用Gorm来find the offers by passing this slice as the param:

offers := make(Offer, 0)
db.Find(&offers, offerIDs)

我认为这个解决方案的好处是您可以执行 更复杂的 查询并将简单的事情留给 Gorm(这就是它的作用 ~ok).