在J2EE領域,Hibernate與Mybatis是大家常用的持久層框架,它們各有特點,在持久層框架中處於領導地位。
本文主要介紹Mybatis(對於較小型的系統,特別是報表較多的系統,個人偏向Mybatis),對於它,個人比較喜歡的是:
- 使用簡單、方便;
- 支持的XML動態SQL的編寫,方便瀏覽、修改,同時降低SQL與應用程序之間的耦合。
不喜歡的是:
- 出現錯誤時,調試不太方便
本文主要介紹Mybatis的搭建,是學習Mybatis過程后整理的札記,其中包括“單獨搭建Mybaits”和常用的“Mybatis與Spring的整合”。
一、數據庫的准備
因為Mybatis是持久層框架,毫無疑問,是需要操作數據庫的。所以,在搭建之前,我們需要先創建一個簡單的表。

create table T_USER_TEST_1407 ( USERNAME VARCHAR2(255), PASSWORD VARCHAR2(255) )
插入一些數據,以作查詢的測試。

insert into T_USER_TEST_1407 (USERNAME, PASSWORD) values ('nick', 'Optimistic,Confident,Love - 1');
二、單獨搭建Mybaits
1)環境准備、版本說明
此工程使用JDK1.6 + mybatis-3.2.4 + Oracle11g。
新建一個Web工程,由於只構建Mybatis,只引用Mybatis和Oracle JDBC驅動包
- mybatis-3.2.4.jar
- ojdbc6.jar
2)程序的搭建
首先,我們將數據源等配置信息放在一個xml,讓Mybatis可以根據這個信息去連接數據庫、管理事務。
目前我們可只關注environments節點,此節點是用於配置數據源、事務管理的 。
其他的節點,如typeAliases、mappers,是用於注冊一些信息的,后面會陸續提到。

1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 5 6 <configuration> 7 8 <!-- Register Alias --> 9 <typeAliases> 10 <typeAlias alias="user" type="com.nicchagil.mybatisonly.bean.User" /> 11 </typeAliases> 12 13 <!-- Data Source --> 14 <environments default="development"> 15 <environment id="development"> 16 <transactionManager type="JDBC" /> 17 <dataSource type="POOLED"> 18 <property name="driver" value="oracle.jdbc.driver.OracleDriver" /> 19 <property name="url" value="jdbc:oracle:thin:@xxx.xxx.xxx.xxx:xxxx:xxxxxx" /> 20 <property name="username" value="xxxx" /> 21 <property name="password" value="xxxx" /> 22 </dataSource> 23 </environment> 24 </environments> 25 26 <!-- Register Mapper --> 27 <mappers> 28 <!-- SQL Mapper --> 29 <mapper resource="com/nicchagil/mybatisonly/mapper/sqlxml/UserMapper.xml" /> 30 </mappers> 31 32 </configuration>
既然有了配置的xml,下一步就需要讓Mybatis加載它了。
- 首先以輸入流的形式加載xml
- 以“SqlSessionFactoryBuilder -> SqlSessionFactory -> SqlSession”的流程最后構建出SqlSession。
- SqlSession,顧名思義,是一次會話,是應用程序與數據庫交互的會話,所以,其生命周期應在一次數據庫連接之間,當然,此次數據庫連接可以包含一次或多次數據庫操作。
- SqlSessionFactory,顧名思義,是SqlSession的工廠類,用於產出SqlSession。我們知道,SqlSession主要用於數據庫操作,而數據庫操作又是貫穿於應用程序整個生命周期當中的,那么,"產出SqlSession"這個動作也應當貫穿於應用程序整個生命周期當中,所以,SqlSessionFactory的生命周期一般為應用程序的整個生命周期,一般為單例/static的形式存在。
- SqlSessionFactoryBuilder,由代碼可見,其主要作用是從配置文件中獲取配置信息,然后構建SqlSessionFactory,所以其生命周期可以是臨時的,局部的。
- 通過SqlSession獲取UserMapper接口,再調用該接口的數據操縱方法。

