一个SqlSessionFactory 对应一个 environment(mybatis-config.xml中的environment)
package com.powernode.bank.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
/**
* MyBatis工具类
*
* @author wyj
* @version 1.0
* @since 1.0
*/
public class SqlSessionUtil {
private SqlSessionUtil() {}
//工具类的构造方法一般都是私有化的的。
//工具类中所有的方法都是静态的,直接采用类名即可调用。不需要new对象
//为了防止new对象构造方法私有化
private static SqlSessionFactory sqlSessionFactory;
/**
* 类加载时初始化sqlSessionFactory对象
*/
static {
try {
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));
} catch (Exception e) {
e.printStackTrace();
}
}
// 全局的,服务器级别的,一个服务器当中定义一个即可。
// 为什么把Sqlsession对象放到ThreadLocal当中呢?为了保证一个线程对应一个SqlSession
private static ThreadLocal<SqlSession> local = new ThreadLocal<>();
/**
* 每调用一次openSession()可获取一个新的会话,该会话支持自动提交。
*
* @return 新的会话对象
*/
public static SqlSession openSession() {
SqlSession sqlSession = local.get();
if (sqlSession==null){
sqlSessionFactory.openSession();
//将sqlsession对象绑定到当前线程上
local.set(sqlSession);
}
return sqlSession;
}
/**
* 关闭sqlsession对象(从当前线程中移除sqlsession对象)
* @param sqlSession
*/
public static void close(SqlSession sqlSession){
if (sqlSession != null) {
sqlSession.close();
// 注意移除SqlSession对象和当前线程的绑定关系。
// 因为Tomcat服务器支持线程池
local.remove();
}
}
}
测试
@Test
public void testInsertCarByUtil(){
SqlSession sqlSession = SqlSessionUtil.openSession();
int count = sqlSession.insert("insertCar");
System.out.println(count);
sqlSession.commit();
SqlSessionUtil.close(sqlSession);
}