在 jdbcTemplate.update(String sql,Object[] args,int[] argTypes) 和 jdbcTemplate.update(String sql,Object[] args) 之间进行选择
Choosing between jdbcTemplate.update(String sql,Object[] args,int[] argTypes) and jdbcTemplate.update(String sql,Object[] args)
我正在学习 Spring Boot 和 jdbcTemplate 的组合以进行一些基本的 crud 操作,并试图更好地了解我应该选择哪种更新方法。
我了解以下两种 class 方法(改编自 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.");
}
但我不清楚为什么 would/should 使用第一个指定参数类型的参数。我读过 the javadoc 但我仍然不确定为什么我需要指定类型。我错过了什么?
设置参数类型为基础 SQL 语句提供正确性和优化(轻微)。 (JdbcTemplate
在内部构建一个 PreparedStatement
并使用 provided/derived 类型为其设置值)。
在你的例子中,如果你没有指定 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 类型是一个很好的做法。
没有Type
参数:
sql SQL containing bind parameters args arguments to bind to the query
(leaving it to the PreparedStatement to guess the corresponding SQL
type); may also contain SqlParameterValue objects which indicate not
only the argument value but also the SQL type and optionally the scale
使用 Type
参数:
sql SQL containing bind parameters args arguments to bind to the query
argTypes SQL types of the arguments (constants from java.sql.Types)
我正在学习 Spring Boot 和 jdbcTemplate 的组合以进行一些基本的 crud 操作,并试图更好地了解我应该选择哪种更新方法。
我了解以下两种 class 方法(改编自 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.");
}
但我不清楚为什么 would/should 使用第一个指定参数类型的参数。我读过 the javadoc 但我仍然不确定为什么我需要指定类型。我错过了什么?
设置参数类型为基础 SQL 语句提供正确性和优化(轻微)。 (JdbcTemplate
在内部构建一个 PreparedStatement
并使用 provided/derived 类型为其设置值)。
在你的例子中,如果你没有指定 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 类型是一个很好的做法。
没有Type
参数:
sql SQL containing bind parameters args arguments to bind to the query (leaving it to the PreparedStatement to guess the corresponding SQL type); may also contain SqlParameterValue objects which indicate not only the argument value but also the SQL type and optionally the scale
使用 Type
参数:
sql SQL containing bind parameters args arguments to bind to the query argTypes SQL types of the arguments (constants from java.sql.Types)