헤르메스 LIFE

[MyBatis] ServletContextListener를 이용한 Application 시작 시 MyBatis 초기화 본문

Spring Framework

[MyBatis] ServletContextListener를 이용한 Application 시작 시 MyBatis 초기화

헤르메스의날개 2012. 5. 25. 10:03
728x90
원문 :  http://blog.idleworx.com/2010/06/initialize-mybatis-servletcontextlisten.html

In order to initialize MyBatis 3.0.1 and make it available to your java web application your can use a ServletContextListener to set the sqlSessionFactory as an application context attribute.

(MyBatis 3.0.1을 초기화하고, 애플리케이션 컨텍스트 속성에 SqlSessionFactory 설정하기 위해, ServletContextListener 사용하여 자바 웹 애플리케이션이 사용할 수 있도록 합니다.)

This way all your servlets will have access to this object once the web application is up. So here's how to do it.

(이 방법은 모든 서블릿이 이 객체에 접근할 수 있도록 웹 애플리케이션에 올립니다. 다음은 내용을 수행하는 방법입니다.)


1) Configuring the custom ServletContextListener (사용자 ServletContextListener 설정 )

Add the listener definition to the web deployment descriptor (web.xml)



  
com.mypackage.listeners.CustomServletContextListener
  


Implement the listener


package com.mypackage.listeners;
 
import java.io.Reader;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
 
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 
public class CustomServletContextListener implements ServletContextListener
{
 public void contextInitialized(ServletContextEvent event) 
 {   
  ServletContext ctx = event.getServletContext();  
        
     String resource = "mybatis.config.xml";
     try{
      //load mybatis configuration 
      Reader reader = Resources.getResourceAsReader(resource);      
      SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
      ctx.setAttribute("sqlSessionFactory", sqlSessionFactory);
     }
     catch(Exception e){
      System.out.println("FATAL ERROR: myBatis could not be initialized");
      System.exit(1);
     }     
 }
 
 @Override
 public void contextDestroyed(ServletContextEvent event){
   
 }
}


2) Retrieving the sqlSessionFactory from a Servlet ( Servlet에서 sqlSessionFactory 찾기 )

Now whenever you need a myBatis sqlSessionFactory, you can use the following code from any servlet (이제 언제든지 myBatis sqlSessionFactory 이 필요로 할 때 , 서블릿에서 다음 코드를 사용할 수 있습니다.)


public class TestServlet extends HttpServlet{
       
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
  {
   SqlSessionFactory sf = (SqlSessionFactory)getServletContext().getAttribute("sqlSessionFactory");
   MyCrazyDAO dao = new MyCarzyDAO(sf); //you can use the sqlSessionFactory to initialize your dao layer
    
   try{
    dao.getSomeDataFromDB();
    request.setAttribute("abc", abc);         
   }
   catch(PersistenceException p){
    p.printStackTrace();  
   }
           
   RequestDispatcher view = request.getRequestDispatcher("page.jsp");
   view.forward(request, response); 
  }
}


Initializing multiple MyBatis environments/databases on application startup

If you have multiple databases (eg. defined multiple <environment> elements) in your mybatis.config.xml file (as shown below), you will need a minor change.



   
  
   
   
    
     
   
  
   
  
   
   
    
    
    
    
   
  
   
 


The MyBatis reference says that you should use only one SqlSessionFactory instance per database.

Therefore the code ServletContextListener from before should be modified to create two independent sqlSessionFactory variables in application scope.


try{
      // Multiple Database Configuration
      //load mybatis configuration 
      Reader reader = Resources.getResourceAsReader(resource); 
     
      SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); //will associate the session factory with the 'default' environment
      ctx.setAttribute("sqlSessionFactory", sqlSessionFactory);

      // 반드시 Reader를 신규로 생성해야 함. - Stream 오류 발생.
      // Source 추가 하였음.
      Reader reader2 = Resources.getResourceAsReader(resource);

      SqlSessionFactory sqlSessionFactory2 = new SqlSessionFactoryBuilder().build(reader2,"testing");
      ctx.setAttribute("sqlSessionFactory2", sqlSessionFactory2);
     }
     catch(Exception e){
      System.out.println("FATAL ERROR: myBatis could not be initialized");
      System.exit(1);
     }  


You can now use two sqlSessionFactories to manipulate data from two databases. And you can reference them in any servlet using


SqlSessionFactory sf = (SqlSessionFactory)getServletContext().getAttribute("sqlSessionFactory");
SqlSessionFactory sf2 = (SqlSessionFactory)getServletContext().getAttribute("sqlSessionFactory2");


728x90