使用 JOOQ,为啥要在 insertInto().values() 中使用 DSL.param()?

Posted

技术标签:

【中文标题】使用 JOOQ,为啥要在 insertInto().values() 中使用 DSL.param()?【英文标题】:Using JOOQ, why would you use DSL.param() in insertInto().values()?使用 JOOQ,为什么要在 insertInto().values() 中使用 DSL.param()? 【发布时间】:2022-01-09 09:52:09 【问题描述】:

我是 JOOQ 的新手,正在努力加快现有代码库的速度(不幸的是,负责此特定代码的开发人员已不在我们身边)。

插入代码看起来像这样(简化):

public class User 

    public static Table<?> table = DSL.table("user");

    public static Field<String> firstName = DSL.field(DSL.name(table.getName(), "first_name"), String.class);
    public static Field<String> lastName = DSL.field(DSL.name(table.getName(), "last_name"), String.class);


private class UserDto 

    private String firstName;
    private String lastName;

    // getters, setters, etc.


public class UserWriter 

    private final DefaultDSLContext dslContext;

    public UserWriter(DefaultDSLContext dslContext) 
        this.dslContext = dslContext;
    

    public void create(UserDto user) 

        dslContext.insertInto(User.table, User.firstName, User.lastName)
            .values(
                DSL.param(User.firstName.getName(), user.getFirstName()),
                DSL.param(User.lastName.getName(), user.getLastName()),
            )
            .execute();
    

既然可以简单地使用实际值,为什么还要在 values() 中使用 DSL.param() ?

dslContext.insertInto(User.table, User.firstName, User.lastName)
    .values(user.getFirstName(), user.getLastName())
    .execute();

这只是不必要的冗长还是我遗漏了什么?

谢谢!

【问题讨论】:

【参考方案1】:

您的param() 使用情况

这只是不必要的冗长还是我遗漏了什么?

是的,在你的情况下它是不必要的冗长。请改用您建议的版本。

在 jOOQ 的 API 的大多数情况下,对于假设的 T|Field&lt;T&gt; 类型总是有一个方便的重载,因此您可以在任何可能的列表达式 (Field&lt;T&gt;) 的地方传递绑定值 (Field&lt;T&gt;),并且绑定值将自动包装在:DSL.val(value, column)

DSL.param() 允许在有意义的地方创建命名绑定参数标记(例如,将 SQL 字符串导出到 Spring 或其他支持命名参数的工具时)。在 jOOQ 中,命名参数几乎没有用处。

另请参阅手册中有关绑定值的部分: https://www.jooq.org/doc/latest/manual/sql-building/bind-values/

其他冗长

似乎param() 并不是您的代码库中唯一重视冗长的地方。 jOOQ 附带了一个非常强大的source code generator,它可以为你生成UserUserDto 类。

只有在使用代码生成器(类型安全除外)时,您才能获得很多功能,例如implicit joins.

【讨论】:

以上是关于使用 JOOQ,为啥要在 insertInto().values() 中使用 DSL.param()?的主要内容,如果未能解决你的问题,请参考以下文章

在 jOOq 中,为啥连接与语句构造高度耦合?

INSERT..RETURNING 在 JOOQ 中不起作用

如何将带有 AES_ENCRYPT 的 mariadb ddl 转换为 jooq?

JOOQ:单个语句是隐式事务性的,还是我仍然必须将其包装在事务性块中?

为啥这不会超载?

如何调试 Gradle 为啥使用我在依赖子项目中指定的不同版本的库?