关于MyBatis中insert返回值与SQLserver触发器/存储过程返回执行结果的问题

今天刚把Mybatis配置好,正处调试阶段。

测试类写了:BorrowRecord,用于记录借书记录。Book,管理书名及库存情况。

BorrowRecord表如下:

CREATE TABLE [dbo].[BorrowRecord](
[BorrowRecordID] [int] IDENTITY(1,1) NOT NULL,
[StudentID] [int] NULL,
[BookID] [int] NULL,
[BorrowDate] [datetime] NULL,
[ReturnDate] [datetime] NULL


Book表如下:

CREATE TABLE [dbo].[Book](
[BookID] [int] IDENTITY(1,1) NOT NULL,
[BookName] [nvarchar](100) NULL,
[TotalQuantity] [int] NULL,
[RestQuantity] [int] NULL
配置完成后,单表CRUD均可以正常运行。

Mapper的insert如下:

<insert id="addBorrowRecord" parameterType="BorrowRecord"
useGeneratedKeys="true" keyProperty="borrowrecordid" >
insert into
BorrowRecord(StudentID,BookID,BorrowDate,ReturnDate)
values(#{student.studentid},#{book.bookid},#{borrowdate},#{returndate})
</insert>
突然想到可以用触发器管理Book的库存。

即:BorrowRecord中增加一行,Book表中对应的RestQuantity自减1.

触发器如下

create trigger [dbo].[triBorrowRecord]
on [dbo].[BorrowRecord]
after insert
as
begin
update Book set RestQuantity = RestQuantity - 1 from Book,inserted where Book.BookID = inserted.BookID
end
结果问题就出现了,只要一调用addBorrowRecord,就报

### Error updating database.  Cause: org.apache.ibatis.executor.ExecutorException: Error getting generated key or setting result to parameter object. 
Cause: com.microsoft.sqlserver.jdbc.SQLServerException: 必须执行该语句才能获得结果。
BUG排查:

第一反应,触发器写错了,然后就直接在SQLserver端执行insert,发现正常。

然后,怀疑Mapper的insert配置有误。drop trigger后,发现addBorrowRecord正常。

然后就开始懵逼了。

触发器没问题,Mapper配置也没问题,两边单独运行也没问题。

结论:SQLserver触发器和Mybatis的Mapper有冲突。

然后,在Mybatis的官网查找相关配置,然而并没有。

遂只能从SQLserver入手,查找触发器的相关设置,尝试诸多方法之后,找到了:

SET NOCOUNT ON
该配置用于设置SQLserver的T-SQL执行结果,相关资料可自行查找。

最终问题解决,总结原因是:

Mybatis的insert从SQLserver获取返回数据的时候,会将T-SQL的执行结果一并返回,导致Mybatis注入insert对象的ID失败。

设置SET NOCOUNT ON,相当于使SQLserver不返回T-SQL的执行结果。从而完美解决该问题。
--------------------- 
作者:Royal_Lily 
来源:CSDN 
原文:https://blog.csdn.net/weixin_41562032/article/details/78936452 
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/xiao190128/article/details/84861486