涉及内容:
- 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./schema/beans"
- xmlns:xsi="http://www./2001/XMLSchema-instance" xmlns:aop="http://www./schema/aop"
- xmlns:tx="http://www./schema/tx"
- xmlns:context="http://www./schema/context"
- xsi:schemaLocation="
- http://www./schema/context
- http://www./schema/context/spring-context-3.0.xsd
- http://www./schema/beans
- http://www./schema/beans/spring-beans-3.0.xsd
- http://www./schema/tx
- http://www./schema/tx/spring-tx-3.0.xsd
- http://www./schema/aop
- http://www./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>
-
- <!-- 这里的dataSource要与sqlSessionFactory的dataSource一致,否则事务无效 -->
- <bean id="transactionManager"
- class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="dataSource" />
- </bean>
-
- <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
- <property name="dataSource" ref="dataSource" />
- <property name="configLocation" value="classpath:mybatis-configuration.xml"></property>
- </bean>
-
- <!-- 注意!这里不要偷懒!。要把userMapper赋给别的.class文件里的一个属性后再使用,否则事务无效。
- 也就是说当直接创建userMapper的一个class,然后使用IUserDao.insertUser方法的话也可以实现,但是事务将无效。 -->
- <!-- 这里的mapperInterface需要接口类型 -->
- <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
- <property name="mapperInterface" value="com.dao.IUserDao" />
- <property name="sqlSessionFactory" ref="sqlSessionFactory" />
- </bean>
-
- <!-- 扫描包 -->
- <context:component-scan base-package="com.service" />
-
- <!-- 使用注解方式的事务 -->
- <tx:annotation-driven transaction-manager="transactionManager" />
-
- </beans>
6. 在src下新建mybatis-configuration.xml
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE configuration PUBLIC "-////DTD Config 3.0//EN"
- "http:///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 "-////DTD Mapper 3.0//EN"
- "http:///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 基础笔记》。
|