Pārlūkot izejas kodu

fix https://github.com/baomidou/mybatis-plus/issues/373 去除全局sqlSession缓存,修改sqlSession获取方式.

聂秋秋 6 gadi atpakaļ
vecāks
revīzija
cdf0744fb1

+ 85 - 15
mybatis-plus-support/src/main/java/com/baomidou/mybatisplus/activerecord/Model.java

@@ -20,7 +20,9 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import com.baomidou.mybatisplus.toolkit.GlobalConfigUtils;
 import org.apache.ibatis.session.SqlSession;
+import org.mybatis.spring.SqlSessionUtils;
 import org.springframework.transaction.annotation.Transactional;
 
 import com.baomidou.mybatisplus.enums.SqlMethod;
@@ -53,7 +55,12 @@ public abstract class Model<T extends Model> implements Serializable {
      */
     @Transactional
     public boolean insert() {
-        return SqlHelper.retBool(sqlSession().insert(sqlStatement(SqlMethod.INSERT_ONE), this));
+        SqlSession sqlSession = sqlSession();
+        try {
+            return SqlHelper.retBool(sqlSession.insert(sqlStatement(SqlMethod.INSERT_ONE), this));
+        }finally {
+            closeSqlSession(sqlSession);
+        }
     }
 
     /**
@@ -63,7 +70,12 @@ public abstract class Model<T extends Model> implements Serializable {
      */
     @Transactional
     public boolean insertAllColumn() {
-        return SqlHelper.retBool(sqlSession().insert(sqlStatement(SqlMethod.INSERT_ONE_ALL_COLUMN), this));
+        SqlSession sqlSession = sqlSession();
+        try {
+            return SqlHelper.retBool(sqlSession.insert(sqlStatement(SqlMethod.INSERT_ONE_ALL_COLUMN), this));
+        }finally {
+            closeSqlSession(sqlSession);
+        }
     }
 
     /**
@@ -94,7 +106,12 @@ public abstract class Model<T extends Model> implements Serializable {
      */
     @Transactional
     public boolean deleteById(Serializable id) {
-        return SqlHelper.delBool(sqlSession().delete(sqlStatement(SqlMethod.DELETE_BY_ID), id));
+        SqlSession sqlSession = sqlSession();
+        try {
+            return SqlHelper.delBool(sqlSession.delete(sqlStatement(SqlMethod.DELETE_BY_ID), id));
+        }finally {
+            closeSqlSession(sqlSession);
+        }
     }
 
     /**
@@ -138,7 +155,12 @@ public abstract class Model<T extends Model> implements Serializable {
     public boolean delete(Wrapper wrapper) {
         Map<String, Object> map = new HashMap<>();
         map.put("ew", wrapper);
-        return SqlHelper.delBool(sqlSession().delete(sqlStatement(SqlMethod.DELETE), map));
+        SqlSession sqlSession = sqlSession();
+        try {
+            return SqlHelper.delBool(sqlSession.delete(sqlStatement(SqlMethod.DELETE), map));
+        }finally {
+            closeSqlSession(sqlSession);
+        }
     }
 
     /**
@@ -154,7 +176,12 @@ public abstract class Model<T extends Model> implements Serializable {
         // updateById
         Map<String, Object> map = new HashMap<>();
         map.put("et", this);
-        return SqlHelper.retBool(sqlSession().update(sqlStatement(SqlMethod.UPDATE_BY_ID), map));
+        SqlSession sqlSession = sqlSession();
+        try {
+            return SqlHelper.retBool(sqlSession.update(sqlStatement(SqlMethod.UPDATE_BY_ID), map));
+        }finally {
+            closeSqlSession(sqlSession);
+        }
     }
 
     /**
@@ -170,7 +197,12 @@ public abstract class Model<T extends Model> implements Serializable {
         // updateAllColumnById
         Map<String, Object> map = new HashMap<>();
         map.put("et", this);
-        return SqlHelper.retBool(sqlSession().update(sqlStatement(SqlMethod.UPDATE_ALL_COLUMN_BY_ID), map));
+        SqlSession sqlSession = sqlSession();
+        try {
+            return SqlHelper.retBool(sqlSession.update(sqlStatement(SqlMethod.UPDATE_ALL_COLUMN_BY_ID), map));
+        }finally {
+            closeSqlSession(sqlSession);
+        }
     }
 
     /**
@@ -202,7 +234,12 @@ public abstract class Model<T extends Model> implements Serializable {
         map.put("et", this);
         map.put("ew", wrapper);
         // update
-        return SqlHelper.retBool(sqlSession().update(sqlStatement(SqlMethod.UPDATE), map));
+        SqlSession sqlSession = sqlSession();
+        try {
+            return SqlHelper.retBool(sqlSession.update(sqlStatement(SqlMethod.UPDATE), map));
+        }finally {
+            closeSqlSession(sqlSession);
+        }
     }
 
     /**
@@ -213,7 +250,13 @@ public abstract class Model<T extends Model> implements Serializable {
      * @return
      */
     public List<T> selectAll() {
-        return sqlSession().selectList(sqlStatement(SqlMethod.SELECT_LIST));
+        SqlSession sqlSession = sqlSession();
+        try {
+            return sqlSession.selectList(sqlStatement(SqlMethod.SELECT_LIST));
+        }finally {
+            closeSqlSession(sqlSession);
+        }
+        
     }
 
     /**
@@ -225,7 +268,12 @@ public abstract class Model<T extends Model> implements Serializable {
      * @return
      */
     public T selectById(Serializable id) {
-        return sqlSession().selectOne(sqlStatement(SqlMethod.SELECT_BY_ID), id);
+        SqlSession sqlSession = sqlSession();
+        try {
+            return sqlSession.selectOne(sqlStatement(SqlMethod.SELECT_BY_ID), id);
+        }finally {
+            closeSqlSession(sqlSession);
+        }
     }
 
     /**
@@ -254,7 +302,12 @@ public abstract class Model<T extends Model> implements Serializable {
     public List<T> selectList(Wrapper wrapper) {
         Map<String, Object> map = new HashMap<>();
         map.put("ew", wrapper);
-        return sqlSession().selectList(sqlStatement(SqlMethod.SELECT_LIST), map);
+        SqlSession sqlSession = sqlSession();
+        try {
+            return sqlSession.selectList(sqlStatement(SqlMethod.SELECT_LIST), map);
+        }finally {
+            closeSqlSession(sqlSession);
+        }
     }
 
     /**
@@ -308,9 +361,14 @@ public abstract class Model<T extends Model> implements Serializable {
         Map<String, Object> map = new HashMap<>();
         wrapper = (Wrapper<T>) SqlHelper.fillWrapper(page, wrapper);
         map.put("ew", wrapper);
-        List<T> tl = sqlSession().selectList(sqlStatement(SqlMethod.SELECT_PAGE), map, page);
-        page.setRecords(tl);
-        return page;
+        SqlSession sqlSession = sqlSession();
+        try {
+            List<T> tl = sqlSession.selectList(sqlStatement(SqlMethod.SELECT_PAGE), map, page);
+            page.setRecords(tl);
+            return page;
+        }finally {
+            closeSqlSession(sqlSession);
+        }
     }
 
     /**
@@ -352,7 +410,12 @@ public abstract class Model<T extends Model> implements Serializable {
     public int selectCount(Wrapper wrapper) {
         Map<String, Object> map = new HashMap<>();
         map.put("ew", wrapper);
-        return SqlHelper.retCount(sqlSession().<Integer>selectOne(sqlStatement(SqlMethod.SELECT_COUNT), map));
+        SqlSession sqlSession = sqlSession();
+        try {
+            return SqlHelper.retCount(sqlSession.<Integer>selectOne(sqlStatement(SqlMethod.SELECT_COUNT), map));
+        }finally {
+            closeSqlSession(sqlSession);
+        }
     }
 
     /**
@@ -397,5 +460,12 @@ public abstract class Model<T extends Model> implements Serializable {
      * 主键值
      */
     protected abstract Serializable pkVal();
-
+    
+    /**
+     * 释放sqlSession
+     * @param sqlSession session
+     */
+    protected void closeSqlSession(SqlSession sqlSession){
+        SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(getClass()));
+    }
 }

