【问题标题】:Choosing between jdbcTemplate.update(String sql,Object[] args,int[] argTypes) and jdbcTemplate.update(String sql,Object[] args)在 jdbcTemplate.update(String sql,Object[] args,int[] argTypes) 和 jdbcTemplate.update(String sql,Object[] args) 之间进行选择
【发布时间】:2019-01-12 11:35:36
【问题描述】:

我正在学习结合 Spring Boot 和 jdbcTemplate 进行一些基本的 crud 操作,并试图更好地了解我应该选择哪种更新方法。

我了解以下两种类方法(改编自this post)会将相同的记录写入数据库。

示例 1:

public class InsertDemo {
private static final String sql =
        "INSERT INTO records (title, " +
        "    release_date, " +
        "    artist_id, " +
        "    label_id, " +
        "    created) " +
        "VALUES (?, ?, ?, ?, ?)";

private DataSource dataSource;

public InsertDemo(DataSource dataSource) {
    this.dataSource = dataSource;
}

public void saveRecord(String title, Date releaseDate,
                       Integer artistId, Integer labelId) {
    JdbcTemplate template = new JdbcTemplate(this.dataSource);

    Object[] params = new Object[] {
            title, releaseDate, artistId, labelId, new Date()
    };
    int[] types = new int[] {
            Types.VARCHAR,
            Types.DATE,
            Types.INTEGER,
            Types.INTEGER,
            Types.DATE
    };

    int row = template.update(sql, params, types);
    System.out.println(row + " row inserted.");
}

示例 2:

public class InsertDemo {
private static final String sql =
        "INSERT INTO records (title, " +
        "    release_date, " +
        "    artist_id, " +
        "    label_id, " +
        "    created) " +
        "VALUES (?, ?, ?, ?, ?)";

private DataSource dataSource;

public InsertDemo(DataSource dataSource) {
    this.dataSource = dataSource;
}

public void saveRecord(String title, Date releaseDate,
                       Integer artistId, Integer labelId) {
    JdbcTemplate template = new JdbcTemplate(this.dataSource);

    Object[] params = new Object[] {
            title, releaseDate, artistId, labelId, new Date()
    };

    int row = template.update(sql, params);
    System.out.println(row + " row inserted.");
}

但我不清楚为什么我会/应该使用第一个指定参数类型的参数。我已经阅读了the javadoc,但我仍然不确定为什么需要指定类型。我错过了什么?

【问题讨论】:

    标签: java spring-boot jdbctemplate


    【解决方案1】:

    设置参数类型为底层 SQL 语句提供了正确性和优化(轻微)。 (JdbcTemplate 在内部构建 PreparedStatement 并使用提供/派生类型为其设置值)。

    在您的示例中,如果您未指定 Types 数组,它们将被设置为 SqlTypeValue.TYPE_UNKOWN 最终被猜测或解析为;

    if (sqlType == SqlTypeValue.TYPE_UNKNOWN || sqlType == Types.OTHER) {
                if (isStringValue(inValue.getClass())) {
                    ps.setString(paramIndex, inValue.toString());
                }
                else if (isDateValue(inValue.getClass())) {
                    ps.setTimestamp(paramIndex, new java.sql.Timestamp(((java.util.Date) inValue).getTime()));
                }
                else if (inValue instanceof Calendar) {
                    Calendar cal = (Calendar) inValue;
                    ps.setTimestamp(paramIndex, new java.sql.Timestamp(cal.getTime().getTime()), cal);
                }
                else {
                    // Fall back to generic setObject call without SQL type specified.
                    ps.setObject(paramIndex, inValue);
                }
            }
    

    看看org.springframework.jdbc.core.StatementCreatorUtils#setValue

    所以设置 arg 类型是一个好习惯。

    【讨论】:

    • 感谢详细的解释!
    • 你知道什么是整数类型的代码吗?例如,我应该为 integer、varchar 或 text 选择哪个代码? PS:好像是在java.sql.Types找到的
    【解决方案2】:

    不带Type参数:

    sql SQL 包含绑定参数 args 参数绑定到查询 (留给PreparedStatement去猜测对应的SQL 类型);还可能包含 SqlParameterValue 对象,这些对象指示不 只有参数值,还有 SQL 类型和可选的比例

    Type参数:

    sql SQL 包含绑定参数 args 参数绑定到查询 argTypes 参数的 SQL 类型(来自 java.sql.Types 的常量)

    【讨论】:

    • 您是否有可能在此答案中调换了“with”和“without”?第一个说“with”,但随后声明“将其留给 PreparedStatement 来猜测相应的 SQL 类型”,但根据上面的@Laksitha-Ranasingha 回答,似乎 without 会留下什么这取决于提到的猜测。
    猜你喜欢
    • 2016-05-07
    • 2011-08-25
    • 1970-01-01
    • 2013-12-11
    • 2014-09-03
    • 2015-09-06
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    相关资源
    最近更新 更多