mybatis 操作数据库的 单例模式实现

阅读前,希望您已经有以下基础:

1、单例模式(枚举实现、静态内部类实现)

2、Mybatis基础知识

3、ThreadLocal原理及作用

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.Logger;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
import java.util.ResourceBundle;


/**
 * mybatis获取数据库操作的简单单例模式
 * 
 * @author zhengchao1991
 *
 */
public class MybatisSqlSessionUtil {
    private static Logger LOGGER = Logger.getLogger(MybatisSqlSessionUtil.class);

    public static final int DEFAULT_DB_LOGIN_TIMEOUT_SEC = 3;

    private static final String JDBC_CONFIG = "jdbc";//默认jdbc配置文件名
    private static final String MYBATIS_CONFIG = "mybatis-config.xml";//mybatis配置文件名
    private static int DB_LOGIN_TIMEOUT_SEC = DEFAULT_DB_LOGIN_TIMEOUT_SEC;
    private static String KEY_PLUGIN_DB_URL = "PluginDBURL";
    private static String KEY_PLUGIN_DB_USER = "PluginDBUser";
    private static String KEY_PLUGIN_DB_PWD = "PluginDBPWD";

    private static ThreadLocal<SqlSession> sqlSessionThreadLocal = new ThreadLocal<>();

    public <T> T getMapper(Class<T> type) {
        SqlSession sqlSession = openSqlSession(false);
        if (sqlSession == null) {
            return null;
        }
        return sqlSession.getMapper(type);
    }

    public static SqlSession openSqlSession(boolean autoCommit) {
        SqlSession sqlSession = sqlSessionThreadLocal.get();
        if (sqlSession == null) {
            SqlSessionFactory sqlSessionFactory = MybatisSqlSessionFactorySingleton.INSTANCE.getSqlSessionFactory();
            if (sqlSessionFactory == null) {
                return null;
            }
            sqlSession = sqlSessionFactory.openSession(autoCommit);
            boolean isConnected = testGetConnection(sqlSession);
            if (!isConnected) {
                return null;
            }
            sqlSessionThreadLocal.set(sqlSession);
        }
        return sqlSession;
    }

    public static SqlSession openSqlSession(boolean autoCommit, int dbLoginTimeoutSec) {
        DB_LOGIN_TIMEOUT_SEC = dbLoginTimeoutSec;
        return openSqlSession(autoCommit);
    }

    private static boolean testGetConnection(SqlSession sqlSession) {
        Connection connection = null;
        try {
            // 后面的代码中再getConnection会取到同一个connection对象, 所以不需要关闭, 也不会影响性能
            connection = sqlSession.getConnection();
            if (connection != null) {
                return true;
            }
        } catch (Exception e) {
            LOGGER.error("test sql error", e);
        }
        return false;
    }

    public static void closeSqlSession() {
        SqlSession sqlSession = sqlSessionThreadLocal.get();
        if (sqlSession != null) {
            sqlSession.close();
            sqlSessionThreadLocal.remove();
        }
    }

    private enum MybatisSqlSessionFactorySingleton {
        INSTANCE();

        private SqlSessionFactory sqlSessionFactory;

        MybatisSqlSessionFactorySingleton() {
            try {
                ResourceBundle bundle = ResourceBundle.getBundle(JDBC_CONFIG);
                String driverName = bundle.getString("driver").trim();
                
                /**
                 * System.getProperty(String key, String def)
                 * parameters:
				 * 		key the name of the system property.
				 * 		def a default value.
				 * 		Returns:
				 * 		the string value of the system property, or the default value if there is no property with that key.
                 */
                String url = System.getProperty(KEY_PLUGIN_DB_URL, bundle.getString("url")).trim();
                String userName = System.getProperty(KEY_PLUGIN_DB_USER, bundle.getString("username")).trim();
                String password = System.getProperty(KEY_PLUGIN_DB_PWD, bundle.getString("password")).trim();
                Properties properties = new Properties();
                properties.setProperty("driver", driverName);
                properties.setProperty("url", url);
                properties.setProperty("username", userName);
                properties.setProperty("password", password);
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader(MYBATIS_CONFIG), properties);

                /**
                 *  数据库连接超时时间默认值
                 */
                if (DriverManager.getLoginTimeout() <= 0) {
                    DriverManager.setLoginTimeout(DB_LOGIN_TIMEOUT_SEC);
                }
            } catch (Exception e) {
                LOGGER.error("init SqlSessionFactory error", e);
            }
        }

        public SqlSessionFactory getSqlSessionFactory() {
            return sqlSessionFactory;
        }
    }

    private static class MybatisSqlSessionHelperHolder {
        private static final MybatisSqlSessionUtil INSTANCE = new MybatisSqlSessionUtil();

        private MybatisSqlSessionHelperHolder() {
        }
    }

    private MybatisSqlSessionUtil() {
    }

    public static final MybatisSqlSessionUtil getInstance() {
        return MybatisSqlSessionHelperHolder.INSTANCE;
    }
}


发布了142 篇原创文章 · 获赞 345 · 访问量 45万+

猜你喜欢

转载自blog.csdn.net/zhengchao1991/article/details/74315633