Java Spring:如何在PostgreSQL中使用KeyHolder
最近迁移到POSTGRESQL,我试图在db表中创建新条目时获取唯一生成的密钥。表格Java Spring:如何在PostgreSQL中使用KeyHolder,java,spring,postgresql,spring-jdbc,Java,Spring,Postgresql,Spring Jdbc,最近迁移到POSTGRESQL,我试图在db表中创建新条目时获取唯一生成的密钥。表格screenstable如下所示: CREATE TABLE screenstable ( id serial NOT NULL, screenshot bytea, CONSTRAINT screen_id PRIMARY KEY (id ) ) 将数据插入screenstable的方法如下: @Autowired NamedParameterJDBCTemplate template; publ
screenstable
如下所示:
CREATE TABLE screenstable
(
id serial NOT NULL,
screenshot bytea,
CONSTRAINT screen_id PRIMARY KEY (id )
)
将数据插入screenstable
的方法如下:
@Autowired NamedParameterJDBCTemplate template;
public int insertImage(ImageBean imageBean){
String query = "insert into screenstable (screenshot) values (:image)";
SqlParameterSource data = new BeanPropertySqlParameterSource(imageBean);
KeyHolder keyHolder = new GeneratedKeyHolder();
template.update(query, data, keyHolder);
return keyHolder.getKey().intValue();
}
template.update(query, data, keyHolder, new String[] { "id" });
而ImageBean
是
import java.util.Arrays;
public class ImageBean {
private int id;
private byte[] image;
@Override
public String toString() {
return "ImageBean [id=" + id + ", image=" + Arrays.toString(image)
+ "]";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public byte[] getImage() {
return image;
}
public void setImage(byte[] image) {
this.image = image;
}
}
但是运行代码会出现以下异常
15:33:20,953 ERROR JsonParseExceptionMapper:15 - org.springframework.dao.InvalidDataAccessApiUsageException: The getKey method should only be used when a single key is returned. The current key entry contains multiple keys: [{id=3, screenshot=[B@db59df}]
org.springframework.dao.InvalidDataAccessApiUsageException: The getKey method should only be used when a single key is returned. The current key entry contains multiple keys: [{id=3, screenshot=[B@db59df}]
at org.springframework.jdbc.support.GeneratedKeyHolder.getKey(GeneratedKeyHolder.java:65)
at some.project.model.FeedbackDao.insertImage(FeedbackDao.java:20)
at some.project.rest.FeedsRest.pluginCheck(FeedsRest.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597).....
同样的代码在MySQL中正常运行,但在POSTGRES中使用时,键失败。数据类型serial
是否对代码失败负有某种责任,或者我是否正确使用了主键功能
请给出建议。快速浏览一下就知道了。。。keyHolder.getKey().intValue()应该是keyHolder.getKey()[“id”].intValue()(或类似的东西)? getKey()函数返回一个具有多个键(id和image)的对象,并且您试图使用intValue()函数将该对象转换为int,我想这是不起作用的,除非您指向从“getKey()返回的对象中的“id”键 干杯
Francesco如果框架没有被告知哪个列是键,它将返回表中的所有列作为键 您可以通过向update方法传递一个新参数来通知它,如下所示:
@Autowired NamedParameterJDBCTemplate template;
public int insertImage(ImageBean imageBean){
String query = "insert into screenstable (screenshot) values (:image)";
SqlParameterSource data = new BeanPropertySqlParameterSource(imageBean);
KeyHolder keyHolder = new GeneratedKeyHolder();
template.update(query, data, keyHolder);
return keyHolder.getKey().intValue();
}
template.update(query, data, keyHolder, new String[] { "id" });
请参见您也可以继续使用JdbcTemplate,但在这种情况下,您必须检查它:
jdbcTemplate.update(this, holder);
Long newId;
if (holder.getKeys().size() > 1) {
newId = (Long)holder.getKeys().get("your_id_column");
} else {
newId= holder.getKey().longValue();
}
GeneratedKeyHolder类抛出异常,因为类只知道当有一个键时应该返回什么(并且该键需要是Number实例,因为getKey方法返回Number对象)
在jdbc驱动程序返回多个键的情况下,您必须确定生成的键列(更新之前或之后)。请看一下GeneratedKeyHolder#getKey的源代码——它非常易于分析。有对键列表大小的检查,对于超过个键,Spring不知道应该返回哪个键,这就是返回异常的原因
注意:请记住,这种方法不适用于Oracle,因为Oracle会返回类似ROWID的内容。对于Oracle,您必须使用NamedParameterJdbcTemplate。方法返回一个数字,因此我无法像地图一样访问它。请查收