+ 0 - 11
mybatis-plus-support/src/main/java/com/baomidou/mybatisplus/entity/GlobalConfiguration.java

@@ -19,10 +19,8 @@ import java.io.Serializable;
 import java.util.Set;
 import java.util.concurrent.ConcurrentSkipListSet;
 
-import org.apache.ibatis.session.SqlSession;
 import org.apache.ibatis.session.SqlSessionFactory;
 
-import com.baomidou.mybatisplus.MybatisSqlSessionTemplate;
 import com.baomidou.mybatisplus.enums.DBType;
 import com.baomidou.mybatisplus.enums.FieldStrategy;
 import com.baomidou.mybatisplus.enums.IdType;
@@ -104,10 +102,6 @@ public class GlobalConfiguration implements Serializable {
      * 缓存已注入CRUD的Mapper信息
      */
     private Set<String> mapperRegistryCache = new ConcurrentSkipListSet<>();
-    /**
-     * 单例重用SqlSession
-     */
-    private SqlSession sqlSession;
     /**
      * 缓存 Sql 解析初始化
      */
@@ -228,7 +222,6 @@ public class GlobalConfiguration implements Serializable {
 
     public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
         this.sqlSessionFactory = sqlSessionFactory;
-        this.sqlSession = new MybatisSqlSessionTemplate(sqlSessionFactory);
     }
 
     public boolean isCapitalMode() {
@@ -264,10 +257,6 @@ public class GlobalConfiguration implements Serializable {
         }
     }
     
-    public SqlSession getSqlSession() {
-        return sqlSession;
-    }
-    
     public boolean isSqlParserCache() {
         return sqlParserCache;
     }

+ 3 - 7
mybatis-plus-support/src/main/java/com/baomidou/mybatisplus/mapper/SqlHelper.java

@@ -17,10 +17,8 @@ package com.baomidou.mybatisplus.mapper;
 
 import java.util.List;
 
-import com.baomidou.mybatisplus.MybatisSqlSessionTemplate;
 import org.apache.ibatis.logging.Log;
 import org.apache.ibatis.logging.LogFactory;
-import org.apache.ibatis.session.Configuration;
 import org.apache.ibatis.session.ExecutorType;
 import org.apache.ibatis.session.SqlSession;
 import org.apache.ibatis.session.SqlSessionFactory;
@@ -32,6 +30,7 @@ import com.baomidou.mybatisplus.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.toolkit.GlobalConfigUtils;
 import com.baomidou.mybatisplus.toolkit.MapUtils;
 import com.baomidou.mybatisplus.toolkit.TableInfoHelper;
+import org.mybatis.spring.SqlSessionUtils;
 
 /**
  * <p>
@@ -54,7 +53,7 @@ public class SqlHelper {
      * @return SqlSession
      */
     public static SqlSession sqlSessionBatch(Class<?> clazz) {
-        return GlobalConfigUtils.currentSessionFactory(clazz).openSession(ExecutorType.BATCH);
+        return SqlSessionUtils.getSqlSession(GlobalConfigUtils.currentSessionFactory(clazz),ExecutorType.BATCH,null);
     }
     
     /**
@@ -67,10 +66,7 @@ public class SqlHelper {
      */
     private static SqlSession getSqlSession(Class<?> clazz) {
         SqlSessionFactory sqlSessionFactory = GlobalConfigUtils.currentSessionFactory(clazz);
-        Configuration configuration = sqlSessionFactory.getConfiguration();
-        SqlSession sqlSession = GlobalConfigUtils.getGlobalConfig(configuration).getSqlSession();
-        //感觉也不可能为空了,后面那个做保险把.
-        return sqlSession !=null ? sqlSession : new MybatisSqlSessionTemplate(sqlSessionFactory);
+        return SqlSessionUtils.getSqlSession(sqlSessionFactory);
     }
 
     /**

+ 59 - 13
mybatis-plus-support/src/main/java/com/baomidou/mybatisplus/mapper/SqlRunner.java

@@ -19,9 +19,10 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import com.baomidou.mybatisplus.MybatisSqlSessionTemplate;
+import com.baomidou.mybatisplus.toolkit.GlobalConfigUtils;
 import org.apache.ibatis.session.SqlSession;
 import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionUtils;
 import org.springframework.transaction.annotation.Transactional;
 
 import com.baomidou.mybatisplus.plugins.Page;
@@ -50,7 +51,6 @@ public class SqlRunner {
     // 默认FACTORY
     public static SqlSessionFactory FACTORY;
     private SqlSessionFactory sqlSessionFactory;
-    private SqlSession sqlSession;
 
     private Class<?> clazz;
 
@@ -91,12 +91,22 @@ public class SqlRunner {
 
     @Transactional
     public boolean insert(String sql, Object... args) {
-        return SqlHelper.retBool(sqlSession().insert(INSERT, sqlMap(sql, args)));
+        SqlSession sqlSession = sqlSession();
+        try {
+            return SqlHelper.retBool(sqlSession.insert(INSERT, sqlMap(sql, args)));
+        }finally {
+            closeSqlSession(sqlSession);
+        }
     }
 
     @Transactional
     public boolean delete(String sql, Object... args) {
-        return SqlHelper.retBool(sqlSession().delete(DELETE, sqlMap(sql, args)));
+        SqlSession sqlSession = sqlSession();
+        try {
+            return SqlHelper.retBool(sqlSession.delete(DELETE, sqlMap(sql, args)));
+        }finally {
+            closeSqlSession(sqlSession);
+        }
     }
 
     /**
@@ -114,7 +124,12 @@ public class SqlRunner {
 
     @Transactional
     public boolean update(String sql, Object... args) {
-        return SqlHelper.retBool(sqlSession().update(UPDATE, sqlMap(sql, args)));
+        SqlSession sqlSession = sqlSession();
+        try {
+            return SqlHelper.retBool(sqlSession.update(UPDATE, sqlMap(sql, args)));
+        }finally {
+            closeSqlSession(sqlSession);
+        }
     }
 
     /**
@@ -126,7 +141,12 @@ public class SqlRunner {
      * @return
      */
     public List<Map<String, Object>> selectList(String sql, Object... args) {
-        return sqlSession().selectList(SELECT_LIST, sqlMap(sql, args));
+        SqlSession sqlSession = sqlSession();
+        try {
+            return sqlSession.selectList(SELECT_LIST, sqlMap(sql, args));
+        }finally {
+            closeSqlSession(sqlSession);
+        }
     }
 
     /**
@@ -138,7 +158,12 @@ public class SqlRunner {
      * @return
      */
     public List<Object> selectObjs(String sql, Object... args) {
-        return sqlSession().selectList(SELECT_OBJS, sqlMap(sql, args));
+        SqlSession sqlSession = sqlSession();
+        try {
+            return sqlSession.selectList(SELECT_OBJS, sqlMap(sql, args));
+        }finally {
+            closeSqlSession(sqlSession);
+        }
     }
 
     /**
@@ -154,7 +179,12 @@ public class SqlRunner {
     }
 
     public int selectCount(String sql, Object... args) {
-        return SqlHelper.retCount(sqlSession().<Integer>selectOne(COUNT, sqlMap(sql, args)));
+        SqlSession sqlSession = sqlSession();
+        try {
+            return SqlHelper.retCount(sqlSession.<Integer>selectOne(COUNT, sqlMap(sql, args)));
+        }finally {
+            closeSqlSession(sqlSession);
+        }
     }
 
     public Map<String, Object> selectOne(String sql, Object... args) {
@@ -166,20 +196,36 @@ public class SqlRunner {
         if (null == page) {
             return null;
         }
-        page.setRecords(sqlSession().selectList(SELECT_LIST, sqlMap(sql, args), page));
+        SqlSession sqlSession = sqlSession();
+        try {
+            page.setRecords(sqlSession.selectList(SELECT_LIST, sqlMap(sql, args), page));
+        }finally {
+            closeSqlSession(sqlSession);
+        }
         return page;
     }
-
+    
     /**
      * <p>
      * 获取Session 默认自动提交
      * <p/>
      */
     private SqlSession sqlSession() {
-        if(sqlSession == null){
-            this.sqlSession = new MybatisSqlSessionTemplate(FACTORY);
+        return (clazz != null) ? SqlSessionUtils.getSqlSession(GlobalConfigUtils.currentSessionFactory(clazz)) : SqlSessionUtils.getSqlSession(sqlSessionFactory);
+    }
+    
+    /**
+     * 释放sqlSession
+     * @param sqlSession session
+     */
+    private void closeSqlSession(SqlSession sqlSession){
+        SqlSessionFactory sqlSessionFactory;
+        if(clazz!=null){
+            sqlSessionFactory = GlobalConfigUtils.currentSessionFactory(clazz);
+        }else {
+            sqlSessionFactory = DEFAULT.sqlSessionFactory;
         }
-        return (clazz != null) ? SqlHelper.sqlSession(clazz):sqlSession;
+        SqlSessionUtils.closeSqlSession(sqlSession,sqlSessionFactory);
     }
 
 }

+ 23 - 4
mybatis-plus-support/src/main/java/com/baomidou/mybatisplus/service/impl/ServiceImpl.java

@@ -20,8 +20,10 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
+import com.baomidou.mybatisplus.toolkit.GlobalConfigUtils;
 import org.apache.ibatis.binding.MapperMethod;
 import org.apache.ibatis.session.SqlSession;
+import org.mybatis.spring.SqlSessionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -81,7 +83,15 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
     protected SqlSession sqlSessionBatch() {
         return SqlHelper.sqlSessionBatch(currentModelClass());
     }
-
+    
+    /**
+     * 释放sqlSession
+     * @param sqlSession session
+     */
+    protected void closeSqlSession(SqlSession sqlSession){
+        SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(currentModelClass()));
+    }
+    
     /**
      * 获取SqlStatement
      *
@@ -123,7 +133,8 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
         if (CollectionUtils.isEmpty(entityList)) {
             throw new IllegalArgumentException("Error: entityList must not be empty");
         }
-        try (SqlSession batchSqlSession = sqlSessionBatch()) {
+        SqlSession batchSqlSession = sqlSessionBatch();
+        try {
             int size = entityList.size();
             String sqlStatement = sqlStatement(SqlMethod.INSERT_ONE);
             for (int i = 0; i < size; i++) {
@@ -135,6 +146,8 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
             batchSqlSession.flushStatements();
         } catch (Throwable e) {
             throw new MybatisPlusException("Error: Cannot execute insertBatch Method. Cause", e);
+        } finally {
+            closeSqlSession(batchSqlSession);
         }
         return true;
     }
@@ -229,7 +242,8 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
         if (CollectionUtils.isEmpty(entityList)) {
             throw new IllegalArgumentException("Error: entityList must not be empty");
         }
-        try (SqlSession batchSqlSession = sqlSessionBatch()) {
+        SqlSession batchSqlSession = sqlSessionBatch();
+        try {
             int size = entityList.size();
             for (int i = 0; i < size; i++) {
                 if (selective) {
@@ -244,6 +258,8 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
             batchSqlSession.flushStatements();
         } catch (Throwable e) {
             throw new MybatisPlusException("Error: Cannot execute insertOrUpdateBatch Method. Cause", e);
+        }finally {
+            closeSqlSession(batchSqlSession);
         }
         return true;
     }
@@ -335,7 +351,8 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
         if (CollectionUtils.isEmpty(entityList)) {
             throw new IllegalArgumentException("Error: entityList must not be empty");
         }
-        try (SqlSession batchSqlSession = sqlSessionBatch()) {
+        SqlSession batchSqlSession = sqlSessionBatch();
+        try {
             int size = entityList.size();
             SqlMethod sqlMethod = selective ? SqlMethod.UPDATE_BY_ID : SqlMethod.UPDATE_ALL_COLUMN_BY_ID;
             String sqlStatement = sqlStatement(sqlMethod);
@@ -350,6 +367,8 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
             batchSqlSession.flushStatements();
         } catch (Throwable e) {
             throw new MybatisPlusException("Error: Cannot execute updateBatchById Method. Cause", e);
+        }finally {
+            closeSqlSession(batchSqlSession);
         }
         return true;
     }