All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jfinal.plugin.activerecord.Config Maven / Gradle / Ivy

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.jfinal.plugin.activerecord;

import com.jfinal.kit.LogKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.cache.EhCache;
import com.jfinal.plugin.activerecord.cache.ICache;
import com.jfinal.plugin.activerecord.dialect.Dialect;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.activerecord.sql.SqlKit;
import org.springframework.jdbc.datasource.ConnectionHolder;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;


/**
 * @ClassName Config
 * @Description: 基于spring事务管理改写,兼容 @Transactional 与 Db.use().tx(......) 类型事务混写
 * @Author 杨志佳
 * @Date 2020/10/13
 * @Version V1.0
 **/
public class Config {

    // 如果这里是静态的话,会导致线程公用同一个连接对象
    private final ThreadLocal threadLocal ;

    String name;
    DataSource dataSource;
    Dialect dialect;
    boolean showSql;
    boolean devMode;
    int transactionLevel;
    IContainerFactory containerFactory;
    IDbProFactory dbProFactory;
    ICache cache;
    SqlKit sqlKit;

    Config(String name, DataSource dataSource, int transactionLevel) {
        this.threadLocal = new ThreadLocal();
        this.dbProFactory = IDbProFactory.defaultDbProFactory;
        this.init(name, dataSource, new MysqlDialect(), false, false, transactionLevel, IContainerFactory.defaultContainerFactory, new EhCache());
    }

    public Config(String name, DataSource dataSource, Dialect dialect, boolean showSql, boolean devMode, int transactionLevel, IContainerFactory containerFactory, ICache cache) {
        this.threadLocal = new ThreadLocal();
        this.dbProFactory = IDbProFactory.defaultDbProFactory;
        if (dataSource == null) {
            throw new IllegalArgumentException("DataSource can not be null");
        } else {
            this.init(name, dataSource, dialect, showSql, devMode, transactionLevel, containerFactory, cache);
        }
    }

    private void init(String name, DataSource dataSource, Dialect dialect, boolean showSql, boolean devMode, int transactionLevel, IContainerFactory containerFactory, ICache cache) {
        if (StrKit.isBlank(name)) {
            throw new IllegalArgumentException("Config name can not be blank");
        } else if (dialect == null) {
            throw new IllegalArgumentException("Dialect can not be null");
        } else if (containerFactory == null) {
            throw new IllegalArgumentException("ContainerFactory can not be null");
        } else if (cache == null) {
            throw new IllegalArgumentException("Cache can not be null");
        } else {
            this.name = name.trim();
            this.dataSource = dataSource;
            this.dialect = dialect;
            this.showSql = showSql;
            this.devMode = devMode;
            this.setTransactionLevel(transactionLevel);
            this.containerFactory = containerFactory;
            this.cache = cache;
            this.sqlKit = new SqlKit(this.name, this.devMode);
        }
    }

    public Config(String name, DataSource dataSource) {
        this(name, dataSource, new MysqlDialect());
    }

    public Config(String name, DataSource dataSource, Dialect dialect) {
        this(name, dataSource, dialect, false, false, 4, IContainerFactory.defaultContainerFactory, new EhCache());
    }

    private Config() {
        this.threadLocal = new ThreadLocal();
        this.dbProFactory = IDbProFactory.defaultDbProFactory;
    }

    void setDevMode(boolean devMode) {
        this.devMode = devMode;
        this.sqlKit.setDevMode(devMode);
    }

    void setTransactionLevel(int transactionLevel) {
        if (transactionLevel != 0 && transactionLevel != 1 && transactionLevel != 2 && transactionLevel != 4 && transactionLevel != 8) {
            throw new IllegalArgumentException("The transactionLevel only be 0, 1, 2, 4, 8");
        } else {
            this.transactionLevel = transactionLevel;
        }
    }

    static Config createBrokenConfig() {
        Config ret = new Config();
        ret.dialect = new MysqlDialect();
        ret.showSql = false;
        ret.devMode = false;
        ret.transactionLevel = 4;
        ret.containerFactory = IContainerFactory.defaultContainerFactory;
        ret.cache = new EhCache();
        return ret;
    }

    public String getName() {
        return this.name;
    }

    public SqlKit getSqlKit() {
        return this.sqlKit;
    }

