我想知道如何使用PreparedStatementCreatorFactory。据我所知,它与以下代码类似,只是在极少数的例子中,不仅sql被提供给工厂,而且还有一个int[]类型,但我不想传入数百个类型,因为如果您将params作为object[]传递,jdbc通常会基于java类型检索类型。我使用的是Spring 3.1.3 RELEASE。
public int addEntityAndGetId(String name, String address){
String sql = "INSERT INTO mytable (NAME,ADDRESS) VALUES (?,?)";
Object[] params = new Object[]{name,address};
PreparedStatementCreatorFactory factory = new PreparedStatementCreatorFactory(sql);
PreparedStatementCreator psc = factory.newPreparedStatementCreator(params);
KeyHolder generatedKeyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(psc, generatedKeyHolder);
return generatedKeyHolder.getKey().intValue();
}
但我得到的只是一个org.springframework.dao.InvalidDataAccessApiUsageException。
我真的需要这些类型吗?就像在每个jdbc更新语句上一样,您只需传递一个对象[],它就可以了。
这个问题的目的是绕过指定任何列类型的需要,并通过让jdbc确定哪种列类型适合哪个对象来避免对crud查询使用PreparedStatementSetters。
您有两个不同的错误。一个症状,一个原因。
首先是症状:正如M.Deinum所说,您得到了一个ClassNotFoundException:
org.springframework.dao.InvalidDataAccessApiUsageException
,因为您在类路径中缺少spring-tx
。添加它是因为如果你不添加它,你会遇到麻烦。
接下来是原因。您使用new PreparedStatementCreatorFactory(sql);
创建您的工厂。javadoc说:创建一个新工厂。需要通过addParameter(org.springframework.jdbc.core.SqlParameter)方法添加参数,或者没有参数
您既没有在PreparedStatementCreatorFactory
的构造函数中,也没有在对newPreparedStatementCreator()
的调用中声明参数的类型。因此Spring发布了异常。
不,您不能简单地将Object[]
传递给update语句,因为底层JBDC调用将需要对象的实际类型(有setInt
、setString
…方法)。
现在开始修复。由于您将向更新方法传递2个字符串,因此应该以这种方式创建工厂:
PreparedStatementCreatorFactory factory = new PreparedStatementCreatorFactory(sql,
new int[]{Types.VARCHAR, Types.VARCHAR});
(假设列的类型为VARCHAR
)
但这还不够。当您想要为新插入的行取回生成的主键时,必须声明它:
factory.setReturnGeneratedKeys(true);
最后,如果您使用PosgreSQL,您可能必须使用
generatedKeyHolder.getKeys().get("id");
而不是简单的generatedKeyHolder.getKey().intValue()
(假设包含生成密钥的列的名称为id
)