mybatis 封裝mybatis工具類以及測試OpenSessionInView
阿新 • • 發佈:2018-12-17
使用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 } }