问题
mybatis有如下代码获取序列作为主键
idmapper.java
@select("select table.nextval from dual") string getid();
同一事务循环调用查询伪代码
@transactional(rollbackfor = exception.class) public querymedicalfeeres querymedicalfee(querymedicalfeereq req) { for (obj o : objs) { long id = idmapper.getid(); log.info("id{}",id); } }
输出如下:id都是1
id1
id1
id1
id1
原因
因为mybatis的一级缓存导致的。而且mybatis默认开启一级缓存,这样就会导致循环调用查询方法的时候,直接从缓存获取,不会查询数据库,从而获取到的数据都是缓存数据。
但请注意,并不是所有查询都不使用一级缓存!而是当你需要查询的内容是需要变化的时候才要禁用一级缓存。如:查询oracle的序列、查询存储过程获取主键值等情况才需要禁用一级缓存。
解决办法
禁用一级缓存
<select id="getid" resulttype="java.lang.long" usecache="false" flushcache="true"> select table.nextval as id from dual </select>
@select("select table.nextval from dual") @options(usecache = false, flushcache = options.flushcachepolicy.true) string getid();
如果是存储过程
<select id="getid" resulttype="java.lang.long" statementtype="callable" usecache="false" flushcache="true"> {call get_next_id(#{identity,mode=in,jdbctype=varchar},#{tablename,mode=in,jdbctype=varchar},#{count,mode=in,jdbctype=integer},#{currentno,mode=out,jdbctype=integer})} </select>
```java @select("{call get_next_id(#{identity,mode=in,jdbctype=varchar},#{tablename,mode=in,jdbctype=varchar},#{count,mode=in,jdbctype=integer},#{currentno,mode=out,jdbctype=integer})}") @options(statementtype = statementtype.callable, usecache = false, flushcache = options.flushcachepolicy.true) string getid();
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论