package com.nicchagil.mybatisonly; 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; import com.nicchagil.mybatisonly.bean.User; import com.nicchagil.mybatisonly.mapper.UserMapper; public class Call { public static SqlSessionFactory sqlSessionFactory = null; public static void main(String[] args) throws IOException { // Query User /* kickStartMybatis(); queryUser("nick"); */ // Inser User kickStartMybatis(); insertUser("user004", "hello world."); } public static void kickStartMybatis() throws IOException { String resource = "com/nicchagil/mybatisonly/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } /** * Query User * @param username * @return */ public static User queryUser(String username) { User user = null; SqlSession session = sqlSessionFactory.openSession(); try { /* Un-recommended Method */ /* user = (User)session.selectOne("com.nicchagil.mybatisonly.mapper.UserMapper.queryUser", username); */ /* Recommended Method */ UserMapper userMapper = session.getMapper(UserMapper.class); user = userMapper.queryUser(username); System.out.println("username - " + user.getUsername() + " , password - " + user.getPassword()); } finally { session.close(); } return user; } /** * Insert User * @param username * @param password */ public static void insertUser(String username, String password) { SqlSession session = sqlSessionFactory.openSession(); try { UserMapper userMapper = session.getMapper(UserMapper.class); User user = new User(); user.setUsername(username); user.setPassword(password); userMapper.insertUser(user); // Flushes batch statements and commits database connection. // Note that database connection will not be committed if no updates/deletes/inserts were called. session.commit(); System.out.println("username - " + user.getUsername() + " , password - " + user.getPassword()); } catch (Exception e) { session.rollback(); e.printStackTrace(); //TODO Print the exception logs //TODO Prompts fail to execute for user } finally { session.close(); } } /** * Insert User * @param username * @param password */ public static void insertUserBySQL(String username, String password) { SqlSession session = sqlSessionFactory.openSession(); try { User user = new User(); user.setUsername(username); user.setPassword(password); session.insert("com.nicchagil.mybatisonly.mapper.UserMapper.insertUser", user); // Flushes batch statements and commits database connection. // Note that database connection will not be committed if no updates/deletes/inserts were called. session.commit(); } catch (Exception e) { session.rollback(); e.printStackTrace(); //TODO Print the exception logs //TODO Prompts fail to execute for user } finally { session.close(); } } }
UserMapper是一個DAO的接口,是定義作哪些數據庫操作的。

1 package com.nicchagil.mybatisonly.mapper; 2 3 import com.nicchagil.mybatisonly.bean.User; 4 5 public interface UserMapper { 6 7 public User queryUser(String username); 8 9 }
UserMapper只是供調用的接口,那么具體的實現邏輯在哪里呢?
我們可見UserMaper.xml,它定義的SQL就是用於定義UserMapper接口的實現。我們需在mybatis-config.xml注冊UserMaper.xml,可見mybatis-config.xml的mappers節點。
- 我們可以看到id為queryUser,與接口的方法名對應;
- SQL我們很熟悉了,就是一個簡單的SQL,而#{username},就是接口方法的入參;
- resultType為"user",這個user是一個別名,具體對應com.nicchagil.mybatisonly.bean.User這個類,我們可以看到在mybatis-config.xml文件的typeAliases節點中已經注冊它們的映射關系。

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.nicchagil.mybatisonly.mapper.UserMapper"> <select id="queryUser" resultType="user"> select * from t_user_test_1407 t where t.username = #{username} </select> <insert id="insertUser" parameterType="user"> INSERT INTO t_user_test_1407 T (T.USERNAME, T.PASSWORD) VALUES (#{username}, #{password}) </insert> </mapper>
而com.nicchagil.mybatisonly.bean.User是實體類,用於裝載數據。

1 package com.nicchagil.mybatisonly.bean; 2 3 public class User { 4 5 private String username; 6 private String password; 7 8 public String getUsername() { 9 return username; 10 } 11 12 public void setUsername(String username) { 13 this.username = username; 14 } 15 16 public String getPassword() { 17 return password; 18 } 19 20 public void setPassword(String password) { 21 this.password = password; 22 } 23 24 @Override 25 public int hashCode() { 26 final int prime = 31; 27 int result = 1; 28 result = prime * result 29 + ((password == null) ? 0 : password.hashCode()); 30 result = prime * result 31 + ((username == null) ? 0 : username.hashCode()); 32 return result; 33 } 34 35 @Override 36 public boolean equals(Object obj) { 37 if (this == obj) 38 return true; 39 if (obj == null) 40 return false; 41 if (getClass() != obj.getClass()) 42 return false; 43 User other = (User) obj; 44 if (password == null) { 45 if (other.password != null) 46 return false; 47 } else if (!password.equals(other.password)) 48 return false; 49 if (username == null) { 50 if (other.username != null) 51 return false; 52 } else if (!username.equals(other.username)) 53 return false; 54 return true; 55 } 56 57 }
最后,我們運行Call.java,將能成功查詢、插入數據庫。我們可通過打印的信息和查詢數據庫,以查看是否成功查詢、插入數據。
3)事務說明
對於數據庫有寫操作的應用程序,一般來說,事務是不可或缺的一部分。因為未使用其他框架,這里使用編程式事務,即使用SqlSession.commit()和SqlSession.rollback()方法,可見Call.java。
- 由於本程序對事務有異常回滾的要求,所以,需要獲取非自動提交的SqlSession
- 如程序執行正常,則最后執行session.commit()以提交事務。
- session.commit()有個需注意的地方,參考其如下注釋,即如果當前會話中不涉及updates/deletes/insert等寫數動作則不提交事務。所以,如果要觸發Mybatis提交事務,就需執行明確的觸發動作,如“執行session.insert(...)方法”或“執行對應的SQL Mapper配置中的insert、update、delete等標簽”等操作。(本人曾嘗試在SQL Mapper配置中用select標簽包含INSERT的SQL,使用SqlSession.commit()后,執行正常,但沒有提交事務,可見並未觸發,所以,需規范使用標簽)。如需強制提交,可用SqlSession.commit(boolean)。
Flushes batch statements and commits database connection. Note that database connection will not be committed if no updates/deletes/inserts were called. To force the commit call SqlSession.commit(boolean)
- session.commit()有個需注意的地方,參考其如下注釋,即如果當前會話中不涉及updates/deletes/insert等寫數動作則不提交事務。所以,如果要觸發Mybatis提交事務,就需執行明確的觸發動作,如“執行session.insert(...)方法”或“執行對應的SQL Mapper配置中的insert、update、delete等標簽”等操作。(本人曾嘗試在SQL Mapper配置中用select標簽包含INSERT的SQL,使用SqlSession.commit()后,執行正常,但沒有提交事務,可見並未觸發,所以,需規范使用標簽)。如需強制提交,可用SqlSession.commit(boolean)。
- 如程序執行異常,則回滾事務,session.rollback()
單獨搭建Mybaits完畢!
二、 Mybatis與Spring的整合
一個項目中,單獨使用Mybatis的情況並不多;更多的情況下,我們需要將Mybatis與其他框架進行整合,以便更好地使用。比如Mybatis + Spring,就是一個流行的整合組合。
1)環境准備、版本說明
本次用Mybatis3 + Spring3進行整合。注意,並不包含MVC框架的配置,因為本文的目的是學習Mybatis,所以盡量不引用其他框架,以避免影響代碼的理解。
需引入的類庫詳情如下:

