【问题标题】:Insert values in many to many relationship tables with JOOQ使用 JOOQ 在多对多关系表中插入值
【发布时间】:2021-01-23 08:09:27
【问题描述】:

我的数据库中有三个表,SUBSCRIPTIONUSER_ID,以及一个名为 SUBSCRIPTION_USER_ID 的关联表。

我的策略是使用JOOQ批处理三个查询,第一个在行上插入SUBSCRIPTION,第二个查询在USER_ID中插入多行,最后,我需要插入关联ID进入SUBSCRIPTION_USER_ID,所以我做了以下操作:

InsertValuesStep2 insertUserIds = insertInto(
    USER_ID, USER_ID.USER_ID_TYPE, USER_ID.USER_ID_VALUE);

for (String userId : subscriptionDTO.getUserId())
    insertUserIds = insertUserIds.values(getValue(0, userId), getValue(1, userId));

InsertReturningStep insertReturningUserIds = insertUserIds.onConflictDoNothing();

InsertResultStep insertReturningSubscription = insertInto(SUBSCRIPTION)
        .set(SUBSCRIPTION.CHANNEL_ID, subscriptionDTO.getChannel())
        .set(SUBSCRIPTION.SENDER_ID, subscriptionDTO.getSenderId())
        .set(SUBSCRIPTION.CATEGORY_ID, subscriptionDTO.getCategory())
        .set(SUBSCRIPTION.TOKEN, subscriptionDTO.getToken())
        .onConflictDoNothing()
        .returningResult(SUBSCRIPTION.ID);

不幸的是,为了向关联表中插入值,我尝试了很多方法但对我没有任何作用,最后,我尝试使用 select 在 SUBSCRIPTION_USER_IDusing 中插入值但它不起作用:

InsertValuesStep insertValuesSubscriptionUserIds = insertInto(
        SUBSCRIPTION_USER_ID, 
        SUBSCRIPTION_USER_ID.SUBSCRIPTION_ID, 
        SUBSCRIPTION_USER_ID.USER_ID_ID)
    .select(select(SUBSCRIPTION.ID, USER_ID.ID)
        .from(SUBSCRIPTION)
        .innerJoin(USER_ID)
        .on(concat(USER_ID.USER_ID_TYPE, 
                val(CATEGORY_USER_ID_DELIMITER), 
                USER_ID.USER_ID_VALUE).in(subscriptionDTO.getUserId())
        .and(SUBSCRIPTION.SENDER_ID.equal(subscriptionDTO.getSenderId()))
        .and(SUBSCRIPTION.CHANNEL_ID.equal(subscriptionDTO.getChannel()))
        .and(SUBSCRIPTION.CATEGORY.equal(subscriptionDTO.getCategory()))
        .and(SUBSCRIPTION.TOKEN.equal(subscriptionDTO.getToken()))));

我在上面遗漏了什么吗?有没有更好的方法使用 JOOQ 插入多对多关系值或使用查询结果作为其他查询的参数?

【问题讨论】:

    标签: java many-to-many jooq


    【解决方案1】:

    我假设您发布了整个代码。在这种情况下:

    您不会在 USER_ID 插入时调用 execute

    简单添加

    insertUserIds.onConflictDoNothing().execute();
    

    或者,使用对returning().fetch()的调用来获取生成的ID

    内连接

    这可能只是一个风格问题,但您似乎在做的是交叉连接。您的 INNER JOIN 过滤器并不是真正的连接谓词。我会把它们放在WHERE 子句中。清晰可能有助于避免此类查询中出现更多问题。

    具体来说,第一个“连接谓词”非常令人困惑,其中包含一个 CONCAT 调用,这在 INNER JOIN 中是不会看到的,并且只涉及一个表,而不是两个表:

    .on(concat(USER_ID.USER_ID_TYPE, 
                    val(CATEGORY_USER_ID_DELIMITER), 
                    USER_ID.USER_ID_VALUE).in(subscriptionDTO.getUserId())
    

    错误的谓词

    最后一个谓词似乎是错误的。您正在插入:

    .set(SUBSCRIPTION.TOKEN, subscriptionDTO.getToken())
    

    但你在查询

    .and(SUBSCRIPTION.TOKEN.equal(subscriptionDTO.getContactId()))));
    

    应该又是subscriptionDTO.getToken()

    【讨论】:

    • 谢谢。我没有发布整个代码,实际上,我试图通过必要的元素使其变得简单,也涉及三个以上的表,但我确信它们没有问题。我正在尝试使用批处理启动查询,这就是为什么在我的代码中没有调用执行的原因。最后,我用你提到的固定谓词编辑了这个问题。我会尝试使用交叉连接。
    【解决方案2】:

    如上所述,我插入了 SUBSCRIPTIONUSER_ID 表的值。并获取关联表我需要从上面两个表中获取已经插入的值的ID,所以为了解决这个问题我已经使用这个查询插入SUBSCRIPTION_USER_ID

    InsertReturningStep insertReturningSubscriptionUserId = insertInto(
        SUBSCRIPTION_USER_ID, 
        SUBSCRIPTION_USER_ID.SUBSCRIPTION_ID, 
        SUBSCRIPTION_USER_ID.USER_ID_ID)
        .select(select(SUBSCRIPTION.ID, USER_ID.ID).from(SUBSCRIPTION
                .where(concat(USER_ID.USER_ID_TYPE, val(CATEGORY_USER_ID_DELIMITER), USER_ID.USER_ID_VALUE).in(subscriptionDTO.getUserId()))
                .and(SUBSCRIPTION.SENDER_ID.equal(subscriptionDTO.getSenderId()))
                .and(SUBSCRIPTION.CHANNEL_ID.equal(subscriptionDTO.getChannel()))
                .and(SUBSCRIPTION.CATEGORY.equal(subscriptionDTO.getCategory()))
                .and(SUBSCRIPTION.TOKEN.equal(subscriptionDTO.getToken()))).onConflictDoNothing();
    

    最后,我使用batch 执行了所有查询:

    using(configuration).batch(insertReturningSubscription,
     insertReturningUserIds,
     insertReturningSubscriptionUserId).execute()
    

    【讨论】:

      猜你喜欢
      • 2021-05-10
      • 2011-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-01
      相关资源
      最近更新 更多