涉及內容:
- Spring 和 MyBatis 的整合
- Annotation的事務管理
- 響應流程
需要的lib文件:
spring 版本:spring-framework-3.1.0.RELEASE
MyBatis 版本: mybatis-3.0.6
注意:請用這以上或是更高的版本,否則會出奇怪的錯誤哦~
源代碼:
1. 新建Oracle數據表
CREATE TABLE MYUSER
(
id VARCHAR2(10) PRIMARY KEY,
pwd VARCHAR2(10) NOT NULL,
NAME VARCHAR2(15) NOT NULL,
birthday VARCHAR2(8) NOT NULL,
salary NUMBER(10,2)
);
2. 在com.entity包下新建UserEntity.class
package com.entity;
import java.io.Serializable;
public class UserEntity implements Serializable{
private static final long serialVersionUID = -458045724375300041L;
private String userID;
private String userPWD;
private String userName;
private String userBirthday;
private String userSalary;
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public String getUserPWD() {
return userPWD;
}
public void setUserPWD(String userPWD) {
this.userPWD = userPWD;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserBirthday() {
return userBirthday;
}
public void setUserBirthday(String userBirthday) {
this.userBirthday = userBirthday;
}
public String getUserSalary() {
return userSalary;
}
public void setUserSalary(String userSalary) {
this.userSalary = userSalary;
}
}
3. 在com.dao包下新建IUserDao.java 的Interface
package com.dao;
import java.util.List;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.entity.UserEntity;
public interface IUserDao{
//這裏的函數名,參數與UserMapper.xml中的id相對應。
public UserEntity getUser(String userID);
public List<UserEntity> getAllUser();
public int insertUser(UserEntity user);
public int updateUser(UserEntity user);
public int deleteUser(String userID);
}
4. 在com.service包下新建UserService.class
package com.service;
import java.util.List;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.dao.IUserDao;
import com.entity.UserEntity;
//表明該文件需要事務
@Transactional
//表明該文件是一個Service
@Service
public class UserService{
// 這個屬性由Spring幫我們注入。也就是說我們無需寫IUserDao userDao = new IUserDao();,Spring會幫我們new一個的
// MyBatis幫我們管理xml與類的映射及Dao,所以我們直接用@Autowired進行注入就可以了
@Autowired
private IUserDao userDao;
public IUserDao getUserDao() {
return userDao;
}
public void setUserDao(IUserDao userDao) {
this.userDao = userDao;
}
public UserEntity getUser(String userID) {
return userDao.getUser(userID);
}
public List<UserEntity> getAllUser() {
return userDao.getAllUser();
}
//表明該方法需要事務
@Transactional
public int insertUser(UserEntity user) {
// 以下爲驗證事務而添加的
// UserEntity user1 = new UserEntity();
// user1.setUserID("10");
// user1.setUserPWD("1");
// user1.setUserName("asd");
// user1.setUserBirthday("20120228");
// user1.setUserSalary("15000.26");
// userDao.insertUser(user1);
return userDao.insertUser(user);
}
@Transactional
public int updateUser(UserEntity user) {
// TODO Auto-generated method stub
return 0;
}
@Transactional
public int deleteUser(String userID) {
// TODO Auto-generated method stub
return 0;
}
}
5. 在src下新建spring-configuration.xml
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!-- 使用apache的DBCP連接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!-- Connection Info -->
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@192.168.80.128:1521:ocp" />
<property name="username" value="shenyang" />
<property name="password" value="shenyang" />
<!-- Connection Pooling DBCP -->
<property name="initialSize" value="5" />
<property name="maxActive" value="100" />
<property name="maxIdle" value="30" />
<property name="maxWait" value="1000" />
<property name="poolPreparedStatements" value="true" />
<property name="defaultAutoCommit" value="false" />
</bean>
6. 在src下新建mybatis-configuration.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置mybatis的緩存,延遲加載等等一系列屬性 -->
<settings>
<!-- 全局映射器啓用緩存 -->
<setting name="cacheEnabled" value="true" />
<!-- 查詢時,關閉關聯對象即時加載以提高性能 -->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 設置關聯對象加載的形態,此處爲按需加載字段(加載字段由SQL指 定),不會加載關聯表的所有字段,以提高性能 -->
<setting name="aggressiveLazyLoading" value="false" />
<!-- 對於未知的SQL查詢,允許返回不同的結果集以達到通用的效果 -->
<setting name="multipleResultSetsEnabled" value="true" />
<!-- 允許使用列標籤代替列名 -->
<setting name="useColumnLabel" value="true" />
<!-- 允許使用自定義的主鍵值(比如由程序生成的UUID 32位編碼作爲鍵值),數據表的PK生成策略將被覆蓋 -->
<!-- <setting name="useGeneratedKeys" value="true" /> -->
<!-- 給予被嵌套的resultMap以字段-屬性的映射支持 -->
<setting name="autoMappingBehavior" value="FULL" />
<!-- 對於批量更新操作緩存SQL以提高性能 -->
<setting name="defaultExecutorType" value="BATCH" />
<!-- 數據庫超過25000秒仍未響應則超時 -->
<setting name="defaultStatementTimeout" value="25000" />
</settings>
<!-- 全局別名設置,在映射文件中只需寫別名,而不必寫出整個類路徑 -->
<!-- <typeAliases>
<typeAlias alias="TestBean"
type="com.wotao.taotao.persist.test.dataobject.TestBean" />
</typeAliases> -->
<!-- 非註解的sql映射文件配置,如果使用mybatis註解,該mapper無需配置,但是如果mybatis註解中包含@resultMap註解,則mapper必須配置,給resultMap註解使用 -->
<mappers>
<mapper resource="com/mybatis/mapper/UserMapper.xml" />
</mappers>
</configuration>
7. 在com.mybatis.mapper包下新建UserMapper.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">
<!-- 這裏的namespace名字必須爲執行該sql的dao地址 -->
<mapper namespace="com.dao.IUserDao">
<resultMap type="com.entity.UserEntity" id="userResultMap">
<id property="userID" column="id"/>
<result property="userPWD" column="pwd"/>
<result property="userName" column="name"/>
<result property="userBirthday" column="birthday"/>
<result property="userSalary" column="salary"/>
</resultMap>
<select id="getUser" parameterType="String" resultType="com.entity.UserEntity" resultMap="userResultMap">
<![CDATA[
SELECT * FROM MYUSER
WHERE ID = #{userID}
]]>
</select>
<insert id="insertUser" parameterType="com.entity.UserEntity">
INSERT INTO MYUSER(ID,PWD,NAME,BIRTHDAY,SALARY)
VALUES(
#{userID},
#{userPWD},
#{userName},
#{userBirthday},
#{userSalary}
)
</insert>
</mapper>
測試:
隨便找個地方新建一個JUnitTest.class
package com.junit.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.entity.UserEntity;
import com.service.UserService;
@RunWith(SpringJUnit4ClassRunner.class)
//因爲我們沒有啓動web工程,所以無法通過web.xml執行執行spring-configuration.xml文件了,所以在這裏要顯示的聲明執行。
@ContextConfiguration(locations = { "classpath:/spring-configuration.xml" })
public class JUnitTest {
// 還記得我們之前做了兩件事嗎?
// 1. <context:component-scan base-package="com.service" />
// 2. @Service
// public class UserService
// 第一告訴Spring掃描com.service下的所有類,第二告訴UserService是一個Service,讓Spring準備處理
// 所以這裏用@Autowired註解的時候就可以將UserService注入進來了。無需我們寫UserService userService = new UserService()
@Autowired
UserService userService;
@Test
public void start(){
//ApplicationContext ct =new ClassPathXmlApplicationContext("spring-configuration.xml");
//UserService userService = (UserService)ct.getBean("userService");
try{
UserEntity user = new UserEntity();
user.setUserID("10");
user.setUserPWD("1");
user.setUserName("asd");
user.setUserBirthday("20120228");
user.setUserSalary("15000.26");
userService.insertUser(user);
}catch(Exception e){
e.printStackTrace();
}
}
}
OK,現在打開JUnitTest.class.然後鼠標右鍵以JUnit方式運行就可以測試了。
因爲是拿JUnit測試,所以並沒有編寫web.xml,在這裏補上。
<servlet>
<servlet-name>spring-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>spring-configuration.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<!-- 這裏不能寫"/*",這樣會攔截所有消息,連Index.jsp都被攔截而進步了了 -->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
其中第6行,可能會有點錯誤,這個地方,我之後如果有時間的話,會測試並改回來。
例行慣例,寫一下響應流程:
- 初始化spring-configration.xml中的userService文件。
- 通過spring-configuration.xml中的 53 行將userService文件中的userDao賦值爲 <bean id="userMapper"> 的值。
- <bean id="userMapper"> 爲com.dao.IUserDao文件加載sqlSessionFactory.openSession()產生的SqlSession屬性。(猜~)所以我們不用像MyBatis那樣自己生成SqlSession了。
- sqlSessionFactory加載 <bean id="sqlSessionFactory">。
- <bean id="userMapper">在spring-configuration.xml的 37 行加載了連接數據庫的dataSource 和mybatis-configuration.xml文件。
- mybatis-configuration.xml文件配置了緩存,延遲加載等等一系列屬性,加載了UserMapper.xml文件。
- UserMapper.xml文件中寫了最關鍵的SQL語句。(暫時告一段落)
- 在UserService.class的 46 行中可以看出UserService.insertUser(UserEntity user) 調用了userDao.insertUser(user)。
- 而經過第三步驟,userDao.insertUser(user)實際上就是調用了sqlSessionFactory.openSession().insert("userDao的包名.insertUser",user);不理解這語句的朋友請看《MyBatis 基礎筆記》。
源代碼請到: 點擊打開鏈接 下載
進階部分請到:點擊打開鏈接 觀看
好了,就這麼簡單,拜拜~