阅读前,希望您已经有以下基础:
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;
}
}