|
@@ -0,0 +1,145 @@
|
|
|
+/*
|
|
|
+ * Copyright 2015-2016 http://hsweb.me
|
|
|
+ *
|
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
+ * you may not use this file except in compliance with the License.
|
|
|
+ * You may obtain a copy of the License at
|
|
|
+ *
|
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
|
+ *
|
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
+ * See the License for the specific language governing permissions and
|
|
|
+ * limitations under the License.
|
|
|
+ */
|
|
|
+
|
|
|
+package org.hsweb.web.mybatis.dynamic;
|
|
|
+
|
|
|
+import org.apache.ibatis.exceptions.ExceptionFactory;
|
|
|
+import org.apache.ibatis.executor.ErrorContext;
|
|
|
+import org.apache.ibatis.executor.Executor;
|
|
|
+import org.apache.ibatis.mapping.Environment;
|
|
|
+import org.apache.ibatis.session.*;
|
|
|
+import org.apache.ibatis.session.defaults.DefaultSqlSession;
|
|
|
+import org.apache.ibatis.transaction.Transaction;
|
|
|
+import org.apache.ibatis.transaction.TransactionFactory;
|
|
|
+import org.apache.ibatis.transaction.managed.ManagedTransactionFactory;
|
|
|
+import org.hsweb.web.core.datasource.DynamicDataSourceHolder;
|
|
|
+
|
|
|
+import javax.sql.DataSource;
|
|
|
+import java.sql.Connection;
|
|
|
+import java.sql.SQLException;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author zhouhao
|
|
|
+ */
|
|
|
+public class DynamicSqlSessionFactory implements SqlSessionFactory {
|
|
|
+ private final Configuration configuration;
|
|
|
+
|
|
|
+ public DynamicSqlSessionFactory(Configuration configuration) {
|
|
|
+ this.configuration = configuration;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public SqlSession openSession() {
|
|
|
+ return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public SqlSession openSession(boolean autoCommit) {
|
|
|
+ return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public SqlSession openSession(ExecutorType execType) {
|
|
|
+ return openSessionFromDataSource(execType, null, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public SqlSession openSession(TransactionIsolationLevel level) {
|
|
|
+ return openSessionFromDataSource(configuration.getDefaultExecutorType(), level, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level) {
|
|
|
+ return openSessionFromDataSource(execType, level, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public SqlSession openSession(ExecutorType execType, boolean autoCommit) {
|
|
|
+ return openSessionFromDataSource(execType, null, autoCommit);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public SqlSession openSession(Connection connection) {
|
|
|
+ return openSessionFromConnection(configuration.getDefaultExecutorType(), connection);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public SqlSession openSession(ExecutorType execType, Connection connection) {
|
|
|
+ return openSessionFromConnection(execType, connection);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Configuration getConfiguration() {
|
|
|
+ return configuration;
|
|
|
+ }
|
|
|
+
|
|
|
+ private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
|
|
|
+ Transaction tx = null;
|
|
|
+ try {
|
|
|
+ final Environment environment = getConfiguration().getEnvironment();
|
|
|
+ final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
|
|
|
+ DataSource ds = DynamicDataSourceHolder.getActiveSource();
|
|
|
+ if (ds == null) ds = environment.getDataSource();
|
|
|
+ tx = transactionFactory.newTransaction(ds, level, autoCommit);
|
|
|
+ final Executor executor = getConfiguration().newExecutor(tx, execType);
|
|
|
+ return new DefaultSqlSession(getConfiguration(), executor, autoCommit);
|
|
|
+ } catch (Exception e) {
|
|
|
+ closeTransaction(tx); // may have fetched a connection so lets call close()
|
|
|
+ throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
|
|
|
+ } finally {
|
|
|
+ ErrorContext.instance().reset();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {
|
|
|
+ try {
|
|
|
+ boolean autoCommit;
|
|
|
+ try {
|
|
|
+ autoCommit = connection.getAutoCommit();
|
|
|
+ } catch (SQLException e) {
|
|
|
+ // Failover to true, as most poor drivers
|
|
|
+ // or databases won't support transactions
|
|
|
+ autoCommit = true;
|
|
|
+ }
|
|
|
+ final Environment environment = configuration.getEnvironment();
|
|
|
+ final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
|
|
|
+ final Transaction tx = transactionFactory.newTransaction(connection);
|
|
|
+ final Executor executor = configuration.newExecutor(tx, execType);
|
|
|
+ return new DefaultSqlSession(configuration, executor, autoCommit);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
|
|
|
+ } finally {
|
|
|
+ ErrorContext.instance().reset();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {
|
|
|
+ if (environment == null || environment.getTransactionFactory() == null) {
|
|
|
+ return new ManagedTransactionFactory();
|
|
|
+ }
|
|
|
+ return environment.getTransactionFactory();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void closeTransaction(Transaction tx) {
|
|
|
+ if (tx != null) {
|
|
|
+ try {
|
|
|
+ tx.close();
|
|
|
+ } catch (SQLException ignore) {
|
|
|
+ // Intentionally ignore. Prefer previous error.
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|