<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>3.2.10.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.webflow</groupId> <artifactId>spring-webflow</artifactId> <version>2.4.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-oracle</artifactId> <version>1.0.0.RELEASE</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.4</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.2</version> </dependency> </dependencies>
2)程序的搭建
首先,我們在Spring中配置關於Mybatis數據源的信息。
這里以applicationContext-mybatis.xml來體現,配置了如下信息:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- JDBC Data Source --> <!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" > <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" /> <property name="url" value="jdbc:oracle:thin:@hostname:port:sid" /> <property name="username" value="username" /> <property name="password" value="password" /> </bean> --> <!-- JNDI Data Source --> <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>JNDI_TEST_DB</value> </property> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations"> <list> <value>classpath:com/nicchagil/mybatis3spring3intg/mapper/sqlxml/*_mapper.xml</value> <value>classpath:com/nicchagil/mybatis3spring3intg/bean/resultmapxml/*_resultmap.xml</value> </list> </property> <property name="typeAliasesPackage" value="com.nicchagil.mybatis3spring3intg.bean" /> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.nicchagil.mybatis3spring3intg.mapper" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> </bean> </beans>
除了Mybatis的信息,還有一些Spring的信息需要配置:
- 根據注解自動掃描並注冊bean
- Spring的聲明式事務管理(用以替代上一章節的“編程式事務”)
- 由於本程序沒有集成MVC框架,在Servlet是通過Spring編程式地獲得Spring管理的bean,所以這里注冊一個Spring的工具類。(使用了MVC框架並將框架交由Spring IOC容器管理的,可忽視此點配置)

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <context:component-scan base-package="com.nicchagil.mybatis3spring3intg" /> <!-- Transaction Support --> <tx:annotation-driven transaction-manager="transactionManager" /> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <bean id="SpringContextUtil" class="com.nicchagil.util.SpringContextUtil"/> </beans>
眾所周知,以上是Spring的配置文件,那么我們需要告訴應用程序“這些配置文件在哪里”,所以我們需要在web.xml中告訴應用程序。另外,此web.xml注冊了一個Servlet,用於接收頁面的請求。

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>mybatis3spring3Intg</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:config/applicationContext*.xml</param-value> </context-param> <servlet> <description></description> <display-name>UserServlet</display-name> <servlet-name>UserServlet</servlet-name> <servlet-class>com.nicchagil.mybatis3spring3intg.servlet.UserServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>UserServlet</servlet-name> <url-pattern>/UserServlet</url-pattern> </servlet-mapping> </web-app>
我們還需要定義Mapper的接口,即DAO接口。此處的Mapper的接口,我們已經在applicationContext-mybatis.xml中注冊為指定路徑下自動掃描。

