【问题标题】:equivalent DBIx::Class syntax?等效的 DBIx::Class 语法?
【发布时间】:2017-01-10 00:16:32
【问题描述】:

我有来自这个question的这个mysql查询。

SELECT a.*
FROM products a
INNER JOIN product_tags b ON a.product_id = b.product_id
WHERE b.tag_id IN (1,23,54)
GROUP BY a.product_id
HAVING COUNT(1) = 3

我想知道如何将其转换为DBIx::Class 语法?

来自 DBIx 文档,这是关于联接的内容,但我不知道如何合并它?

定义联接和关系 ^

在 DBIx::Class 中,需要首先在表的 ResultSource 中定义两个表之间的每个关系。如果需要双向访问关系(即获取 CD 的所有曲目,并获取 Track 的 CD 数据),则需要为两个表定义它。

对于 CD/Tracks 示例,这意味着在 MySchema::CD: 中写入:

  MySchema::CD->has_many('tracks', 'MySchema::Tracks');

在 MySchema::Tracks 中:

  MySchema::Tracks->belongs_to('cd', 'MySchema::CD', 'CDID');

还有几种其他类型的关系,它们在 DBIx::Class::Relationship 中有更全面的描述。 使用连接 ^

定义完所有关系后,在实际连接中使用它们就相当简单了。您选择的关系类型,例如has_many,已经表明将执行哪种连接。例如,has_many 产生一个 LEFT JOIN,它将获取左侧的所有行,无论右侧是否有匹配的行(正在连接的表)。您可以强制在您的关系中加入其他类型,请参阅 DBIx::Class::Relationship 文档。

在执行搜索或查找操作时,您可以使用 join 属性指定要根据哪些关系来细化结果,如下所示:

  $schema->resultset('CD')->search(
    { 'Title' => 'Funky CD',
      'tracks.Name' => { like => 'T%' }
    },
    { join      => 'tracks',
      order_by  => ['tracks.id'],
    }
  );

如果您不认识其中的大部分语法,您可能应该阅读 DBIx::Class::ResultSet 中的“search”和 DBIx::Class::ResultSet 中的“ATTRIBUTES”,但这里有一个快速分解:

搜索的第一个参数是 WHERE 属性的 hashref,在这种情况下是对 CD 表中 Title 列的限制,以及对 Tracks 表中曲目名称的限制,但仅适用于实际相关的曲目到所选的 CD。第二个参数是搜索属性的hashref,返回的结果将按照相关曲目的id排序。

【问题讨论】:

  • 你好 abra 你有什么建议吗?你用过 DBIx 吗?你知道 DBIx 吗?你有朋友知道 DBIx 吗?请告诉他们这个问题。
  • DBIx 是一个完整的命名空间,其中 DBIx::Class 只是一个模块。 DBIx::Class的缩写是DBIC。

标签: mysql perl dbi dbix-class


【解决方案1】:

所以首先你要在产品标签上定义一个 rel。

 MySchema::Result::Product->has_many(
    'tags', 'MySchema::Result::ProductTag', 'product_id'
 );

然后根据标签定义产品的相关性:

 MySchema::Result::ProductTag->belongs_to(
    'products', 'MySchema::Result::Product', 'product_id'
 );

如果您顺便使用 Schema::Loader,这些已经被推断出来了。 (无耻插件:使用 DBIx::Class::Candy 和 DBIx::Class::Helper::Row::RelationshipDWIM 会更短更甜)

现在复制您的原始查询:

$schema->resultset('Product')->search({
  tags.tag_id => { -in => [1,23,54] },
}, {
  join => 'tags',
  group_by => 'me.product_id',
  having => { 'count 1' => 3 },
})

【讨论】:

  • 接受并赞成。谢谢你的时间和帮助弗鲁。它比许多其他显然不了解 DBIx 但投反对票并准备批评的网站管理员好很多倍。
猜你喜欢
  • 2011-07-09
  • 1970-01-01
  • 2016-08-25
  • 2013-01-21
  • 2013-03-08
  • 2011-07-09
  • 1970-01-01
  • 1970-01-01
  • 2011-06-27
相关资源
最近更新 更多