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.
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
Add the listener definition to the web deployment descriptor (web.xml)
<listener> <listener-class> com.mypackage.listeners.CustomServletContextListener </listener-class> </listener>
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
Now whenever you need a myBatis sqlSessionFactory, you can use the following code from any servlet
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.
<environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="JNDI"> <property name="initial_context" value="java:comp/env"/> <property name="data_source" value="/jdbc/mydb"/> </dataSource> </environment> <environment id="testing"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${db.driver}"/> <property name="url" value="${db.url}"/> <property name="username" value="${db.user}"/> <property name="password" value="${db.pass}"/> </dataSource> </environment> </environments>
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{ //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); SqlSessionFactory sqlSessionFactory2 = new SqlSessionFactoryBuilder().build(reader,"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");