    public Dialect getDialect() {
        return this.dialect;
    }

    public ICache getCache() {
        return this.cache;
    }

    public int getTransactionLevel() {
        return this.transactionLevel;
    }

    public DataSource getDataSource() {
        return this.dataSource;
    }

    public IContainerFactory getContainerFactory() {
        return this.containerFactory;
    }

    public IDbProFactory getDbProFactory() {
        return this.dbProFactory;
    }

    public boolean isShowSql() {
        return this.showSql;
    }

    public boolean isDevMode() {
        return this.devMode;
    }

    /**
     * 设置当前线程连接
     * @param connection
     */
    public void setThreadLocalConnection(Connection connection) {
        this.threadLocal.set(connection);
        //System.out.println("当前线程2-1:"+Thread.currentThread().getId()+ "对象:" + this.threadLocal.get());
    }

    /**
     * 移除当前线程连接
     */
    public void removeThreadLocalConnection() {
        //System.out.println("当前线程2-3:"+Thread.currentThread().getId() + "准备释放对象:" + this.threadLocal.get());
        // 移除事务层
        this.threadLocal.remove();
    }


    /**
     * 获取连接
     * @return
     * @throws SQLException
     */
    public Connection getConnection() throws SQLException {
        //System.out.println("当前线程2-2:"+Thread.currentThread().getId() + "对象:" + this.threadLocal.get());
        Connection conn = null;
        ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);

        // 不是spring的事务管理,则走原来的逻辑
        if(conHolder == null ){
            conn = (Connection)this.threadLocal.get();
            if (conn != null) {
                return conn;
            } else {
                return this.showSql ? (new SqlReporter(this.dataSource.getConnection())).getConnection() : this.dataSource.getConnection();
            }
        }else{
            //
            conn = (Connection)this.threadLocal.get();
            if (conn != null) {
                return conn;
            } else {
                // 通过spring获取连接对象
                conn = DataSourceUtils.getConnection(this.getDataSource());
            }

        }
        return  conn;
    }




    /**
     * 获取当前连接 -- 如果已经有事务的话,这里是会有对象的
     * @return
     */
    public Connection getThreadLocalConnection() {
        Connection connection =  threadLocal.get();
        if(connection != null){
            return connection;
        }
        // 如果是spring事务,则返回spring的事务对象,否则直接取 jfinal 当前线程的事务对象
        ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
        if(conHolder == null){
            return threadLocal.get();
        }else{
            // 获取spring的事务对象
            return DataSourceUtils.getConnection(this.getDataSource());
        }
    }

    /**
     * 是否在事务中
     * @return
     */
    public boolean isInTransaction() {
        ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
        // 不是spring的事务管理,则走原来的逻辑
        if(conHolder == null){
            return threadLocal.get() != null;
        }
        return conHolder != null && (conHolder.getConnectionHandle()!=null || conHolder.isSynchronizedWithTransaction());
    }

    public void close(ResultSet rs, Statement st, Connection conn) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException var7) {
                LogKit.error(var7.getMessage(), var7);
            }
        }

        if (st != null) {
            try {
                st.close();
            } catch (SQLException var6) {
                LogKit.error(var6.getMessage(), var6);
            }
        }

        // 关闭连接
        close(conn);
    }

    public void close(Statement st, Connection conn) {
        if (st != null) {
            try {
                st.close();
            } catch (SQLException var5) {
                LogKit.error(var5.getMessage(), var5);
            }
        }
        // 关闭连接
        close(conn);
    }

    /**
     * 改造关闭对象
     * @param conn
     */
    public void close(Connection conn) {
        // 是否在事务中
        ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
        // spring事务则走这个方法 && !conHolder.isSynchronizedWithTransaction()
        if (conHolder != null ) {
            // 直接交给spring来关闭 -- 是否释放,在spring里会有判断
            DataSourceUtils.releaseConnection(conn, dataSource);
        }else{
            // 原 jfinal 事务走法
            if (threadLocal.get() == null){
                // 连接
                if (conn != null)
                {
                    try {
                        //conn.close();
                        DataSourceUtils.releaseConnection(conn, dataSource);
                    } catch (Throwable e) {
                        e.printStackTrace();
                    }
                }
            }
        }


    }



}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy