JOOQ - выбор отличия с помощью соединения - выборка картографа - PullRequest
1 голос
/ 03 мая 2020

Это SQL Я пытаюсь создать с помощью JOOQ -

select distinct(kmp.*) from office_all_company_kmp kmp
 inner join company_kmp companykmp on kmp.id=companykmp.kmp_id
 where companykmp.company_id=?1

Я пишу код в Kotlin. У меня было 2 проблемы, делающие это -

  1. В предложении выбора, если я не добавил .asList () в массив полей, я не смог получить его компиляцию.
  2. Картограф выборки должен быть закодирован вручную. Есть ли способ, которым я могу использовать это сделать без написания всего этого кода? Я могу отобразить записи, извлеченные из одной таблицы, без записи какого-либо сопоставления.

Вот что я имею в виду:

fun OfficeAllCompanyKmpDao.findByCompany(companyId: UUID): List<OfficeAllCompanyKmp> =
    this.ctx()
        .selectDistinct(OFFICE_ALL_COMPANY_KMP.fields().asList()) // without the asList() it wouldn't compile
        .from(OFFICE_ALL_COMPANY_KMP)
        .join(COMPANY_KMP).on(OFFICE_ALL_COMPANY_KMP.ID.eq(COMPANY_KMP.KMP_ID))
        .where(COMPANY_KMP.COMPANY_ID.eq(companyId))
        .fetch { // how do I write the mapper without manually writing code like the below?
            OfficeAllCompanyKmp(
                id = it[OFFICE_ALL_COMPANY_KMP.ID],
                officeId = it[OFFICE_ALL_COMPANY_KMP.OFFICE_ID],
                din = it[OFFICE_ALL_COMPANY_KMP.DIN],
                pan = it[OFFICE_ALL_COMPANY_KMP.PAN],
                name = it[OFFICE_ALL_COMPANY_KMP.NAME],
                dateOfBirth = it[OFFICE_ALL_COMPANY_KMP.DATE_OF_BIRTH],
                address = it[OFFICE_ALL_COMPANY_KMP.ADDRESS],
                email = it[OFFICE_ALL_COMPANY_KMP.EMAIL],
                kmpDetails = it[OFFICE_ALL_COMPANY_KMP.KMP_DETAILS],
                createdTimestamp = it[OFFICE_ALL_COMPANY_KMP.CREATED_TIMESTAMP],
                updatedTimestamp = it[OFFICE_ALL_COMPANY_KMP.UPDATED_TIMESTAMP],
                versionNo = it[OFFICE_ALL_COMPANY_KMP.VERSION_NO],
                createdUserId = it[OFFICE_ALL_COMPANY_KMP.CREATED_USER_ID],
                updatedUserId = it[OFFICE_ALL_COMPANY_KMP.UPDATED_USER_ID]
            )
        }

1 Ответ

1 голос
/ 04 мая 2020

Лучшим подходом, чем внутреннее объединение, а затем повторное удаление дубликатов, было бы полусоединение с другой таблицей, используя IN или EXISTS:

this.ctx()
    .selectFrom(OFFICE_ALL_COMPANY_KMP)
    .where(OFFICE_ALL_COMPANY_KMP.ID.`in`(
         select(COMPANY_KMP.KMP_ID)
        .from(COMPANY_KMP)
        .where(COMPANY_KMP.COMPANY_ID.eq(companyId)))
    .fetchInto(OfficeAllCompanyKmp::class.java)

Или, в качестве альтернативы, используйте синтаксис jOOQ c LEFT SEMI JOIN синтаксис ( см. Также этот блог для объяснения этого синтаксиса , или этот для объединений в целом , или хорошее объяснение Википедии о полусоединениях )

this.ctx()
    .select()
    .from(OFFICE_ALL_COMPANY_KMP)
    .leftSemiJoin(COMPANY_KMP)
    .on(OFFICE_ALL_COMPANY_KMP.ID.eq(COMPANY_KMP.KMP_ID))
    .and(COMPANY_KMP.COMPANY_ID.eq(companyId))
    .fetchInto(OfficeAllCompanyKmp::class.java)

Ваша проблема 1) ушла из-за использования другого jOOQ API, где вам не нужно явно перечислять все столбцы в SELECT. Ваша проблема 2) легко решается путем вызова fetchInto().

...