JOOQ рдФрд░ рдЙрд╕рдХрд╛ рдЦрд░рдЧреЛрд╢ рдЫреЗрджред рд╣рд╛рдЗрдмрд░рдиреЗрдЯ рдХреЗ рдмрд┐рдирд╛ рдЬреАрд╡рд┐рдд рдХреИрд╕реЗ рд░рд╣реЗрдВ

рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ JOOQ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рдбреВрдмреВрдВрдЧрд╛ред рдореИрдВ рд╣рд╛рдЗрдмрд░рдиреЗрдЯ рдФрд░ рдЗрд╕рдХреЗ рдкреАрдЫреЗ рдХреА рд╕рднреА рд╕реНрдкреНрд░рд┐рдВрдЧ рдбреЗрдЯрд╛ рдЬреЗрдкреАрдП рд╢рдХреНрддрд┐ рдХреЛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВред рд▓реЗрдХрд┐рди рд▓реЗрдЦ рдЙрдирдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред



рдЬрдм рд╣рдо рд╣рд╛рдЗрдмрд░рдиреЗрдЯ рдФрд░ рд╕реНрдкреНрд░рд┐рдВрдЧ рдбреЗрдЯрд╛ рдЬреЗрдкреАрдП рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдЖрдВрддрд░рд┐рдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рдирд╣реАрдВ рд╣реИ - рдПрдиреЛрдЯреЗрд╢рди рдХреЛ рдЬрд╛рдиреЗрдВ рдФрд░ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рд╕рд╣реА рд╡рд┐рдзрд┐ рдХреЗ рдирд╛рдо рд▓рд┐рдЦреЗрдВ - рдпреЗ рджреЛрдиреЛрдВ рд░рд╛рдХреНрд╖рд╕ рдЖрдкрдХреЗ рд▓рд┐рдП рдмрд╛рдХреА рдХрд╛рдо рдХрд░реЗрдВрдЧреЗред JOOQ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рдХрдИ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдереЛрдбрд╝рд╛ рддрдирд╛рд╡ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ findAllByUserId (Long userId) рд╕реЗ рдЕрдзрд┐рдХ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ ред

JOOQ рдХреНрдпрд╛ рд╣реИ?


рдЖрдЗрдП рдПрдХ рд╕рд░рд▓ SQL рдХреНрд╡реЗрд░реА рд▓рд┐рдЦреЗрдВ:

select * from countries c where c.population > 10000000;

рд╣рдо рдХрдВрд╕реЛрд▓ рдореЗрдВ рдЗрд╕ рдЕрдиреБрд░реЛрдз рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдареАрдХ рд╣реИ

рд╣рдо рдХрдВрд╕реЛрд▓ рдореЗрдВ рдРрд╕рд╛ рдорд╣рд╕реВрд╕ рдирд╣реАрдВ рдХрд░рддреЗред рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░рд╛ рдЖрд╡реЗрджрди рдЗрд╕ рдЕрдиреБрд░реЛрдз рдХреЛ рднреЗрдЬреЗрдВред рдпрд╣ рдПрдХ рдмрд╛рд░ рдХреА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдирд╣реАрдВ рдереА рдФрд░ рдЗрд╕реЗ рдХрдо рд╕реЗ рдХрдо рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдХреЗ рд▓рд┐рдП рдорд╛рдиреНрдп рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд╣рдо рдЗрд╕реЗ рд╕реНрдкреНрд░рд┐рдВрдЧ рдбреЗрдЯрд╛ JPA рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд░рддреЗ рд╣реИрдВ:

List<Country> findAllByPopulationAfter(Long amount);

рдПрдХ рд╣реА рдЕрдиреБрд░реЛрдз рдКрдкрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд╕рдВрдд рджреНрд╡рд╛рд░рд╛ред

рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕реНрдкрд╖реНрдЯ рд▓рд╛рдн рдХреНрдпрд╛ рд╣реИрдВ? рдпрд╣ рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдврд╛рдВрдЪреЗ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╣ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рдЕрдиреБрд░реЛрдз рдХреЛ рднреА рдорд╛рдиреНрдп рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдХреНрд╡реЗрд░реА рдкреНрд░рдмрдВрдзрди рдврд╛рдВрдЪреЗ рдХрд╛ рдЦреНрдпрд╛рд▓ рд░рдЦрддрд╛ рд╣реИред рдФрд░ рд╣рдо рдЕрдиреБрд░реЛрдз рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ, рддрд╛рдХрд┐ рдЕрдиреБрд░реЛрдз рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдорд╛рдиреНрдп рд╣реЛред
рдЙрдкрдпреЛрдЧрд╕рд╡рд╛рд▓:

@Query("select c from Country c where c.population > :amount")
List<Country> findAllPopulationGreaterThan(@Param("amount") Long amount);

SQL рдФрд░ DSL рдХреЗ рдмреАрдЪ рдРрд╕рд╛ рд╡реНрдпрд╛рдкрд╛рд░ рдмрдВрдж рднреА рдЕрдЪреНрдЫрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рд╣рдо рдПрд╕рдХреНрдпреВрдПрд▓ рдХреЗ рд╕рд╛рде рдЧрдбрд╝рдмрдбрд╝ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдХреБрдЫ рдРрд╕рд╛ рджреЗрдЦрдХрд░ рдкреНрд░рд╕рдиреНрди рд╣реЛрдВрдЧреЗ:

return dsl.selectFrom(COUNTRIES)
                .where(COUNTRIES.POPULATION.greaterThan(amount))
                .fetch();

рдХрдИ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдЗрд╕рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реИрдВ:

QueryDSL
JOOQ
рдЧрддрд┐ рдХреЗ


