mybatis 封装mybatis工具类以及测试OpenSessionInView

使用Mybatis时的重复操作

  我们在使用mybatis来进行数据库的相关操作时,无论是增删改,还是查询,都需要做的就是:

  1、读取mybatis.xml配置文件。

  2、利用配置文件创建SqlSessionFactory类的对象。

  3、利用SqlSessionFactory类的对象来获取SqlSession

  4、进行数据库操作之后,关闭SqlSession。

  上面这几步,如果不封装为一个工具类,那么就需要在每一个serviceImpl中写一次,当service数量较大时,代码的冗余就会比较明显。另外,上面这几步都涉及到对象的创建与销毁,如果客户端每次发起一个请求,请求处理过程中,如果涉及到多个java文件的相互配合,那么,就需要在每一个涉及到的每一个java文件中都写一次,产生不必要的开销,因为一个请求由一个线程解决,可以通过线程的共享数据来实现节约资源。

封装的Mybatis工具类

package lixin.gan.util;

import java.io.IOException;
import java.io.InputStream;

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 	factory = null;
	private static ThreadLocal<SqlSession> threadlocal = new ThreadLocal<>();
	
	// 静态初始块,用来创建一个SqlSessionFactory,不需要每次使用这个工具类都去创建一个工厂。
	static {
		try{
			InputStream config = Resources.getResourceAsStream("mybatis.xml");
			factory = new SqlSessionFactoryBuilder().build(config);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取mybatis连接数据库返回的sqlsession
	 * @return	org.apache.ibatis.session.SqlSession
	 */
	public static SqlSession getSqlSession() {
		SqlSession sqlSession = threadlocal.get();
		
		if (sqlSession == null) {
			sqlSession = factory.openSession();
			threadlocal.set(sqlSession);
		}
		
		return sqlSession;
	}
	
	/**
	 * 关闭当前线程的mybatis的sqlSession连接
	 */
	public static void closeSqlSession() {
		SqlSession sqlSession = threadlocal.get();
		
		if (sqlSession != null) {
			sqlSession.close();
		}
		
		threadlocal.set(null);
	}

}

  

封装后的小问题

  封装后,可以分别调用两个静态方法getSqlSession()和closeSqlSession()来实现sqlSession的获取与销毁,但是我们在业务逻辑中,还需要手动写这两行代码,对吗,其实这还是有一点冗余的,这个时候,我们可以尝试使用OpenSessionInView的思想。

OpenSessionInView

  平时的业务处理流程如下:

  1、用户请求

  2、serlvet接受请求

  3、servlet实例化serviceImpl来处理业务

  4、serviceImpl实例化mapper或者dao

  上面的过程,我们可以找到一个缝隙,将获取和销毁sqlSession的操作,塞到这个缝隙中,而这个缝隙就是在1和2之间,也就是filter(过滤器)。

package lixin.gan.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;

import org.apache.ibatis.session.SqlSession;

import lixin.gan.util.MyBatisUtil;

/**
 * Servlet Filter implementation class OpenSessionInView
 */
@WebFilter("/*")
public class OpenSessionInView implements Filter {

	@Override
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}
	
	/**
	 * 在正式处理请求之前,获取SqlSession
	 * 在请求处理完毕之后,销毁SqlSession
	 */
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		
		SqlSession sqlSession = MyBatisUtil.getSqlSession();
		// 调用getSqlSession()后,ThreadLocal容器中可以通过get()来获取此处创建的sqlSession。
		
		try {
			chain.doFilter(request, response);
		} catch(Exception e) {
			sqlSession.rollback();
			e.printStackTrace();
		} finally {
			MyBatisUtil.closeSqlSession();
		}
		
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
	}

}

  

  

猜你喜欢

转载自www.cnblogs.com/-beyond/p/10130300.html