package com.nicchagil.mybatis3spring3intg.mapper; import com.nicchagil.mybatis3spring3intg.bean.User; public interface UserMapper { public User find(String username); public void save(User user); }
而Mapper的實現是如何的呢?
Mybatis會幫我們實現,我們只需要通過user_mapper.xml文件告訴Mybatis對應的SQL,此處的mapper文件,已經在applicationContext-mybatis.xml中注冊為指定路徑下自動掃描。

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.nicchagil.mybatis3spring3intg.mapper.UserMapper"> <select id="find" resultType="user" resultMap="userResultMap"> select * from t_user_test_1407 t where t.username = #{username} </select> <insert id="save" parameterType="user"> INSERT INTO t_user_test_1407 T (T.USERNAME, T.PASSWORD) VALUES (#{username}, #{password}) </insert> </mapper>
可以看到,Mapper和SQL配置文件中都引用到了實體類,我們也需要定義。此處的實體類,已經在applicationContext-mybatis.xml中注冊為指定路徑下自動掃描。

package com.nicchagil.mybatis3spring3intg.bean; public class User { private String username; private String password; private String childhoodName; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getChildhoodName() { return childhoodName; } public void setChildhoodName(String childhoodName) { this.childhoodName = childhoodName; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((childhoodName == null) ? 0 : childhoodName.hashCode()); result = prime * result + ((password == null) ? 0 : password.hashCode()); result = prime * result + ((username == null) ? 0 : username.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; User other = (User) obj; if (childhoodName == null) { if (other.childhoodName != null) return false; } else if (!childhoodName.equals(other.childhoodName)) return false; if (password == null) { if (other.password != null) return false; } else if (!password.equals(other.password)) return false; if (username == null) { if (other.username != null) return false; } else if (!username.equals(other.username)) return false; return true; } }
實體的屬性與DB的字段之間的映射/匹配,我們需要定義一下。此處的resultmap.xml文件已經在applicationContext-mybatis.xml中注冊為指定路徑下自動掃描。

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.nicchagil.mybatis3spring3intg.mapper.UserMapper"> <resultMap type="user" id="userResultMap"> <result property="username" column="USERNAME" /> <result property="password" column="PASSWORD" /> <result property="childhoodName" column="USERNAME" /> </resultMap> </mapper>
完成了DAO,那么接着寫Service。
首先一個Service的接口。

package com.nicchagil.mybatis3spring3intg.service; import com.nicchagil.mybatis3spring3intg.bean.User; public interface UserService { public User query(String username); public void save(User user); public void testTransaction(User user1, User user2); }
Service的實現類如下,這里只簡單地測試查詢、保存、事務是否能正常處理。

package com.nicchagil.mybatis3spring3intg.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.nicchagil.mybatis3spring3intg.bean.User; import com.nicchagil.mybatis3spring3intg.mapper.UserMapper; import com.nicchagil.mybatis3spring3intg.service.UserService; @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper mapper; @Override public User query(String username) { return mapper.find(username); } @Override public void save(User user) { mapper.save(user); } @Override @Transactional public void testTransaction(User user1, User user2) { mapper.save(user1); // Code a NullPointerException to test transaction setting String str = null; str.charAt(0); mapper.save(user2); } }
由於沒有整合MVC框架,此處由一個Servlet(此Servlet已於web.xml中注冊)獲取頁面請求並調用Service,
那么如何在Servlet中獲得Spring IOC管理下Service的bean呢?這里借助SpringContextUtil(implements ApplicationContextAware),此SpringContextUtil於以上提及的applicationContext.xml中注冊。

package com.nicchagil.mybatis3spring3intg.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.nicchagil.mybatis3spring3intg.bean.User; import com.nicchagil.mybatis3spring3intg.service.UserService; import com.nicchagil.util.SpringContextUtil; /** * Servlet implementation class UserServlet */ public class UserServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public UserServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String action = request.getParameter("action"); UserService service = (UserService)SpringContextUtil.getBean("userServiceImpl"); if ("find".equals(action)) { User user = service.query(request.getParameter("username")); System.out.println(user.getUsername() + " - " + user.getPassword() + " - " + user.getChildhoodName()); } if ("save".equals(action)) { User user = new User(); user.setUsername(request.getParameter("username")); user.setPassword(request.getParameter("password")); service.save(user); System.out.println(user.getUsername() + " - " + user.getPassword()); } if ("testTransaction".equals(action)) { User user1 = new User(); user1.setUsername(request.getParameter("username")); user1.setPassword(request.getParameter("password")); User user2 = new User(); user2.setUsername(request.getParameter("username") + " - Double"); user2.setPassword(request.getParameter("password") + " - Double"); service.testTransaction(user1, user2); System.out.println(user1.getUsername() + " - " + user1.getPassword()); System.out.println(user2.getUsername() + " - " + user2.getPassword()); } } }

