1. 程式人生 > >mybatis 封裝mybatis工具類以及測試OpenSessionInView

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
	}

}