瀏覽代碼

通用Service支持多SqlSessionFactory注入.

nieqiurong 1 年之前
父節點
當前提交
3bc5fdb298

+ 4 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/override/MybatisMapperProxy.java

@@ -117,6 +117,10 @@ public class MybatisMapperProxy<T> implements InvocationHandler, Serializable {
         }
     }
 
+    public SqlSession getSqlSession() {
+        return sqlSession;
+    }
+
     private MethodHandle getMethodHandleJava9(Method method)
         throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
         final Class<?> declaringClass = method.getDeclaringClass();

+ 24 - 8
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/service/impl/ServiceImpl.java

@@ -20,6 +20,7 @@ import com.baomidou.mybatisplus.core.enums.SqlMethod;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.TableInfo;
 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
+import com.baomidou.mybatisplus.core.override.MybatisMapperProxy;
 import com.baomidou.mybatisplus.core.toolkit.*;
 import com.baomidou.mybatisplus.core.toolkit.reflect.GenericTypeUtils;
 import com.baomidou.mybatisplus.extension.service.IService;
@@ -30,6 +31,7 @@ import org.apache.ibatis.logging.LogFactory;
 import org.apache.ibatis.session.ExecutorType;
 import org.apache.ibatis.session.SqlSession;
 import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionTemplate;
 import org.mybatis.spring.SqlSessionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.convert.ConversionService;
@@ -37,6 +39,7 @@ import org.springframework.core.convert.support.DefaultConversionService;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.io.Serializable;
+import java.lang.reflect.Proxy;
 import java.util.Collection;
 import java.util.Map;
 import java.util.Objects;
@@ -61,9 +64,6 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
     @Autowired
     protected M baseMapper;
 
-    @Autowired
-    protected SqlSessionFactory sqlSessionFactory;
-
     protected final Class<?>[] typeArguments = GenericTypeUtils.resolveTypeArguments(getClass(), ServiceImpl.class);
 
     @Override
@@ -80,6 +80,22 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
 
     protected final Class<M> mapperClass = currentMapperClass();
 
+    private volatile SqlSessionFactory sqlSessionFactory;
+
+    @SuppressWarnings("rawtypes")
+    protected SqlSessionFactory getSqlSessionFactory() {
+        if (this.sqlSessionFactory == null) {
+            synchronized (this) {
+                if (this.sqlSessionFactory == null) {
+                    MybatisMapperProxy mybatisMapperProxy = (MybatisMapperProxy) Proxy.getInvocationHandler(this.baseMapper);
+                    SqlSessionTemplate sqlSessionTemplate = (SqlSessionTemplate) mybatisMapperProxy.getSqlSession();
+                    this.sqlSessionFactory = sqlSessionTemplate.getSqlSessionFactory();
+                }
+            }
+        }
+        return this.sqlSessionFactory;
+    }
+
     /**
      * 判断数据库操作是否成功
      *
@@ -108,7 +124,7 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
      */
     @Deprecated
     protected SqlSession sqlSessionBatch() {
-        return sqlSessionFactory.openSession(ExecutorType.BATCH);
+        return getSqlSessionFactory().openSession(ExecutorType.BATCH);
     }
 
     /**
@@ -119,7 +135,7 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
      */
     @Deprecated
     protected void closeSqlSession(SqlSession sqlSession) {
-        SqlSessionUtils.closeSqlSession(sqlSession, this.sqlSessionFactory);
+        SqlSessionUtils.closeSqlSession(sqlSession, getSqlSessionFactory());
     }
 
     /**
@@ -187,7 +203,7 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
         Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
         String keyProperty = tableInfo.getKeyProperty();
         Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
-        return SqlHelper.saveOrUpdateBatch(this.sqlSessionFactory, this.mapperClass, this.log, entityList, batchSize, (sqlSession, entity) -> {
+        return SqlHelper.saveOrUpdateBatch(getSqlSessionFactory(), this.mapperClass, this.log, entityList, batchSize, (sqlSession, entity) -> {
             Object idVal = tableInfo.getPropertyValue(entity, keyProperty);
             return StringUtils.checkValNull(idVal)
                 || CollectionUtils.isEmpty(sqlSession.selectList(getSqlStatement(SqlMethod.SELECT_BY_ID), entity));
@@ -238,7 +254,7 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
      */
     @Deprecated
     protected boolean executeBatch(Consumer<SqlSession> consumer) {
-        return SqlHelper.executeBatch(this.sqlSessionFactory, this.log, consumer);
+        return SqlHelper.executeBatch(getSqlSessionFactory(), this.log, consumer);
     }
 
     /**
@@ -252,7 +268,7 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
      * @since 3.3.1
      */
     protected <E> boolean executeBatch(Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) {
-        return SqlHelper.executeBatch(this.sqlSessionFactory, this.log, list, batchSize, consumer);
+        return SqlHelper.executeBatch(getSqlSessionFactory(), this.log, list, batchSize, consumer);
     }
 
     /**

+ 2 - 2
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/service/impl/H2UserServiceImpl.java

@@ -147,14 +147,14 @@ public class H2UserServiceImpl extends ServiceImpl<H2UserMapper, H2User> impleme
     @Transactional(rollbackFor = RuntimeException.class)
     public void testSaveOrUpdateTransactional1(List<H2User> users) {
         var method = new MybatisBatch.Method<H2User>(H2UserMapper.class);
-        MybatisBatchUtils.saveOrUpdate(sqlSessionFactory, users, method.insert(), (sqlSession, user) -> this.getById(user.getTestId()) == null, method.updateById());
+        MybatisBatchUtils.saveOrUpdate(getSqlSessionFactory(), users, method.insert(), (sqlSession, user) -> this.getById(user.getTestId()) == null, method.updateById());
     }
 
     @Override
     @Transactional(rollbackFor = RuntimeException.class)
     public void testSaveOrUpdateTransactional2(List<H2User> users) {
         var method = new MybatisBatch.Method<H2User>(H2UserMapper.class);
-        MybatisBatchUtils.saveOrUpdate(sqlSessionFactory, users, method.insert(), (sqlSession, user) -> sqlSession.selectList(method.get("selectById").getStatementId(), user.getTestId()).isEmpty(), method.updateById());
+        MybatisBatchUtils.saveOrUpdate(getSqlSessionFactory(), users, method.insert(), (sqlSession, user) -> sqlSession.selectList(method.get("selectById").getStatementId(), user.getTestId()).isEmpty(), method.updateById());
     }
 
 }