-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add affectData
attribute to @Select
, @SelectProvider
and <select />
#2741
Conversation
Some DBs support INSERT, UPDATE or DELETE statement that returns result set. PostgreSQL has RETURNING MS SQL Server has OUTPUT MyBatis can return results by using @select, @SelectProvider or <select />, however, rollback does not work as expected because SELECT does not mark the session 'dirty'.
8551087
to
04d1971
Compare
To indicate the SELECT affects DB data. e.g. PostgreSQL's RETURNING, MS SQL Server's OUTPUT
04d1971
to
52fd6eb
Compare
@harawata I'm happy you are working on this issue! Your solution makes sense to me, but I wonder if it will cause too much confusion as statements will be written like this: <select ...>
UPDATE...
</select> I think users are sometimes confused about this thinking that I wonder if it would ultimately be less confusing to add resultSet support to |
Thank you, @jeffgbutler for the comment! I understand the look of INSERT / UPDATE / DELETE annotations / tags will have all sorts of attributes that [1] This is off-topic, but I might be OK with the idea of having only one annotation like I also explored possible implementation to add result set support to INSERT / UPDATE / DELETE a little bit. // This one expects update count
@Insert("insert into users (name) values (#{name})")
int insert(String name);
// This one expects result set
@Insert("insert into users (name) values (#{name}) returning id")
int insert(String name); This, I think, means that we need to introduce a new attribute or something (e.g. Regarding simultaneous use with generated keys, I did quick JDBC tests.
So, it's a mess, LOL. Batch: I didn't test it, but these statement clearly are incompatible with JDBC batch API. |
I thought about just having a single Spring JDBC template basically has four methods: Your idea is the least intrusive for sure. I'm +1 on your implementation. |
Thank you for the comment, @jeffgbutler ! |
@harawata LGTM 👍 |
For anyone that has a large codebase, here is an IntelliJ inspection that can detect and fix these issues for you, after the
<replaceConfiguration name="SELECT statements affecting data" uuid="b73cae76-4e66-330c-8a61-c7c45c7cb78e" description="This select statement is affecting data, it needs to be annotated with affectData="true"" suppressId="mybatis-affect-data" problemDescriptor="Add affectData="true" to #ref" text="<$select$ $other_attrs$ $affectData$>$text$</$select$>" recursive="false" caseInsensitive="false" type="XML" reformatAccordingToStyle="false" shortenFQN="false" replacement="<$select$ $other_attrs$ affectData="true">$text$</$select$>">
<constraint name="__context__" within="" contains="" />
<constraint name="text" regexp=".*((?<!for )\bupdate\b|\binsert\b|\bdelete\b).*" within="" contains="" />
<constraint name="affectData" regexp="affectData" minCount="0" maxCount="0" within="" contains="" />
<constraint name="other_attrs" regexp="affectData" minCount="0" maxCount="2147483647" negateName="true" within="" contains="" />
<constraint name="select" regexp="select" target="true" within="" contains="" />
</replaceConfiguration>
<component name="DependencyValidationManager">
<scope name="MyBatis XML Mappers" pattern="file:resources/mappers//*.xml" />
</component> |
Some DBs support returning result set from INSERT/UPDATE/DELETE statements. e.g.
RETURNING
OUTPUT
By using
@Select
,@SelectProvider
or<select />
, it is possible to retrieve data from those statements.The problem is that calling
SqlSession#commit()
orSqlSession#rollback()
does not work as expected because MyBatis assumes SELECT does not affect DB data [1].By setting
affectData=true
, users can indicate that the SELECT statement affects DB data.Related to:
Notes:
@Select
,@SelectProvider
,<select />
might look unintuitive, but changing the INSERT/UPDATE/DELETE behavior requires bigger change. The characteristic of these statement is closer to SELECT from MyBatis' perspective.affectData
does not automatically activateflushCache
.TODO: doc
@emacarron @jeffgbutler @mnesarco @hazendaz @kazuki43zoo @eddumelendez
Any input would be appreciated!
[1] An obvious (but not ideal) workaround is to execute another INSERT/UPDATE/DELETE in the same session.