在一个查询中从不同表中进行多项选择

Multiple selection from different tables in one query

我的问题是关于使用 mybatis 优化查询。

List<SomeObject> someObjectList = oracleMapper.getAllSomeObject();

在我的项目中,我必须从一个数据库卸载数据并向另一个数据库发出请求

List<String> subscriptionIds = someObjectList.stream().map(g -> g.getSubscriptionId()).collect(Collectors.toList());

     List<Subscription> subscriptionsByIds = postgresMapper.getSubscriptionsByIds(subscriptionIds);
     List<SubscriptionSubject> subjectsByIds = postgresMapper.getSubscriptionSubjectsByIds(subscriptionIds);

我必须使用 id 列表对不同的表进行两次查询

  <select id="getSubscriptionsByIds" resultType="com.mappers.Subscription">
        SELECT "s_id" as sId, "old" as old FROM "subscriptions"."subscriptions" s where s."subscription_id_old"  IN
    <foreach item="item" collection="subscriptionIds" separator="," open="(" close=")">
      #{item}
    </foreach>
  </select>

  <select id="getSubscriptionSubjectsByIds" resultType="com.mappers.SubscriptionSubject">
        SELECT  "s_id" as sId, "old" as old FROM "subscriptions"."subscription_subjects" s where s."subscription_id_old"  IN
    <foreach item="item" collection="subscriptionIds" separator="," open="(" close=")">
      #{item}
    </foreach>
  </select>

@Data
public class Subscription {
    private Long subscriptionId;
    private String subscriptionIdOld;
//others
    }


@Data
public class SubscriptionSubject {
    private Long subscriptionId;
    private String subscriptionIdOld;
//others
}

是否可以通过某种方式不执行两个查询,而是对两个表进行一个查询? 有很多数据,也会有很多请求,我想减少它。提前致谢

如果两个查询之间的唯一区别是 table 名称。您可以将该值作为额外参数传递,并使用“SQL Injection”将其添加到查询中。

例如:

<select id="getSubscriptionsByIds" resultType="com.mappers.Subscription">
  SELECT "s_id" as sId, "old" as old FROM ${tableName} s 
  WHERE s."subscription_id_old" IN
  <foreach item="item" collection="subscriptionIds" separator=","
    open="(" close=")">
    #{item}
  </foreach>
</select>

确保您作为参数传递的对象包括一个额外的 属性 tableName 除了您已经传递的 ID 列表。

请注意,为了实现 SQL 注入,您需要使用 ${parameter} 而不是 #{parameter}。仅在绝对必要时才使用 SQL 注入。在错误的人手中,它可能会在您的应用程序中打开安全漏洞。