在用MyBatis框架连接数据库时,往往要经常创建sessionFactory,重复的编写大量代码,故将其中的重复代码提出成一个工具类,这样直接调用方法即可,可简化代码编写和优化运行效率,不需要重复的读取mybatis核心配置文件和反复new工厂对象
我编写的MyBatis的util工具类如下:
package com.cxy.util;
/*避免重复new Factory对象
*
*/
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUtil {
private static SqlSessionFactory sqlsesssionFactory = null;
/*
* 创建本地线程变量,为每一个线程独立管理一个session对象 每一个线程只有且仅有单独且唯一的一个session对象
* 加上线程变量对session进行管理,可以保证线程安全,避免多实例同时调用同一个session对象
* 每一个线程都会new一个线程变量,从而分配到自己的session对象
*/
private static ThreadLocal<SqlSession> threadlocal = new ThreadLocal<>();
//创建sessionFactory对象,由于整个应用只需要一个,所以用static块
static {
String resource = "mybatis-config.xml";
try (
InputStream inputstream = Resources.getResourceAsStream(resource)){
sqlsesssionFactory = new SqlSessionFactoryBuilder().build(inputstream);
}
catch (IOException e) {
e.printStackTrace();
}
}
/**
* 返回sqlsessionFactory对象 工厂对象
*
* @return sqlsessionFactory
*/
public static SqlSessionFactory getSqlSessionFactory() {
return sqlsesssionFactory;
}
/**
* 新建session会话,并把session放在线程变量中
*/
private static void newSession() {
//打开session会话
SqlSession session = sqlsesssionFactory.openSession();
//将其保存在本地线程之中
threadlocal.set(session);
}
/*
* 返回session对象
* @return session
*/
public static SqlSession getSqlSession() {
//优先从本地线程中取
SqlSession session = threadlocal.get();
if(session==null) {
newSession();
session=threadlocal.get();
}
return session;
}
/*
* 关闭session变量,并清空threadlocal
*/
public static void closeSession() {
SqlSession session = threadlocal.get();
//当线程变量不为空,才关闭session,并清空threadlocal
if(session==null){
session.close();
threadlocal.set(null);
}
}
}
其中的Mybatis_config.xml是我的MyBatis的核心配置文件。
用静态代码块进行创建SqlSessionFactory,只在类加载时创建一次,保证了整个程序运行时只有一个工厂实例。
用线程变量保存session对象,是为了线程安全着想,这样自己的线程管理自己线程的session,不会出现多实例同时调用同一个session对象,造成数据不准确的情况出现。