MyBatis实现SaveOrUpdate

MyBatis实现SaveOrUpdate

这篇文章主要讲如何通过xml方式实现SaveOrUpdate,但是仍然建议在Service中实现。

例子

<code class="language-xml hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">insert</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"saveOrUpdate"</span> ></span>
  <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">selectKey</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">keyProperty</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"count"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">resultType</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"int"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">order</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"BEFORE"</span>></span>
    select count(*) from country where id = #{id}
  <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">selectKey</span>></span>
  <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">if</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">test</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"count > 0"</span>></span>
    update country 
    set countryname = #{countryname},countrycode = #{countrycode} 
    where id = #{id}
  <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">if</span>></span>
  <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">if</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">test</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"count==0"</span>></span>
    insert into country values(#{id},#{countryname},#{countrycode})
  <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">if</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">insert</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

条件限制

根据不同的判断逻辑,会有所不同,就上面这个例子而言,就要求实体类中包含count属性(可以是别的名字)。否则selectKey的结果没法保存,如果入参是个Map类型,就没有这个限制。

说明

从例子来看除了有个限制外,也没别的麻烦。

通过selectKey做第一次查询,然后根据结果进行判断,所以这里的order="BEFORE"是必须的。

也是因为BEFORE,所以没法通过<bind>标签来临时存储中间的值,只能在入参中增加属性来存放。

测试代码

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//数据库中已经存在该ID,但是countryname=China</span>
Country country = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Country();
country.setId(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">35</span>);
country.setCountryname(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"中国"</span>);
country.setCountrycode(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"CN"</span>);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//由于存在,这里会update</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> result = countryMapper.saveOrUpdate(country);

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//查询结果,判断是否已经改变</span>
Country c2 = countryMapper.selectById(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">35</span>);
assertEquals(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"中国"</span>,c2.getCountryname());

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//id=300的不存在</span>
c2 = countryMapper.selectById(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">300</span>);
assertNull(c2);

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//将id=300</span>
country.setId(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">300</span>);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//由于id=300不存在,这里会Insert</span>
result = countryMapper.saveOrUpdate(country);

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//查询结果</span>
c2 = countryMapper.selectById(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">300</span>);
assertNotNull(c2);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li></ul>

输出日志

<code class="hljs vbnet has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">DEBUG ==>  Preparing: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">select</span> count(*) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> country <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">where</span> id = ? 
DEBUG ==> Parameters: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">35</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Integer</span>)
TRACE <==    Columns: C1
TRACE <==        Row: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
DEBUG <==      Total: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
DEBUG ==>  Preparing: update country <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">set</span> countryname = ?,countrycode = ? <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">where</span> id = ? 
DEBUG ==> Parameters: 中国(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>), CN(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>), <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">35</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Integer</span>)
DEBUG <==    Updates: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
DEBUG ==>  Preparing: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">select</span> * <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> country <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">where</span> id = ? 
DEBUG ==> Parameters: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">35</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Integer</span>)
TRACE <==    Columns: ID, COUNTRYNAME, COUNTRYCODE
TRACE <==        Row: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">35</span>, 中国, CN
DEBUG <==      Total: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
DEBUG ==>  Preparing: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">select</span> * <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> country <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">where</span> id = ? 
DEBUG ==> Parameters: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">300</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Integer</span>)
DEBUG <==      Total: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>
DEBUG ==>  Preparing: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">select</span> count(*) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> country <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">where</span> id = ? 
DEBUG ==> Parameters: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">300</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Integer</span>)
TRACE <==    Columns: C1
TRACE <==        Row: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>
DEBUG <==      Total: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
DEBUG ==>  Preparing: insert <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">into</span> country values(?,?,?) 
DEBUG ==> Parameters: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">300</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Integer</span>), 中国(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>), CN(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>)
DEBUG <==    Updates: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
DEBUG ==>  Preparing: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">select</span> * <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> country <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">where</span> id = ? 
DEBUG ==> Parameters: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">300</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Integer</span>)
TRACE <==    Columns: ID, COUNTRYNAME, COUNTRYCODE
TRACE <==        Row: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">300</span>, 中国, CN
DEBUG <==      Total: <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li></ul>

最后

这种方式只是利用了selectKey会多执行一次查询来实现的,但是如果你同时还需要通过selectKey获取序列或者自增的id,就会麻烦很多(oracle麻烦,其他支持自增的还是很容易)。

建议在复杂情况下,还是选择在Service中实现更好。

MyBatis工具:www.mybatis.tk

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值