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

时间:2022-12-11 11:13:42

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

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;
}
}