我们知道在JDBC中获取并管理好Connection对象是很重要的,同样获取和管理SqlSession在MyBatis中也是很重要的。理解SqlSession相关类的作用域和生命周期才能很好地管理和使用好这些对象。
1.SqlSessionFactoryBuilder
这个类可以被实例化、使用和丢弃。一旦创建了SqISessionFactory后,这个类就不需要存在了。因此SqlSessionFactoryBuilder实例的最佳作用域是方法范围(即作为本地方法变量)。
2. SqISessionFactory
SqlSessionFactory,顾名思义就是获取SqlSession对象的工厂,功能类似于JDBC中加载数据库驱动。所以SqISessionFactory对象一旦被创建,应该在应用执行期间都存在,因此SqlSessionFactory的最佳作用域是应用范围,建议定义为静态变量。
3.SqlSession
SqlSession类似于JDBC的connection对象,每个线程都应该有自己的SqlSession实例。SqlSession的实例不能共享,它是线程不安全的。因此最佳作用域是请求或方法范围。SqlSession对象能够执行数据库的增删改查操作,因此在使用后应该关闭,并确保使用finally块来关闭它。下面的示例就是一个确保SqlSession关闭的基本模式:
SqlSessionsession=sqlSessionFactory.openSession();
try{
//do work
}finally{
session.close();
}
SqlSessionFactory和SqlSession与Hibernate的SessionFactory和Session的用法类似。而为了方便地管理和使用SqlSession对象,可以写一个类似HibernateUtil的MybatisUtil。
==========================MybatisUtil.java==========================
package com.obtk.utils;
import java.io.IOException;
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 String CONFIG_FILE_LOCATION = "mybatis-config.xml";
//当前线程里面存放session
private static final ThreadLocal<SqlSession> threadLocal
= new ThreadLocal<SqlSession>();
private static Reader reader = null;
private static SqlSessionFactoryBuilder builder=null;
private static SqlSessionFactory factory=null;
//不允许对该类进行new操作
private MybatisUtil(){}
static{
try {
//1.加载配置文件
reader=Resources.getResourceAsReader(CONFIG_FILE_LOCATION);
//2.得到工厂的创建对象
builder=new SqlSessionFactoryBuilder();
//3.得到工厂对象
factory=builder.build(reader);
} catch (IOException e) {
e.printStackTrace();
}
}
//获取session
public static SqlSession getSession(){
SqlSession session=threadLocal.get();
if(session==null){
SqlSessionFactory factory=getFactory();
session=factory.openSession();
threadLocal.set(session);
}
return session;
}
//关闭session
public static void closeSession(){
SqlSession session=threadLocal.get();
if(session!=null){
session.close();
}
threadLocal.set(null);
}
//获得工厂对象
public static SqlSessionFactory getFactory() {
if(factory==null){
factory=builder.build(reader);
}
return factory;
}
}
根据工具类,修改上一篇的代码,如下所示:
package com.obtk.test;
import org.apache.ibatis.session.SqlSession;
import com.obtk.utils.MybatisUtil;
public class TestCnt2 {
public static void main(String[] args) {
SqlSession session=null;
try {
//4.得到session
session=MybatisUtil.getSession();
//5.执行语句
int cnt=session.selectOne("user.countAll");
System.out.println("用户数:"+cnt);
} catch (Exception e) {
e.printStackTrace();
}finally{
MybatisUtil.closeSession();
}
}
}
对照上一篇入门案例的代码,是不是得到了大量的简化。