Java 插入具有自动生成id的新记录

Java 插入具有自动生成id的新记录,java,mybatis,ibatis,Java,Mybatis,Ibatis,我试图用MyBatis将一条新记录插入到一个简单的数据库表中,但遇到了一个奇怪的异常。Mybe这与我没有使用POJO有关 MyBatis版本:3.4.5 我的桌子: CREATE TABLE IF NOT EXISTS image ( id BIGINT PRIMARY KEY, content BYTEA ) WITHOUT OIDS; MyBatis制图器: @Insert("INSERT INTO image (id, content) VALUES (#{id}, #{

我试图用MyBatis将一条新记录插入到一个简单的数据库表中,但遇到了一个奇怪的异常。Mybe这与我没有使用POJO有关

MyBatis版本:3.4.5

我的桌子:

CREATE TABLE IF NOT EXISTS image
(
    id BIGINT PRIMARY KEY,
    content BYTEA
) WITHOUT OIDS;
MyBatis制图器:

@Insert("INSERT INTO image (id, content) VALUES (#{id}, #{content})")
@SelectKey(statement = "SELECT NEXTVAL('image_seq')", keyProperty = "id", before = true, resultType = long.class)
long insertImage(byte[] content);
我尝试使用它的方式:

byte[] fileContent = IOUtils.toByteArray(inputStream);
long id = imageDao.insertImage(fileContent);
我得到的例外是:

java.lang.ClassCastException: java.lang.Long cannot be cast to [B
    at org.apache.ibatis.type.ByteArrayTypeHandler.setNonNullParameter(ByteArrayTypeHandler.java:26)
    at org.apache.ibatis.type.BaseTypeHandler.setParameter(BaseTypeHandler.java:53)
    at org.apache.ibatis.scripting.defaults.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:87)
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.parameterize(PreparedStatementHandler.java:93)
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.parameterize(RoutingStatementHandler.java:64)
    at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:86)
    at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:49)
    at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
    at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:185)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
我不想用getter/setter方法为这个“content”参数创建POJO类,但我认为这个问题与缺少POJO有关

解决办法是什么

编辑

我正在尝试调试mybatis代码,我在
参数类型中找到了“
[B
”:

java.lang.Long不能强制转换为[B]

这表示您正在尝试将
long
转换为
byte[]

查看org.apache.ibatis.type.ByteArrayTypeHandler的源代码:

public void  setNonNullParameter(PreparedStatement ps, int i, byte[] parameter, JdbcType jdbcType) throws SQLException {
    ps.setBytes(i, parameter);
}
我认为您需要从insert注释中删除
{id}
(因为这个值是自动生成的)


否则,参数将移位一。

@SelectKey
在您希望在代码中进一步重用生成的值时很有用,但您似乎不会

那么为什么不将所有内容都保存在SQL中呢:

INSERT INTO image (id, content) VALUES ((SELECT NEXTVAL('image_seq')), #{content})
关于参数的例外情况,参数必须用
@Param
注释命名

int insertImage(@Param("content") byte[] content);

请注意,INSERT以及UPDATE和DELETE语句返回的int类型是插入/更新/删除的行数[…]

<强>编辑:除非你认为在引擎盖下,java 8返回长。 […]而不是像建议的那样生成的键。然后,您似乎最终想要获得键值,这意味着返回到与

@SelectKey
的平方一,并且需要一个POJO和一个生成值的目标属性。它甚至可以与生成键的批量插入一起工作

我最近发现,如果在中遵循以下说明,则可以使用实际参数名称(然后代码将按原样工作):

useActualParamName
允许按语句参数引用语句参数 方法签名中声明的实际名称。若要使用此功能, 您的项目必须使用带有-parameters选项的Java8编译。 (自:3.4.1)有效值:
true
|
false
默认值:
true


根据您的建议,我从sql中删除了id,但没有任何帮助。我遇到了一个奇怪的异常:org.apache.ibatis.binding.BindingException:找不到参数“content”。可用参数是[array,id],我删除了@SelectKey,并向方法签名添加了一个长输入参数,如下所示:long insertImage(long id,byte[]content)。但现在这是我得到的异常:org.apache.ibatis.binding.BindingException:未找到参数“id”。可用参数有[arg1、arg0、param1、param2]我知道日志中这4个参数的来源。谢谢你的回复。最后,我创建了一个带有id、注释、文件名和长度属性的POJO。将这些元数据与文件内容一起存储是有意义的。当然,POJO解决了我的问题。谢谢。
int insertImage(@Param("content") byte[] content);
int insertImage(@Param("id) Long id, @Param("content") byte[] content)