我想知道如何使用PreparedStatementCreatorFactory。至于read,它就像下面的代码一样,除了在极少数的例子中,不仅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的需要。
答案 0 :(得分:1)
您有2种不同的错误。一个症状和一个原因。
首先是症状:你得到一个ClassNotFoundException:
org.springframework.dao.InvalidDataAccessApiUsageException
,因为你在类路径中缺少spring-tx
,因为M.Deinum说。添加它是因为如果不这样做会遇到麻烦。
接下来的原因。您使用new PreparedStatementCreatorFactory(sql);
创建工厂。 javadoc说:创建一个新工厂。需要通过addParameter(org.springframework.jdbc.core.SqlParameter)方法添加参数或没有参数
您既不在PreparedStatementCreatorFactory
的构造函数中声明参数类型,也不在newPreparedStatementCreator()
的调用中声明参数类型。所以Spring发布了例外。
不,不能简单地将Object[]
传递给更新语句,因为基础JBDC调用需要实际的对象类型(setInt
,setString
,. ..方法)。
现在进行修复。由于您将2个字符串传递给update方法,因此您应该以这种方式创建工厂:
PreparedStatementCreatorFactory factory = new PreparedStatementCreatorFactory(sql,
new int[]{Types.VARCHAR, Types.VARCHAR});
(假设列的类型为VARCHAR
)
但这还不够。当您想要为新插入的行返回生成的主键时,必须声明它:
factory.setReturnGeneratedKeys(true);
最后,如果您使用PosgreSQL,则必须使用
generatedKeyHolder.getKeys().get("id");
而不仅仅是generatedKeyHolder.getKey().intValue()
(假设包含生成密钥的列的名称为id
)