рдмрд╛рд░реЗ рдореЗрдВ QueryDSL рдореИрдВрдиреЗ рдХреБрдЫ рд╕рд╛рд▓ рдкрд╣рд▓реЗ рд▓рд┐рдЦрд╛ рдерд╛ред рдореИрдВрдиреЗ рд╕реНрдкреАрдб рдЦреБрджрд╛рдИ рдирд╣реАрдВ рдХреА рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдбреАрдПрд╕рдПрд▓ рдЬрдирд░реЗрдЯрд░ рд╕реЗ рдХреБрдЫ рдЕрдзрд┐рдХ рд▓рдЧрддрд╛ рд╣реИ, рд╕рд╛рде рд╣реА рдореБрдЭреЗ рдЙрди рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рд╕реАрдЦрдирд╛ рд╣реЛрдЧрд╛ рдЬрд┐рдирдХреЗ рджреНрд╡рд╛рд░рд╛ рдЙрдиреНрд╣реЛрдВрдиреЗ рдПрд╕рдХреНрдпреВрдПрд▓ рдХреНрд╡реЗрд░реА рдХрдорд╛рдВрдб рдХреЛ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯ рдХрд┐рдпрд╛ рдерд╛ред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдЖрдЬ рд╣рдо JOOQ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗред

JOOQ рдкреНрд░рд╢реНрди


рд╣рд╛рдБ, рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрди рдкреНрд░рд╢реНрдиреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рджреЗрдЦ рдЪреБрдХреЗ рд╣реИрдВ:

return dsl.selectFrom(COUNTRIES)
                .where(COUNTRIES.POPULATION.greaterThan(amount))
                .fetch();

рдФрд░ рдХреНрдпрд╛ рд╣реИрдВ?

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рд╕рд░рд▓ рдЕрдиреБрд░реЛрдз рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ:

return dsl.selectFrom(Countries.COUNTRIES)
                .where(Countries.COUNTRIES.ID.eq(id))
                .fetchAny();

рдпрд╛ рдЕрдиреБрд░реЛрдз рдбрд╛рд▓реЗрдВ:

return dsl.insertInto(Countries.COUNTRIES)
                .set(Countries.COUNTRIES.NAME, country.getName())
                .set(Countries.COUNTRIES.POPULATION, country.getPopulation())
                .set(Countries.COUNTRIES.GOVERNMENT_FORM, nameOrNull(country.getGovernmentForm()))
                .returning()
                .fetchOne();

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реИ, рдЕрдзрд┐рдХ рдХреБрдЫ рдирд╣реАрдВред рд▓реЗрдХрд┐рди рдпрд╣ рдХреЗрд╡рд▓ рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ рд╣реИред рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рдХрд┐ рдЗрд╕ рдЦрд░рдЧреЛрд╢ рдХреЗ рдЫреЗрдж рдореЗрдВ рдХрд┐рддрдиреЗ рд╕рдкреНрддрд╛рд╣ рд▓рдЧ рд╕рдХрддреЗ рд╣реИрдВред

рд▓реЗрдХрд┐рди рд╢реБрд░реВ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред

рд╣рд╛рдБ рдпрд╣ рдорд╛рд╡реЗрди рд╣реЛрдЧрд╛


рдореБрдЭреЗ рдЧреНрд░реИрдбрд▓ рдкрд╕рдВрдж рд╣реИред рд▓реЗрдХрд┐рди рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ, JOOQ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдЧреНрд░реИрдбрд▓ рдкрд░ рдХрдо рдзреНрдпрд╛рди рджреЗрддреЗ рд╣реИрдВ, рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХреЗ рд▓рд┐рдП рдЬрд╛рдиреЗ рдХреА рдкреЗрд╢рдХрд╢ рдХрд░рддреЗ рд╣реИрдВред рдареАрдХ рд╣реИ, рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдкрд░рд┐рдпреЛрдЬрдирд╛ рдорд╛рд╡реЗрди рдкрд░ рд╣реЛрдЧреАред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк, рдкреНрд░рд┐рдп рдкрд╛рдардХ, рдЕрдлрд╡рд╛рд╣ рдХреЗ рд░реВрдк рдореЗрдВ рдпрд╣ рдЧрд┐рддреБрдм рдХреА рдЧрд╣рд░рд╛рдИ рдореЗрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдЧреНрд░реИрдбрд▓ рдкрд░ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдкреНрд░рдХрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВ - рдореБрдЭреЗ рд▓рд┐рдЦреЗрдВ рдФрд░ рдЖрдк рдЗрд╕ рд▓реЗрдЦ рдХреЗ рд╕рд╣-рд▓реЗрдЦрдХ рдмрди рдЬрд╛рдПрдВрдЧреЗред рдпрд╣реА рдмрд╛рдд H2 рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддреА рд╣реИ (рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдкрд░рд┐рдпреЛрдЬрдирд╛ PostgreSQL рдкрд░ рд╣реЛрдЧреА)ред

рдореИрдВ рдЧреНрд░реИрдбрд▓ рдФрд░ H2 рдХреЗ рд╕рд╛рде рд╕рдлрд▓ рдХреНрдпреЛрдВ рдирд╣реАрдВ рд╣реБрдЖ
, Gradle. jooq-generator . H2, ┬л ┬╗ H2 , , , .

рдЖрд╡рд╢реНрдпрдХ рдорд╛рд╡реЗрди рдирд┐рд░реНрднрд░рддрд╛:

<dependencies>

        <!-- Spring Starters -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jooq</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Database -->
        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- Helpers -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>${commons.lang3.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--Test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- JOOQ Generator -->
        <dependency>
            <groupId>org.jooq</groupId>
            <artifactId>jooq</artifactId>
            <version>${jooq.version}</version>
        </dependency>
        <dependency>
            <groupId>org.jooq</groupId>
            <artifactId>jooq-meta</artifactId>
            <version>${jooq.version}</version>
        </dependency>
        <dependency>
            <groupId>org.jooq</groupId>
            <artifactId>jooq-codegen</artifactId>
            <version>${jooq.version}</version>
        </dependency>

    </dependencies>

рд╕реНрдкреНрд░рд┐рдВрдЧ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ JOOQ рд╕реНрдЯрд╛рд░реНрдЯрд░ рд╣реИ рдЬреЛ Application.yml рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЗ рдЕрдиреБрд╕рд╛рд░ DataSource рдХреЛ рд╕реНрд╡-рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдЧрд╛ред рд▓реЗрдХрд┐рди JOOQ рдХреЗ рдкреВрд░реНрдг рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП, рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИред рд╕рдВрд╕реНрдерд╛рдУрдВ рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рд╣рд╛рдВ, рд╣рд╛рдВ, рд╣рдо рдЗрдХрд╛рдЗрдпрд╛рдВ рдирд╣реАрдВ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЗрдВ рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╣реИрдВред рддрдерд╛рдХрдерд┐рдд рддрд╛рд▓рд┐рдХрд╛-рдкрд╣рд▓рд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдгред

рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдкрд░ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд╕рд╛рде рд╕рд╛рдорд╛рдиреНрдп рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╕рдВрд░рдЪрдирд╛ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддреА рд╣реИ:



рдЬрдм рддрдХ рд╕реЗрд╡рд╛ рдХреА рдкрд░рдд, рдбреЗрдЯрд╛ рдлреНрд▓реИрдЯ рдореЙрдбрд▓ (рдбреАрдЯреАрдУ) рдХреЗ рд░реВрдк рдореЗрдВ рдЖрд╡реЗрджрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдпрд╛рддреНрд░рд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЬрдм рд╕реЗрд╡рд╛ рдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рдпрд╣ рдбреАрдЯреАрдУ рдХреЛ рдПрдХ рдЗрдХрд╛рдИ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЗрд╕реЗ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЛ рднреЗрдЬрддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдмрдЪрд╛рддрд╛ рд╣реИред JOOQ рдбреЗрд╡рд▓рдкрд░реНрд╕ рд╕рдм рдХреБрдЫ рдЕрд▓рдЧ рддрд░рд╣ рд╕реЗ рджреЗрдЦрддреЗ рд╣реИрдВ:



рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, JOOQ рдореЗрдВ рдЙрдиреНрд╣реЛрдВрдиреЗ рдЧрдВрднреАрд░рддрд╛ рд╕реЗ рдорд╛рдирдХ рдкреИрдЯрд░реНрди рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд┐рдпрд╛ рдФрд░ рдЕрдкрдиреЗ рддрд░реАрдХреЗ рд╕реЗ рдЬрд╛рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рдЕрдВрддрд░ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИрдВ:

  1. рдбреАрдЯреАрдУ рдХрд╛ рдПрдХ рдЗрдХрд╛рдИ рдореЗрдВ рд░реВрдкрд╛рдВрддрд░рдг рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред
  2. рд╣рдо рдПрдХ рдЗрдХрд╛рдИ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдирд╣реАрдВ рд▓рд┐рдЦрддреЗ рд╣реИрдВред рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП JOOQ рдЬрдирд░реЗрдЯрд░ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИред

рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдпрд╣ рдирд┐рд╖реНрдХрд░реНрд╖ рдирд┐рдХрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ рдХрд┐ JOOQ рдЗрддрдирд╛ рд╕рд░рд▓ рдирд╣реАрдВ рд╣реИред рдПрдХ рдЙрдЪреНрдЪ рдЕрдиреБрдХреВрд▓рди рдЙрддреНрдкрдиреНрди рдЗрдХрд╛рдИ, рдбреАрдЯреАрдУ рдФрд░ рдЕрдиреНрдп рдХрдард┐рдирд╛рдЗрдпреЛрдВ рдореЗрдВ рд╕рдордЭ рд╕реЗ рдмрд╛рд╣рд░ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдореИрдкрд┐рдВрдЧ рдХрдИ рдХреЛ рджреВрд░ рдХрд░ рджреЗрдЧреАред рд▓реЗрдХрд┐рди рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдЬрд╣рд╛рдВ рдХрд╣реАрдВ рдЬрд╛рдирд╛ рдирд╣реАрдВ рд╣реИ, JOOQ рдХреЗ рдЗрди рдкрд╣рд▓реБрдУрдВ рдХрд╛ рдПрдХ рдХреЗрдВрджреНрд░рд┐рдд рдЕрдзреНрдпрдпрди рдЧрдВрднреАрд░рддрд╛ рд╕реЗ рджреВрд░ рд▓реЗ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рджрд┐рди, рдпрд╛ рд╕рдкреНрддрд╛рд╣ рднреА рд▓реЗ рд╕рдХрддрд╛ рд╣реИред рдореБрдЭреЗ рдпрдХреАрди рд╣реИ рдХрд┐ рдореЗрд░реА рдкреЛрд╕реНрдЯ рдЖрдкрдХреЗ рд╕рдордп рдХреЛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд░реВрдк рд╕реЗ рдмрдЪрд╛рдПрдЧреАред

рд╣рдо JOOQ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд╣рд▓реБрдУрдВ рдХреЛ рдХрд╡рд░ рдХрд░реЗрдВрдЧреЗ:

  • рдЗрдХрд╛рдИ рд╕реГрдЬрдиред
  • рд▓реЗрдЦрди CRUD рдкреНрд░рд╢реНрдиред
  • CRUD рдЕрдиреБрд░реЛрдзреЛрдВ рдХрд╛ рдЕрдиреБрдХреВрд▓рдиред
  • рдФрд░ рджреВрд╕рд░рд╛ CRUD рдЕрдиреБрдХреВрд▓рди рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИред
  • рдорд╛рдирдХ JOOQ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдореИрдкрд┐рдВрдЧ рдЗрдХрд╛рдЗрдпрд╛рдБред
  • рдФрд░ рдЪрд░реНрдЪрд╛ рдХрд░реЗрдВ рдХрд┐ рдпрд╣ рд╕рдм рдХреНрдпреЛрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИред

рдЪрд▓реЛ рдЪрд▓рддреЗ рд╣реИрдВред

рд╣рдо рдХреНрдпрд╛ рд▓рд┐рдЦрддреЗ рд╣реИрдВ?


рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рджреЛ рд╕рдВрд╕реНрдерд╛рдПрдБ рд╣реЛрдВрдЧреА:

рджреЗрд╢:

@Data
public class Country {

    private Long id;
    private String name;
    private GovernmentForm governmentForm;
    private Integer population;

    private List<City> cities;
}

Faridabad:

@Data
public class City {

    private Long id;
    private Long countryId;
    private String name;
}

рдПрдХ рд╕реЗ рдХрдИ рд░рд┐рд╢реНрддреЗред рджреЗрд╢ рдореЗрдВ рдХрдИ рд╕рдВрдмрдВрдзрд┐рдд рд╢рд╣рд░ рд╣реИрдВред рд╕рд┐рдЯреА рдореЗрдВ рдХрдВрдЯреНрд░реА рдЖрдИ.рдбреА.
рдлреНрд▓рд╛рдЗрд╡реЗ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

create table countries
(
    id              bigserial primary key,
    name            varchar(255),
    government_form varchar(255),
    population      int
);

create table cities
(
    id         bigserial primary key,
    country_id bigint,
    name       varchar(255)
);

рдЖрдЗрдП рд╢реБрд░реБрдЖрдд рдХрд░реЗрдВ рдЗрдХрд╛рдИ рдирд┐рд░реНрдорд╛рдг рд╕реЗред


рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдХрд╣рд╛ рдХрд┐ рдЗрдХрд╛рдЗрдпрд╛рдБ, рдЕрд▓рдЧ рд╕реЗ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИрдВред рдЗрд╕реЗ рдХрд░рдиреЗ рдХреЗ рджреЛ рддрд░реАрдХреЗ рд╣реИрдВред

  • рдорд╛рд╡реЗрди рдкреНрд▓рдЧрдЗрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗред
  • рдЬрд╛рд╡рд╛ рдХреЛрдб рдореЗрдВред

рдорд╛рд╡реЗрди рдореЗрдВ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпрд╛рдБ рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛


рдЬрдм рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирддрд╛ рд╣реИ, рддреЛ рдорд╛рд╡реЗрди рдЬрдирд░реЗрдЯрд░ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрдХрд╛рдЗрдпрд╛рдВ рдмрдирд╛рддрд╛ рд╣реИред рдФрд░ рдЖрдк рдХрд┐рд╕реА рднреА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╕рдордп рдкрд░ рдЬрдирд░реЗрдЯрд░ рдХреЛ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрдХрд╛рдЗрдпрд╛рдВ рдЙрддреНрдкрдиреНрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдЙрди рдХреНрд╖рдгреЛрдВ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдЬрдм, рдХрд╣рддреЗ рд╣реИрдВ, рдЖрдзрд╛рд░ рдХреА рд╕рдВрд░рдЪрдирд╛ рдмрджрд▓ рдЧрдИ рд╣реИред рдорд╛рд╡реЗрди рдореЗрдВ рдкреНрд▓рдЧрдЗрди рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

            <!-- JOOQ Generator Plugin -->
            <plugin>
                <groupId>org.jooq</groupId>
                <artifactId>jooq-codegen-maven</artifactId>
                <version>${jooq.version}</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <jdbc>  <!--    -->
                        <driver>${db.driver}</driver>
                        <url>${db.url}</url>
                        <user>${db.username}</user>
                        <password>${db.password}</password>
                    </jdbc>
                    <generator>
                        <database>
                            <includes>.*</includes>  <!--     -->
                            <excludes>  <!--     -->
                                flyway_schema_history
                            </excludes>
                            <inputSchema>public</inputSchema>  <!--  -->
                        </database>
                        <generate>
                            <records>true</records>
                        </generate>
                        <target>
                            <!--      -->
                            <packageName>ru.xpendence.jooqexample.domain</packageName>
                            <!--  .    target. -->
                            <directory>target/generated-sources/jooq</directory>
                        </target>
                    </generator>
                </configuration>
            </plugin>

рдпрджрд┐ рдЖрдкрдиреЗ рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдорд╛рд╡реЗрди рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ рдФрд░ рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХреЗ рдмреАрдЪ рдЖрдк jooq-codegen рджреЗрдЦреЗрдВрдЧреЗред



рдЪрд▓рд╛рдУред рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рдЗрдХрд╛рдЗрдпрд╛рдБ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛ред



рдпреЗ рдмрд╣реБрдд рд╣реА рдЗрдХрд╛рдЗрдпрд╛рдБ рд╣реИрдВ рдЬрд┐рдирдХрд╛ рдЙрдкрдпреЛрдЧ рдЖрдк рдбреЗрдЯрд╛рдмреЗрд╕ рддрдХ рдкрд╣реБрдБрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реЗрдВрдЧреЗред рдкрд╣рд▓рд╛ рдЙрдкрджреНрд░рд╡: рд╡реЗ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рд╣реИрдВред рдпрд╣реА рд╣реИ, рд╡реЗ рдЙрддреНрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рд╣реИрдВ, рд▓реЗрдХрд┐рди рдкреНрд░рдХрд╛рд░ рдкрд░рд┐рд╡рд░реНрддрди рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдЖрдХрд╕реНрдорд┐рдХ рддрд░реАрдХреЗ рд╕реЗ рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рд╡рд┐рд╡рд░рдг рдПрдХ рдЕрд▓рдЧ рд▓реЗрдЦ рдореЗрдВ рдЦреАрдВрдЪ рд▓рд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕рд▓рд┐рдП, рддрд╛рд▓рд┐рдХрд╛ рдкреАрдврд╝реА рдХреЗ рдЪрд░рдг рдореЗрдВ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдкрд░ рд╕реЛрдЪрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВред

рд╕рдВрд╕реНрдерд╛рдПрдВ рдЕрдЬреАрдмреЛрдЧрд░реАрдм рджрд┐рдЦрддреА рд╣реИрдВред рдпрд╣рд╛рдБ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, CountryRecord рд╡рд░реНрдЧ рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╣реИрдВ:

public class CountriesRecord extends UpdatableRecordImpl<CountriesRecord> implements Record4<Long, String, String, Integer> {
    //...

рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, CountryRecord рд░рд┐рдХреЙрд░реНрдб 4 рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ 4 рдкреНрд░рдХрд╛рд░реЛрдВ рджреНрд╡рд╛рд░рд╛ рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рджреЗрд╢реЛрдВ рдХреА рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ 4 рдХреЙрд▓рдо рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд░рд┐рдХреЙрд░реНрдб 4ред рд╢рд╣рд░реЛрдВ рдореЗрдВ 3 рдХреЙрд▓рдо рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд░рд┐рдХреЙрд░реНрдб 3ред рдЗрд╕рдХрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХреНрдпреЛрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛, рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ред JOOQ рд▓рд╛рдЗрдмреНрд░реЗрд░реА, рд░рд┐рдХреЙрд░реНрдб 1 ... рд░рд┐рдХреЙрд░реНрдб 22 рдореЗрдВ рдРрд╕реЗ 22 рд░рд┐рдХреЙрд░реНрдб рд╣реИрдВред рдЬрд┐рд╕рд╕реЗ рд╣рдо рдпрд╣ рдирд┐рд╖реНрдХрд░реНрд╖ рдирд┐рдХрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ JOOQ рдХреА рдХреНрд╖рдорддрд╛рдПрдВ рдЕрдзрд┐рдХрддрдо 22 рд╕реНрддрдВрднреЛрдВ рд╡рд╛рд▓реА рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдЯреЗрдмрд▓ рддрдХ рд╕реАрдорд┐рдд рд╣реИрдВ, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИред рдореЗрд░реЗ рдкрд╛рд╕ рджрд░реНрдЬрдиреЛрдВ рдХреЙрд▓рдо рд╣реИрдВ, рдФрд░ JOOQ рдмрд╕ рддреБрд░рдВрдд рд░рд┐рдХреЙрд░реНрдб рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рдареАрдХ рд╣реИ, рдХрд┐ ...

рдЬрд╛рд╡рд╛ рдХреЛрдб рдореЗрдВ JOOQ рдЗрдХрд╛рдЗрдпрд╛рдБ рдмрдирд╛рдирд╛ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

@Component
public class AfterStartupApplicationListener implements ApplicationListener<ContextRefreshedEvent> {

    @Value("${spring.datasource.driver-class-name}")
    private String driver;

    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;

    @Value("${jooq.generator.database.name}")
    private String databaseName;

    @Value("${jooq.generator.database.with-includes}")
    private String databaseWithIncludes;

    @Value("${jooq.generator.database.with-input-schema}")
    private String databaseWithInputSchema;

    @Value("${jooq.generator.target.package-name}")
    private String targetPackageName;

    @Value("${jooq.generator.target.directory}")
    private String targetDirectory;

    @SneakyThrows
    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        new GenerationTool().run(configureGenerator());
    }

    private Configuration configureGenerator() {
        return new Configuration()
                .withJdbc(new Jdbc()
                        .withDriver(driver)
                        .withUrl(url)
                        .withUser(username)
                        .withPassword(password))
                .withGenerator(new Generator()
                        .withDatabase(new Database()
                                .withName(databaseName)
                                .withIncludes(databaseWithIncludes)
                                .withExcludes("")
                                .withInputSchema(databaseWithInputSchema))
                        .withTarget(new Target()
                                .withPackageName(targetPackageName)
                                .withDirectory(targetDirectory)));
    }
}

рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЬрдирд░реЗрдЯрд░ рдЖрд╡реЗрджрди рдХреА рдкреВрд░реА рд╢реБрд░реБрдЖрдд рдХреЗ рдмрд╛рдж рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдЬрдм рд╕рднреА рдирдП рдорд╛рдЗрдЧреНрд░реЗрд╢рди рд░реЛрд▓ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдЕрджреНрдпрддрд┐рдд рд╣реЛрддрд╛ рд╣реИред

рдЗрд╕рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдореЙрдбрд▓ рд╣реИрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЗрдХрд╛рдЗрдпрд╛рдВ рд╣реИрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЖрдзрд╛рд░ рд╣реИред рдпрд╣ рдПрдХ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдмрдирд╛рдиреЗ рдФрд░ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХрд╛ рд╕рдордп рд╣реИред

рд░рд┐рдкреЛрдЬрд┐рдЯрд░реА рдмрдирд╛рдПрдВ


рд╕рднреА рдЕрдиреБрд░реЛрдз DslContext рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рддреЗ рд╣реИрдВред DslContext рдХреЛ рджреЛрд╣рд░рд╛рдПрдВред

@Repository
@RequiredArgsConstructor
public class CountryRepository implements CrudRepository<Country> {

    private final DSLContext dsl;

} 

рднрдВрдбрд╛рд░ рддреИрдпрд╛рд░ рд╣реИред

рд▓реЗрдЦрди CRUD рдкреНрд░рд╢реНрди


рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░реЗрдВ


рдпрджрд┐ рд╣рдо SQL рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рджреВрд╕рд░реЗ рджреЗрд╢ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдЕрдиреБрд░реЛрдз рд╣реЛрдЧрд╛:

insert into countries(name, government_form, population)
values (' -', 'UNITARY', 100500) returning *;

JOOQ рдореЗрдВ, SQL рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреНрд╡реЗрд░реА рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЙрддрдирд╛ рдХрд░реАрдм рд╣реИ:

    public Country insertValues(Country country) {
        return dsl.insertInto(Countries.COUNTRIES)  //insert into countries
                .values(country.getId(), country.getName(), country.getPopulation(), nameOrNull(country.getGovernmentForm()))  //values (? ? ? ?)
                .returning()  //returning
                .fetchOne()  //*
                .into(Country.class);
    }

рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ, рдХреБрдЫ рднреА рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕ рддрд░рд╣ рдХрд╛ рдЕрдиреБрд░реЛрдз рд╣рдореЗрдВ рд╢реЛрднрд╛ рдирд╣реАрдВ рджреЗрддрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЖрдИрдбреА рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИ рдФрд░ рд╣рдореЗрдВ рдЗрд╕реЗ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЕрдЧрд░ рд╣рдо рдХреБрдЫ рд▓рд┐рдЦрддреЗ рд╣реИрдВ:

.values(null, country.getName(), country.getPopulation(), nameOrNull(country.getGovernmentForm()))

рд╣рдо рдорд┐рд▓реЗрдВрдЧреЗ

org.postgresql.util.PSQLException: :     "id"   NOT NULL

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрджрд┐ рд╣рдордиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкрдХреНрд╖ рдореЗрдВ рдЖрдИрдбреА рдЬрдирд░реЗрдЯ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдРрд╕рд╛ рдЕрдиреБрд░реЛрдз рдПрдХ рд╕рд╡рд╛рд░реА рд╣реЛрдЧрд╛ред рд╣рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдХреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдореВрд▓реНрдп рджреЗрддреЗ рд╣реБрдП рдЕрдиреБрд░реЛрдз рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ред рддреЛ рддреБрдо рдХрд░ рд╕рдХрддреЗ рд╣реЛ:

    public Country insert(Country country) {
        return dsl.insertInto(Countries.COUNTRIES)
                .set(Countries.COUNTRIES.NAME, country.getName())
                .set(Countries.COUNTRIES.POPULATION, country.getPopulation())
                .set(Countries.COUNTRIES.GOVERNMENT_FORM, nameOrNull(country.getGovernmentForm()))
                .returning()
                .fetchOne()
                .into(Country.class);
    }

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдлрд╝реАрд▓реНрдб рдореЗрдВ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рд╡рд┐рдХрд▓реНрдк рдХрд╛рдлреА рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдмреЗрд╣рддрд░ рд╣реИред рдмрдЪрдд рдХреЗ рд▓рд┐рдП рдкреВрд░реА рд╡рд╕реНрддреБ рднреЗрдЬрдирд╛ рдЖрджрд░реНрд╢ рд╣реЛрдЧрд╛, рдЬреИрд╕рд╛ рдХрд┐ рд╕реНрдкреНрд░рд┐рдВрдЧ рдбреЗрдЯрд╛ рдЬреЗрдкреАрдП рдореЗрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

repository.save(country);

рдРрд╕рд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЕрдкрдиреЗ рдореЙрдбрд▓ рдХреЛ рд░рд┐рдХреЙрд░реНрдб рдЗрдХрд╛рдИ рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд░рдиреЗ рдФрд░ рдЗрд╕реЗ рд╕рд╣реЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рднреЗрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

    public Country insert(Country country) {
        return dsl.insertInto(Countries.COUNTRIES)
                .set(dsl.newRecord(Countries.COUNTRIES, country))  //   
                .returning()
                .fetchOptional()
                .orElseThrow(() -> new DataAccessException("Error inserting entity: " + country.getId()))
                .into(Country.class);
    }

рдпрд╣ рд╡рд┐рдзрд┐ рдЙрди рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рд╕рд░рд▓ рдФрд░ рд╕рдмрд╕реЗ рд╕рдордЭрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдЬрдм рд╣рдореЗрдВ рдореИрдкрд┐рдВрдЧ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред рд▓реЗрдХрд┐рди рдореИрдкрд┐рдВрдЧ рдХреА рд╕реЗрдЯрд┐рдВрдЧ рдХрдо рд╣реЛрдЧреАред

рдЬреИрд╕рд╛ рдХрд┐ рд╣рдордиреЗ рджреЗрдЦрд╛, рдпрд╣ рдХреНрд╡реЗрд░реА рдкреВрд░реА рдЗрдХрд╛рдИ рдХреЛ рд▓реМрдЯрд╛рддреА рд╣реИред рдЖрдк рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЖрдкрдХреЛ рднреНрд░реВрдг () рд╡рд┐рдзрд┐ рдореЗрдВ рд╡рд╛рдкрд╕ рдЖрдиреЗ рдХреА рдХреНрдпрд╛ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд░рд╣рд╛ рд╣реИ:

    public Long insertAndReturnId(Country country) {
        return dsl.insertInto(Countries.COUNTRIES)
                .set(dsl.newRecord(Countries.COUNTRIES, country))
                .returning(Countries.COUNTRIES.ID) //  Record    - id
                .fetchOptional()
                .orElseThrow(() -> new DataAccessException("Error inserting entity: " + country.getId()))
                .get(Countries.COUNTRIES.ID); // id
    }

рдереЛрдбрд╝рд╛ рдмреЛрдЭрд┐рд▓, рд▓реЗрдХрд┐рди, рдлрд┐рд░, рдХреНрдпрд╛ рддреБрд▓рдирд╛ рдХреЗ рд╕рд╛рдеред

рд╣рдо рд╕реАрдЖрд░рдпреВрдбреА рдХреЗ рдмрд╛рдХреА рддрд░реАрдХреЛрдВ рдХреЛ рд▓рд┐рдЦреЗрдВрдЧреЗред

рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ


SQL рдХреНрд╡реЗрд░реА:

update countries
set name            = '',
    government_form = 'CONFEDERATE',
    population      = 100500
where id = 1
returning *;

JOOQ рдЕрдиреБрд░реЛрдз:

    public Country update(Country country) {
        return dsl.update(Countries.COUNTRIES)
                .set(dsl.newRecord(Countries.COUNTRIES, country))
                .where(Countries.COUNTRIES.ID.eq(country.getId()))
                .returning()
                .fetchOptional()
                .orElseThrow(() -> new DataAccessException("Error updating entity: " + country.getId()))
                .into(Country.class);
    }

рдЪреБрдирддреЗ рд╣реИрдВ


SQL рдореЗрдВ рдПрдХ рдХреНрд╡реЗрд░реА рд╣реЛрдЧреА:

select *
from countries c
where id = ?;

JOOQ рдореЗрдВ, рдХреНрд╡реЗрд░реА рддрджрдиреБрд╕рд╛рд░ рджрд┐рдЦрд╛рдИ рджреЗрдЧреА:

    public Country find(Long id) {
        return dsl.selectFrom(Countries.COUNTRIES) //select * from countries
                .where(Countries.COUNTRIES.ID.eq(id))  //where id = ?
                .fetchAny()  // ,    
                .into(Country.class);
    }

рд╣рдЯрд╛рдПрдВ


рдРрд╕реЗ рдЕрдиреБрд░реЛрдз рд╣реИрдВ рдЬрд┐рдирдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд▓реМрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИред рдЗрд╕ рддрд░рд╣ рдХреА рдХреНрд╡реЗрд░реА рдкреНрд░рднрд╛рд╡рд┐рдд рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рд▓реМрдЯрд╛рддреА рд╣реИред рд╣рдЯрд╛рдиреЗ рдореЗрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд▓реМрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЬреЛ рдЬрд╛рдирдХрд╛рд░реА рд╣рдореЗрдВ рдорд┐рд▓рддреА рд╣реИ рд╡рд╣ рдЕрднреА рднреА рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧреАред

    public Boolean delete(Long id) {
        return dsl.deleteFrom(Countries.COUNTRIES)
                .where(Countries.COUNTRIES.ID.eq(id))
                .execute() == 1;
    }

рд╣рдо рдПрдХ рд▓рд╛рдЗрди рд╣рдЯрд╛рддреЗ рд╣реИрдВред рддреЛ SQL рдХреНрд╡реЗрд░реА рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧреА:

1 row affected in 5 ms

рдРрд╕рд╛ рдЙрддреНрддрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдкрдВрдХреНрддрд┐ рд╣рдЯрд╛ рджреА рдЧрдИ рд╣реИред рдпрд╣ рдСрдкрд░реЗрд╢рди рдХреЛ рд╕рдлрд▓ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдЧрд╛ред

рдпрд╣ рдПрдХ рдкрд░реА рдХрдерд╛ рдирд╣реАрдВ рдереАред рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рд╕реНрдиреЗрд╣рдХ рдерд╛ред рд░рд┐рдХреЙрд░реНрдб рдореЗрдВ рдПрдХ рдЗрдХрд╛рдИ рдХреА рдкрддрд▓реА рдореИрдкрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рдирд┐рдпрдорд┐рдд рдкреЗрдкрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд


"рдареАрдХ рд╣реИ," рдЖрдк рдХрд╣рддреЗ рд╣реИрдВ, рдкрд╛рдардХ, "рдПрдХ-рд╕реЗ-рдХрдИ, рдПрдореЛ рдХрд╣рд╛рдБ рд╣реИ?" рдореИрдВрдиреЗ рдХреБрдЫ рдРрд╕рд╛ рдирд╣реАрдВ рджреЗрдЦрд╛, рдЬрд┐рд╕рдореЗрдВ рджреЗрд╢ рд╢рд╣рд░ рдХреА рднреАрдбрд╝ рдХреЗ рд╕рд╛рде рдмрдврд╝рддрд╛ рд╣реИред тАЭ

рдФрд░ рдЖрдк рд╕рд╣реА рд╣реЛрдВрдЧреЗред рдпрд╣ рд╣рд╛рдЗрдмрд░рдиреЗрдЯ рдирд╣реАрдВ рд╣реИ, рдпрд╣рд╛рдВ рдЖрдкрдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЖрдкрдХреЛ рдмрд╕ рдЙрд╕ рд╢рд╣рд░ рдХреА рд╕реВрдЪреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреА рд╣реИ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП id = country.getId () рд╣реИред рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА () рд╡рд┐рдзрд┐ рджрд┐рдЦрд╛рдИ рд╣реИ, рдЬреЛ рдПрдХ рдЗрдХрд╛рдИ рдореЗрдВ рд░рд┐рдХреЙрд░реНрдб рдХреЛ рдореИрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдирд┐рдпрдорд┐рдд рдореИрдкрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди JOOQ рдХреЗ рдкрд╛рд╕ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдирдХреНрд╢рд╛ () рд╡рд┐рдзрд┐ рд╣реИ рдЬреЛ рд╣рдореЗрдВ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд╕рд╛рде рдЬреЛ рдХреБрдЫ рднреА рдХрд░рдирд╛ рд╣реИ, рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЖрдЗрдП рдЗрд╕рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рджреЗрдЦреЗрдВ рдФрд░ рд╢рд╣рд░реЛрдВ рдХреЛ рдЬреЛрдбрд╝реЗрдВ:

    public Country find(Long id) {
        return dsl.selectFrom(Countries.COUNTRIES)
                .where(Countries.COUNTRIES.ID.eq(id))
                .fetchAny()
                .map(r -> {
                    Country country = r.into(Country.class);
                    country.setCities(cityRepository.findAll(Cities.CITIES.COUNTRY_ID.eq(country.getId())));
                    return country;
                });
    }

рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ, рдЕрдм рд╣рдо рдкрд╣рд▓реЗ рджреЗрд╢ рдореЗрдВ рд░рд┐рдХреЙрд░реНрдб рдХрд╛ рдирдХреНрд╢рд╛ рдмрдирд╛рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рд╣рдо рд╢рд╣рд░реЛрдВ рдореЗрдВ рдПрдХ рдФрд░ рдЕрдиреБрд░реЛрдз рдХрд░рддреЗ рд╣реИрдВ, рд╣рдо рдЗрд╕ рджреЗрд╢ рдХреЗ рд▓рд┐рдП рд╕рднреА рд╢рд╣рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╕рд╛рд░ рдореЗрдВ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВред

рд▓реЗрдХрд┐рди рдРрд╕реЗ рджрд░реНрдЬрдиреЛрдВ рд╕реЗрдЯ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рджрд░реНрдЬрдиреЛрдВ рдЕрдиреБрд░реЛрдз рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдФрд░ рдЗрди рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕реАрдзреЗ рд╡рд┐рдзрд┐ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдРрд╕рд╛ рд╣реИред рд╕рд╣реА рд╕рдорд╛рдзрд╛рди рдПрдХ рдЕрд▓рдЧ рдореИрдкрд░ рд▓рд┐рдЦрдирд╛ рд╣реИ рдФрд░ рдЗрди рд╕рднреА рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╡рд╣рд╛рдВ рд░рдЦрдирд╛ рд╣реИред

@RequiredArgsConstructor
@Component
public class CountryRecordMapper implements RecordMapper<CountriesRecord, Country> {

    private final CityRepository cityRepository;

    @Override
    public Country map(CountriesRecord record) {
        Country country = record.into(Country.class);
        country.setCities(cityRepository.findAll(Cities.CITIES.COUNTRY_ID.eq(country.getId())));
        return country;
    }
}

рдХреНрд╡реЗрд░реА рдЕрдм рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧреА:

    public Country findWithCustomMapper(Long id) {
        return dsl.selectFrom(Countries.COUNTRIES)
                .where(Countries.COUNTRIES.ID.eq(id))
                .fetchAny()
                .map(r -> countryRecordMapper.map((CountriesRecord) r));
    }

рдпрд╣ рдЕрдзрд┐рдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╣реИ, рдФрд░ рдЗрд╕рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХ рдирд╣реАрдВ рд╣реИрдВред

рдареАрдХ рд╣реИ, рд╣рдордиреЗ рд╕реАрдЦрд╛ рдХрд┐ рд░рд┐рдХреЙрд░реНрдб рдХреЛ рдПрдХ рдЗрдХрд╛рдИ рдореЗрдВ рдХреИрд╕реЗ рдореИрдк рдХрд┐рдпрд╛ рдЬрд╛рдП, рд▓реЗрдХрд┐рди рд░рд┐рдХреЙрд░реНрдб рдореЗрдВ рдХрд┐рд╕реА рдЗрдХрд╛рдИ рдХреА рдореИрдкрд┐рдВрдЧ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛?


рдЕрдм рддрдХ рд╣рдо рдЗрд╕ рдбрд┐рдЬрд╛рдЗрди:

.set(dsl.newRecord(Countries.COUNTRIES, country))

рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрдЪреНрдЫрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рд╣рдореЗрдВ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдПрдХ рдХреНрд╖реЗрддреНрд░ рдХреЛ рдореИрдк рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ? рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╡рд╣рд╛рдВ LocalDateTime рд╣реИ, рдФрд░ рдЯрд╛рдЗрдорд╕реНрдЯреИрдореНрдк рдЬреИрд╕реЗ PostgreSQL рдХреЗ рд▓рд┐рдП рдПрдХ рдЬрдирд░реЗрдЯрд░ рдиреЗ рдПрдХ рдСрдлрд╕реЗрдЯрд╕реЗрдЯреЗрдЯ рдЙрддреНрдкрдиреНрди рдХрд┐рдпрд╛ред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдлрд╝реАрд▓реНрдб рдХреЛ рдХреЗрд╡рд▓ рдореИрдк рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рджрд░реНрдЬ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рдФрд░ рдореИрдкрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдЬреЛ рдРрд╕рд╛ рд╣реА рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рд╡рд┐рдкрд░реАрдд рджрд┐рд╢рд╛ рдореЗрдВред

рд╣рд╛рдВ, рд╣рд░ рдореИрдкрд░ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрдирдореИрдкрд░ рд╣реИ


рдЙрд╕реЗ рд╡рд╣ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрд╕рдХрд╛ рд╡рд╛рд░рд┐рд╕ рд▓рд┐рдЦреВрдБред

@Component
@RequiredArgsConstructor
public class CountryRecordUnmapper implements RecordUnmapper<Country, CountriesRecord> {

    private final DSLContext dsl;

    @Override
    public CountriesRecord unmap(Country country) throws MappingException {
        CountriesRecord record = dsl.newRecord(Countries.COUNTRIES, country);
        record.setPopulation(-1);
        return record;
    }
}

рдЗрд╕рдХреЗ рдЖрд╡реЗрджрди рдХреЗ рд╕рд╛рде рдбрд╛рд▓реЗрдВ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:

    public Country insertWithUnmapper(Country country) {
        return dsl.insertInto(Countries.COUNTRIES)
                .set(countryRecordUnmapper.unmap(country))
                .returning()
                .fetchOptional()
                .orElseThrow(() -> new DataAccessException("Error inserting entity: " + country.getId()))
                .into(Country.class);
    }

рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ, рдХрд╛рдлреА рд╣реИред

рдирд┐рд╖реНрдХрд░реНрд╖ рдФрд░ рдирд┐рд╖реНрдХрд░реНрд╖


рдирд┐рдЬреА рддреМрд░ рдкрд░, рдореБрдЭреЗ рд╣рд╛рдЗрдмрд░рдиреЗрдЯ рдЕрдзрд┐рдХ рдкрд╕рдВрдж рд╣реИред рд╕рдВрднрд╡рддрдГ, 90 +% рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдзрд┐рдХ рдЙрдЪрд┐рдд рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк, рдкрд╛рдардХ, рд╣рд░ рдЕрдиреБрд░реЛрдз рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ JOOQ рдпрд╛ рдЗрд╕реА рддрд░рд╣ рдХреА рдЕрдиреНрдп рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдЖрдкрдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рдЙрдкрдпреБрдХреНрдд рд╣реИред

рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рдореИрдВ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкреЛрд╕реНрдЯ рдХрд░рддрд╛ рд╣реВрдВред рд╡рд╣ рдпрд╣рд╛рдВ рдкрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ ред

All Articles