如何使用 org.springframework.jdbc.object 实现可重用的 ddl 语句?

Posted

技术标签:

【中文标题】如何使用 org.springframework.jdbc.object 实现可重用的 ddl 语句?【英文标题】:How to use org.springframework.jdbc.object to implement reusable ddl statements? 【发布时间】:2020-09-16 16:24:38 【问题描述】:

我想使用 org.springframework.jdbc.object 包中的实体来对数据库的访问进行建模。

很清楚如何为选择、更新、插入和删除查询创建对象。我们可以扩展MappingSqlQuery<?>SqlUpdate,然后声明所有参数,在一些map中收集命名参数并执行语句stmt.executeByNamedParam(Map<String, ?> paramMap);

目前尚不清楚我们如何使用org.springframework.jdbc.object 包来实现 ddl 语句,例如创建模式/表或更改表。 例如,我想动态创建模式,查询如下所示:create schema if not exists schema_name。 我用下一种方式创建语句:

public final class CreateSchemaStmt extends SqlUpdate 

    private static final String CREATE_SCHEMA_SQL_TEMPLATE =
            "create schema if not exists ?";

    public CreateSchemaStmt(DataSource ds) 
        setDataSource(ds);
        setSql(CREATE_SCHEMA_SQL_TEMPLATE);
        declareParameter(new SqlParameter("schema", Types.VARCHAR));
        compile();
    

但是不可能以这种方式声明参数并将其传递给语句执行。 当然,当我需要创建新的模式/表或更改表(使用不带占位符的 sql 查询)时,我总是可以创建新语句,但在这种情况下,该语句将无法重用。

可以使用命名参数创建和执行这种查询吗?

【问题讨论】:

【参考方案1】:

不,不能重复使用 DDL 语句。表名、列名、列数据类型等的任何变化都会是一个不同的语句。

org.springframework.jdbc.object 包中的所有类都是使用PreparedStatement 的助手,而 DDL 语句不会从准备中受益。

对于 DDL,使用 JdbcTemplateexecute(String sql) 方法。正如该方法的 javadoc 所说:

发出单个 SQL 执行,通常是 DDL 语句

不要专注于工具。当你说“我想使用来自org.springframework.jdbc.object 包的实体”时,你过于关注这个工具了。您应该专注于需要完成的工作,然后选择适合该工作的工具。对于 DDL 语句,JdbcTemplate.execute(sql) 是正确的工具。

使用batchUpdate(String... sql) 并忽略返回值,如果您有很多 条DDL 语句要执行并且性能至关重要。但对于 DDL 语句,情况不太可能如此。

【讨论】:

感谢您的详细回答!

以上是关于如何使用 org.springframework.jdbc.object 实现可重用的 ddl 语句?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 org.springframework.jdbc.CannotGetJdbcConnectionException 上记录 JDBC 连接信息

如何在 Grails 3 中捕获“org.springframework.web.multipart.MultipartException”

MongoDB $addFields 使用 org.springframework.data.mongodb.core.MongoTemplate

未找到 ID 为“org.springframework.boot”的插件

如何修复 Grails 应用程序中的 org.springframework.beans.factory.BeanCreationException 错误?

如何修复 org.springframework.beans.factory.UnsatisfiedDependencyException:创建名称为“name”的 bean 时出错?