package com.nicchagil.util; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; public class SpringContextUtil implements ApplicationContextAware { private static ApplicationContext applicationContext = null; @Override public void setApplicationContext(ApplicationContext ac) throws BeansException { applicationContext = ac; } public static ApplicationContext getApplicationContext() { return applicationContext; } public static Object getBean(String beanName) { return applicationContext.getBean(beanName); } public static boolean containsBean(String beanName) { return applicationContext.containsBean(beanName); } }
幾乎大功告成。
這里寫了些觸發測試的頁面,執行結果可通過“查看控制台”或“查詢數據庫”獲得。哈哈!~~
導航頁

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <a href="find.html">find</a> <br/> <a href="save.html">save</a> <br/> <a href="testTransaction.html">testTransaction</a> </body> </html>
輸入username查詢記錄的觸發頁面

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <form action="UserServlet"> <input type="hidden" name="action" value="find"> <input type="text" name="username"> <input type="submit"> </form> </body> </html>
保存頁面

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <body> <form action="UserServlet"> <input type="hidden" name="action" value="save"> <input type="text" name="username"> <input type="password" name="password"> <input type="submit"> </form> </body> </body> </html>
測試事務的觸發頁面

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <body> <form action="UserServlet"> <input type="hidden" name="action" value="testTransaction"> <input type="text" name="username"> <input type="password" name="password"> <input type="submit"> </form> </body> </body> </html>
大功告成!!
分享於:
https://github.com/nicchagil/mybatis3spring3Intg/tree/mybatis3spring3Intg_branch_initialization