亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

java筆記:自己動手寫javaEE框架(五)--Spring

系統 3451 0

上篇文章寫到了編程式事務的使用TransactionTemplate類的實現,TransactionTemplate類里的execute方法需要TransactionCallback接口實現類做參數,其接口的定義中只包含一個doInTransaction方法用于執行事務操作,上面的代碼中使用匿名類的方式定義TransactionCallback接口實現,并且在doInTransaction()方法中定義事務處理代碼。

第五章 聲明式事務管理

  我們使用最多的還是Spring聲明式事務管理,其實所有Spring事務管理都是基于AOP來實現,而其中的聲明式事務才是真正體現AOP全部優點的最佳應用,記得我以前參加面試一說到AOP我就提及聲明式事務管理,哎,那個時候對AOP的理解也就僅限于此,太菜了。Spring聲明式事務不涉及組件的依賴關系,使用它時候不需要編寫任何代碼,很大程度的節省了工作量,提高了工作效率。下面我在我的框架里面加入聲明式事務,首先修改applicationContext.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:context
          
          
            ="http://www.springframework.org/schema/context"
          
          
            
  xmlns:aop
          
          
            ="http://www.springframework.org/schema/aop"
          
          
            
  xmlns:tx
          
          
            ="http://www.springframework.org/schema/tx"
          
          
            
  xsi:schemaLocation
          
          
            ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
          
          
            >
          
          
            <!--
          
          
             掃描該路徑下的spring組件 
          
          
            -->
          
          
            <
          
          
            context:component-scan 
          
          
            base-package
          
          
            ="cn.com.sharpxiajun"
          
          
          
          
            />
          
          
            <!--
          
          
             讀取資源文件 
          
          
            -->
          
          
            <
          
          
            bean 
          
          
            id
          
          
            ="propertyConfigurer"
          
          
             class
          
          
            ="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
          
          
            >
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="locations"
          
          
            >
          
          
            <
          
          
            list
          
          
            >
          
          
            <
          
          
            value
          
          
            >
          
          classpath:conf/constants.properties
          
            </
          
          
            value
          
          
            >
          
          
            </
          
          
            list
          
          
            >
          
          
            </
          
          
            property
          
          
            >
          
          
            </
          
          
            bean
          
          
            >
          
          
            <!--
          
          
             配置數據源 
          
          
            -->
          
          
            <!--
          
          
              <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
             <property name="driverClass" value="${db.driverClass}"/>
             <property name="jdbcUrl" value="${db.jdbcUrl}"/>
             <property name="user" value="${db.user}"/>
             <property name="password" value="${db.password}"/>
         </bean>
          
          
            -->
          
          
            <
          
          
            bean 
          
          
            id
          
          
            ="myDataSource"
          
          
             class
          
          
            ="org.apache.commons.dbcp.BasicDataSource"
          
          
             destroy-method
          
          
            ="close"
          
          
            >
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="driverClassName"
          
          
             value
          
          
            ="${db.driverClass}"
          
          
            />
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="url"
          
          
             value
          
          
            ="${db.jdbcUrl}"
          
          
            />
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="username"
          
          
             value
          
          
            ="${db.user}"
          
          
            />
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="password"
          
          
             value
          
          
            ="${db.password}"
          
          
            />
          
          
            </
          
          
            bean
          
          
            >
          
          
            <
          
          
            bean 
          
          
            id
          
          
            ="sqlMapClient"
          
          
             class
          
          
            ="org.springframework.orm.ibatis.SqlMapClientFactoryBean"
          
          
            >
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="configLocation"
          
          
            >
          
          
            <
          
          
            value
          
          
            >
          
          classpath:conf/SqlMapConfig.xml
          
            </
          
          
            value
          
          
            >
          
          
            </
          
          
            property
          
          
            >
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="dataSource"
          
          
             ref
          
          
            ="myDataSource"
          
          
            />
          
          
            </
          
          
            bean
          
          
            >
          
          
            <
          
          
            bean 
          
          
            id
          
          
            ="sqlMapClientTemplate"
          
          
             class
          
          
            ="org.springframework.orm.ibatis.SqlMapClientTemplate"
          
          
            >
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="sqlMapClient"
          
          
            >
          
          
            <
          
          
            ref 
          
          
            local
          
          
            ="sqlMapClient"
          
          
            />
          
          
            </
          
          
            property
          
          
            >
          
          
            </
          
          
            bean
          
          
            >
          
          
            <
          
          
            bean 
          
          
            id
          
          
            ="transactionManager"
          
          
             class
          
          
            ="org.springframework.jdbc.datasource.DataSourceTransactionManager"
          
          
            >
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="dataSource"
          
          
            >
          
          
            <
          
          
            ref 
          
          
            local
          
          
            ="myDataSource"
          
          
            />
          
          
            </
          
          
            property
          
          
            >
          
          
            </
          
          
            bean
          
          
            >
          
          
            <!--
          
          
             聲明式事務 
          
          
            -->
          
          
            <
          
          
            tx:advice 
          
          
            id
          
          
            ="txAdvice"
          
          
             transaction-manager
          
          
            ="transactionManager"
          
          
            >
          
          
            <
          
          
            tx:attributes
          
          
            >
          
          
            <
          
          
            tx:method 
          
          
            name
          
          
            ="get*"
          
          
             read-only
          
          
            ="true"
          
          
             propagation
          
          
            ="REQUIRED"
          
          
            />
          
          
            <
          
          
            tx:method 
          
          
            name
          
          
            ="query*"
          
          
             read-only
          
          
            ="true"
          
          
             propagation
          
          
            ="REQUIRED"
          
          
            />
          
          
            <
          
          
            tx:method 
          
          
            name
          
          
            ="find*"
          
          
             read-only
          
          
            ="true"
          
          
              propagation
          
          
            ="REQUIRED"
          
          
            />
          
          
            <
          
          
            tx:method 
          
          
            name
          
          
            ="list*"
          
          
             read-only
          
          
            ="true"
          
          
              propagation
          
          
            ="REQUIRED"
          
          
            />
          
          
            <
          
          
            tx:method 
          
          
            name
          
          
            ="search*"
          
          
             read-only
          
          
            ="true"
          
          
              propagation
          
          
            ="REQUIRED"
          
          
            />
          
          
            <
          
          
            tx:method 
          
          
            name
          
          
            ="add*"
          
          
              propagation
          
          
            ="REQUIRED"
          
          
             isolation
          
          
            ="READ_COMMITTED"
          
          
            />
          
          
            <
          
          
            tx:method 
          
          
            name
          
          
            ="insert*"
          
          
              propagation
          
          
            ="REQUIRED"
          
          
             isolation
          
          
            ="READ_COMMITTED"
          
          
            />
          
          
            <
          
          
            tx:method 
          
          
            name
          
          
            ="del*"
          
          
              propagation
          
          
            ="REQUIRED"
          
          
             isolation
          
          
            ="READ_COMMITTED"
          
          
            />
          
          
            <
          
          
            tx:method 
          
          
            name
          
          
            ="save*"
          
          
              propagation
          
          
            ="REQUIRED"
          
          
             isolation
          
          
            ="READ_COMMITTED"
          
          
            />
          
          
            <
          
          
            tx:method 
          
          
            name
          
          
            ="update*"
          
          
              propagation
          
          
            ="REQUIRED"
          
          
             isolation
          
          
            ="READ_COMMITTED"
          
          
            />
          
          
            <
          
          
            tx:method 
          
          
            name
          
          
            ="modify*"
          
          
              propagation
          
          
            ="REQUIRED"
          
          
             isolation
          
          
            ="READ_COMMITTED"
          
          
            />
          
          
            </
          
          
            tx:attributes
          
          
            >
          
          
            </
          
          
            tx:advice
          
          
            >
          
          
            <
          
          
            bean 
          
          
            id
          
          
            ="transactionTemplate"
          
          
             class
          
          
            ="org.springframework.transaction.support.TransactionTemplate"
          
          
            >
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="transactionManager"
          
          
            >
          
          
            <
          
          
            ref 
          
          
            bean
          
          
            ="transactionManager"
          
          
            />
          
          
            </
          
          
            property
          
          
            >
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="propagationBehaviorName"
          
          
            >
          
          
            <
          
          
            value
          
          
            >
          
          PROPAGATION_REQUIRED
          
            </
          
          
            value
          
          
            >
          
          
            </
          
          
            property
          
          
            >
          
          
            </
          
          
            bean
          
          
            >
          
          
            <!--
          
          
             將我自己定義的攔截器生成bean 
          
          
            -->
          
          
            <
          
          
            bean 
          
          
            id
          
          
            ="methodServiceAdvisor"
          
          
             class
          
          
            ="cn.com.sharpxiajun.common.aop.MethodServiceAdvisor"
          
          
            />
          
          
            <
          
          
            aop:config
          
          
            >
          
          
            <!--
          
          
            配置規則,滿足以下規則的將攔截,第一個*表示所有返回類型,第二個表示service包下的所有class,第三個表示所有方法
          
          
            -->
          
          
            <
          
          
            aop:pointcut 
          
          
            id
          
          
            ="baseServiceMethods"
          
          
             expression
          
          
            ="execution(* cn.com.sharpxiajun.service.*.*(..))"
          
          
            />
          
          
            <!--
          
          
             聲明式事務 
          
          
            -->
          
          
            <
          
          
            aop:advisor 
          
          
            advice-ref
          
          
            ="txAdvice"
          
          
             pointcut-ref
          
          
            ="baseServiceMethods"
          
          
          
          
            />
          
          
            <!--
          
          
             符合上面規則的攔截器都會調用到methodServiceAdvisor 
          
          
            -->
          
          
            <
          
          
            aop:advisor 
          
          
            advice-ref
          
          
            ="methodServiceAdvisor"
          
          
             pointcut-ref
          
          
            ="baseServiceMethods"
          
          
            />
          
          
            </
          
          
            aop:config
          
          
            >
          
          
            </
          
          
            beans
          
          
            >
          
        

  這里面添加了<tx:advice id="txAdvice" transaction-manager="transactionManager">,根據方法前綴不同綁定不同的事務策略,然后在<aop:config>里面添加<aop:advisor advice-ref="txAdvice" pointcut-ref="baseServiceMethods" />,那么service包下面類里的方法都會綁定相應的事務管理。在javaEE工程里面到底是DAO層綁定事務還是在Service層綁定事務?這個問題以前有同事問過我,我當時回答是都應該綁定,現在我會說最好只在Service層綁定事務。DAO層在我的理解里應該是數據庫操作的映射,那是針對數據的原子操作,而Service層則是把這些各種數據庫操作封裝成一個業務操作單元,所以Service層的含義更符合事務本質,所以事務最好綁定在Service層。DAO層再綁定事務沒必要,而且多余,甚至還會操作不必要的錯誤。

  接下來我修改USERS.xml映射文件,代碼如下:

          
            <?
          
          
            xml version="1.0" encoding="UTF-8"
          
          
            ?>
          
          
            <!
          
          
            DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd"
          
          
            >
          
          
            <
          
          
            sqlMap 
          
          
            namespace
          
          
            ="USERS"
          
          
            >
          
          
            <
          
          
            select 
          
          
            id
          
          
            ="queryUserList"
          
          
             parameterClass
          
          
            ="java.util.Map"
          
          
             resultClass
          
          
            ="java.util.HashMap"
          
          
            >
          
          
        select t.username,t.password,t.enabled from users t
    
          
            </
          
          
            select
          
          
            >
          
          
            <!--
          
          
             新增用戶信息 
          
          
            -->
          
          
            <
          
          
            insert 
          
          
            id
          
          
            ="addUsers"
          
          
             parameterClass
          
          
            ="java.util.Map"
          
          
            >
          
          
        insert into users
        
          
            <
          
          
            dynamic 
          
          
            prepend
          
          
            ="("
          
          
            >
          
          
            <
          
          
            isNotNull 
          
          
            prepend
          
          
            =","
          
          
             property
          
          
            ="username"
          
          
            >
          
          
                username
            
          
            </
          
          
            isNotNull
          
          
            >
          
          
            <
          
          
            isNotNull 
          
          
            prepend
          
          
            =","
          
          
             property
          
          
            ="password"
          
          
            >
          
          
                password
            
          
            </
          
          
            isNotNull
          
          
            >
          
          
            <
          
          
            isNotNull 
          
          
            prepend
          
          
            =","
          
          
             property
          
          
            ="enabled"
          
          
            >
          
          
                enabled
            
          
            </
          
          
            isNotNull
          
          
            >
          
          
            )        
        
          
            </
          
          
            dynamic
          
          
            >
          
              
        values
        
          
            <
          
          
            dynamic 
          
          
            prepend
          
          
            ="("
          
          
            >
          
          
            <
          
          
            isNotNull 
          
          
            prepend
          
          
            =","
          
          
             property
          
          
            ="username"
          
          
            >
          
          
                #username:VARCHAR#
            
          
            </
          
          
            isNotNull
          
          
            >
          
          
            <
          
          
            isNotNull 
          
          
            prepend
          
          
            =","
          
          
             property
          
          
            ="password"
          
          
            >
          
          
                #password:VARCHAR#
            
          
            </
          
          
            isNotNull
          
          
            >
          
          
            <
          
          
            isNotNull 
          
          
            prepend
          
          
            =","
          
          
             property
          
          
            ="enabled"
          
          
            >
          
          
                #enabled:NUMBER#
            
          
            </
          
          
            isNotNull
          
          
            >
          
          
            )
        
          
            </
          
          
            dynamic
          
          
            >
          
          
            </
          
          
            insert
          
          
            >
          
          
            </
          
          
            sqlMap
          
          
            >
          
        

  修改cn.com.sharpxiajun.dao包下的接口UsersDao,代碼如下:

          
            package
          
           cn.com.sharpxiajun.dao;


          
            import
          
           java.util.List;

          
            import
          
           java.util.Map;


          
            public
          
          
            interface
          
           UsersDao {
    
    
          
            public
          
          
            static
          
          
            final
          
           String QUERY_USERS_SQL = "USERS.queryUserList";
    
          
            public
          
          
            static
          
          
            final
          
           String ADD_USERS_SQL = "USERS.addUsers";
    
    
          
            public
          
           List<Map<String, Object>> queryUserList(Map<String, Object> map) 
          
            throws
          
           Exception;
    
    
          
            public
          
           Object addUsers(Map<String, Object> map) 
          
            throws
          
           Exception;

}
        

  修改cn.com.sharpxiajun.dao.impl包下面UsersDaoImpl類,代碼如下:

          
            package
          
           cn.com.sharpxiajun.dao.impl;


          
            import
          
           java.util.List;

          
            import
          
           java.util.Map;



          
            import
          
           org.springframework.beans.factory.annotation.Autowired;

          
            import
          
           org.springframework.beans.factory.annotation.Qualifier;

          
            import
          
           org.springframework.context.annotation.Scope;

          
            import
          
           org.springframework.orm.ibatis.SqlMapClientTemplate;

          
            import
          
           org.springframework.stereotype.Repository;


          
            import
          
           cn.com.sharpxiajun.dao.UsersDao;

@SuppressWarnings("unchecked")
@Scope("prototype")
@Repository("usersDao")

          
            public
          
          
            class
          
           UsersDaoImpl 
          
            implements
          
           UsersDao {
    
    @Autowired
    @Qualifier("sqlMapClientTemplate")
    
          
            private
          
           SqlMapClientTemplate sqlMapClientTemplate = 
          
            null
          
          ;

    
          
            public
          
           List<Map<String, Object>> queryUserList(Map<String, Object> map)
            
          
            throws
          
           Exception {
        
          
            return
          
           sqlMapClientTemplate.queryForList(QUERY_USERS_SQL, map);
    }

    @Override
    
          
            public
          
           Object addUsers(Map<String, Object> map) 
          
            throws
          
           Exception {
        
          
            return
          
            sqlMapClientTemplate.insert(ADD_USERS_SQL, map);
    }

}
        

  修改cn.com.sharpxiajun.service包下接口UsersService,代碼如下:

          
            package
          
           cn.com.sharpxiajun.service;


          
            import
          
           java.util.List;

          
            import
          
           java.util.Map;


          
            public
          
          
            interface
          
           UsersService {
    
    
          
            public
          
           List<Map<String, Object>> queryUsersList(Map<String, Object> map) 
          
            throws
          
           Exception;
    
    
          
            public
          
           Object addUsers(Map<String, Object> map) 
          
            throws
          
           Exception;

}
        

  修改cn.com.sharpxiajun.service.impl包下類UsersServiceImpl,代碼如下:

          
            package
          
           cn.com.sharpxiajun.service.impl;


          
            import
          
           java.util.List;

          
            import
          
           java.util.Map;



          
            import
          
           org.springframework.beans.factory.annotation.Autowired;

          
            import
          
           org.springframework.beans.factory.annotation.Qualifier;

          
            import
          
           org.springframework.context.annotation.Scope;

          
            import
          
           org.springframework.stereotype.Service;


          
            import
          
           cn.com.sharpxiajun.dao.UsersDao;

          
            import
          
           cn.com.sharpxiajun.service.UsersService;

@SuppressWarnings("unchecked")
@Scope("prototype")
@Service("userService")

          
            public
          
          
            class
          
           UsersServiceImpl 
          
            implements
          
           UsersService {
    
    @Autowired
    @Qualifier("usersDao")
    
          
            private
          
           UsersDao usersDao = 
          
            null
          
          ;

    @Override
    
          
            public
          
           List<Map<String, Object>> queryUsersList(Map<String, Object> map)
            
          
            throws
          
           Exception {
        
          
            return
          
           usersDao.queryUserList(map);
    }

    @Override
    
          
            public
          
           Object addUsers(Map<String, Object> map) 
          
            throws
          
           Exception {
        
          
            return
          
           usersDao.addUsers(map);
    }

}
        

  修改cn.com.sharpxiajun.junittest.service包下測試類UsersServiceImplTest,代碼如下:

          
            package
          
           cn.com.sharpxiajun.junittest.service;


          
            import
          
           java.util.HashMap;

          
            import
          
           java.util.List;

          
            import
          
           java.util.Map;


          
            import
          
           org.apache.commons.logging.Log;

          
            import
          
           org.apache.commons.logging.LogFactory;

          
            import
          
           org.junit.After;

          
            import
          
           org.junit.Before;

          
            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.AbstractTransactionalJUnit4SpringContextTests;

          
            import
          
           org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

          
            import
          
           org.springframework.test.context.transaction.TransactionConfiguration;


          
            import
          
           cn.com.sharpxiajun.service.UsersService;

          
            import
          
           cn.com.sharpxiajun.service.impl.UsersServiceImpl;

@RunWith(SpringJUnit4ClassRunner.
          
            class
          
          )
@ContextConfiguration(locations={"classpath:conf/applicationContext.xml"})
@TransactionConfiguration(defaultRollback = 
          
            false
          
          )

          
            public
          
          
            class
          
           UsersServiceImplTest 
          
            extends
          
          
        AbstractTransactionalJUnit4SpringContextTests {
    
    
          
            private
          
          
            final
          
          
            static
          
           Log log = LogFactory.getLog(UsersServiceImpl.
          
            class
          
          );
    
    @Autowired
    
          
            private
          
           UsersService usersService = 
          
            null
          
          ;
    
    
          
            public
          
           UsersServiceImplTest()
    {
        System.out.println("初始化測試類....");
    }
    
    @Before
    
          
            public
          
          
            void
          
           setUp() 
          
            throws
          
           Exception
    {
        System.out.println("測試開始....");
    }
    
    @After
    
          
            public
          
          
            void
          
           tearDown() 
          
            throws
          
           Exception
    {
        System.out.println("測試結束!!");
    }
    
    @Test
    
          
            public
          
          
            void
          
           testQueryUserList()
    {
        Map<String, Object> map = 
          
            new
          
           HashMap<String, Object>();
        map.put("username", "sharpxiajun");
        
          
            try
          
           {
            List<Map<String, Object>> list = usersService.queryUsersList(map);
            log.info(list);
        } 
          
            catch
          
           (Exception e) {
            e.printStackTrace();
        }
    }
    
    @Test
    
          
            public
          
          
            void
          
           testAddUsers()
    {
        Map<String, Object> map = 
          
            new
          
           HashMap<String, Object>();
        map.put("username", "xiajun");
        map.put("password", "xiajun");
        map.put("enabled", 1);
        
        
          
            try
          
           {
            Object obj = usersService.addUsers(map);
            log.info("testAddUsers:" + obj);
        } 
          
            catch
          
           (Exception e) {
            e.printStackTrace();
        }
    }

}
        

  運行測試類,結果如下:

java筆記:自己動手寫javaEE框架(五)--Spring事務管理學習

  數據新增了,但是沒有體現事務的作用,我前面寫事務示例代碼也沒有考慮到如何表現事務的作用,為了體現事務作用,我在USERS.xml配置文件里添加新方法,代碼如下:

          
            <!--
          
          
             修改用戶信息 
          
          
            -->
          
          
            <
          
          
            update 
          
          
            id
          
          
            ="updateUsers"
          
          
             parameterClass
          
          
            ="java.util.Map"
          
          
            >
          
          
        update users set errinfo = 'error'
    
          
            </
          
          
            update
          
          
            >
          
        

  修改cn.com.sharpxiajun.dao包下的UsersDao接口,代碼如下:

          
            package
          
           cn.com.sharpxiajun.dao;


          
            import
          
           java.util.List;

          
            import
          
           java.util.Map;


          
            public
          
          
            interface
          
           UsersDao {
    
    
          
            public
          
          
            static
          
          
            final
          
           String QUERY_USERS_SQL = "USERS.queryUserList";
    
          
            public
          
          
            static
          
          
            final
          
           String ADD_USERS_SQL = "USERS.addUsers";
    
          
            public
          
          
            static
          
          
            final
          
           String UPDATE_USERS_SQL = "USERS.updateUsers";
    
    
          
            public
          
           List<Map<String, Object>> queryUserList(Map<String, Object> map) 
          
            throws
          
           Exception;
    
    
          
            public
          
           Object addUsers(Map<String, Object> map) 
          
            throws
          
           Exception;
    
    
          
            public
          
           Object updateUsers(Map<String, Object> map) 
          
            throws
          
           Exception;

}
        

  修改cn.com.sharpxiajun.dao.impl包下的UsersDaoImpl類,代碼如下:

          
            package
          
           cn.com.sharpxiajun.dao.impl;


          
            import
          
           java.util.List;

          
            import
          
           java.util.Map;



          
            import
          
           org.springframework.beans.factory.annotation.Autowired;

          
            import
          
           org.springframework.beans.factory.annotation.Qualifier;

          
            import
          
           org.springframework.context.annotation.Scope;

          
            import
          
           org.springframework.orm.ibatis.SqlMapClientTemplate;

          
            import
          
           org.springframework.stereotype.Repository;


          
            import
          
           cn.com.sharpxiajun.dao.UsersDao;

@SuppressWarnings("unchecked")
@Scope("prototype")
@Repository("usersDao")

          
            public
          
          
            class
          
           UsersDaoImpl 
          
            implements
          
           UsersDao {
    
    @Autowired
    @Qualifier("sqlMapClientTemplate")
    
          
            private
          
           SqlMapClientTemplate sqlMapClientTemplate = 
          
            null
          
          ;

    
          
            public
          
           List<Map<String, Object>> queryUserList(Map<String, Object> map)
            
          
            throws
          
           Exception {
        
          
            return
          
           sqlMapClientTemplate.queryForList(QUERY_USERS_SQL, map);
    }

    @Override
    
          
            public
          
           Object addUsers(Map<String, Object> map) 
          
            throws
          
           Exception {
        
          
            return
          
            sqlMapClientTemplate.insert(ADD_USERS_SQL, map);
    }

    @Override
    
          
            public
          
           Object updateUsers(Map<String, Object> map) 
          
            throws
          
           Exception {
        
          
            return
          
           sqlMapClientTemplate.update(UPDATE_USERS_SQL, map);
    }

}
        

  在cn.com.sharpxiajun.service包的UsersService接口里添加方法:

          
            public
          
          
            void
          
           updateUsers(Map<String, Object> map) 
          
            throws
          
           Exception;
        

  在cn.com.sharpxiajun.service.impl下的UsersServiceImpl類里實現該方法,代碼如下:

              @Override
    
          
            public
          
          
            void
          
           updateUsers(Map<String, Object> map) 
          
            throws
          
           Exception {
        usersDao.addUsers(map);
        usersDao.updateUsers(map);
    }
        

  從上面代碼可以看出USERS.xml的update方法是不能被執行,程序一定會報出異常,如果方法綁定了事務,那么usersDao.addUsers(map);操作會被回滾掉,也就是新增操作不會成功,下面我在cn.com.sharpxiajun.junittest.service包下的UsersServiceImplTest類里添加新的測試方法,代碼如下:

              @Test
    
          
            public
          
          
            void
          
           testUpdateUsers()
    {
        Map<String, Object> map = 
          
            new
          
           HashMap<String, Object>();
        map.put("username", "sharp");
        map.put("password", "sharp");
        map.put("enabled", 1);
        
        
          
            try
          
           {
            usersService.updateUsers(map);
        } 
          
            catch
          
           (Exception e) {
            e.printStackTrace();
        }
    }
        

(注意:最好把測試新增方法的代碼注釋掉)

  運行測試類,控制臺會打印出下面異常:

          2011-10-25 23:10:59  SQLErrorCodesFactory - SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
org.springframework.jdbc.BadSqlGrammarException: SqlMapClient operation; bad SQL grammar []; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:   
--- The error occurred in cn/com/sharpxiajun/dao/sqlmap/USERS.xml.  
--- The error occurred 
          
            while
          
           applying a parameter map.  
--- Check the USERS.updateUsers-InlineParameterMap.  
--- Check the statement (update failed).  
--- Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'errinfo' in 'field list'
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:233)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
    at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:203)
    at org.springframework.orm.ibatis.SqlMapClientTemplate.update(SqlMapClientTemplate.java:378)
    at cn.com.sharpxiajun.dao.impl.UsersDaoImpl.updateUsers(UsersDaoImpl.java:36)
    at cn.com.sharpxiajun.service.impl.UsersServiceImpl.updateUsers(UsersServiceImpl.java:45)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at cn.com.sharpxiajun.common.aop.MethodServiceAdvisor.invoke(MethodServiceAdvisor.java:31)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy18.updateUsers(Unknown Source)
    at cn.com.sharpxiajun.junittest.service.UsersServiceImplTest.testUpdateUsers(UsersServiceImplTest.java:103)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: com.ibatis.common.jdbc.exception.NestedSQLException:   
--- The error occurred in cn/com/sharpxiajun/dao/sqlmap/USERS.xml.  
--- The error occurred 
          
            while
          
           applying a parameter map.  
--- Check the USERS.updateUsers-InlineParameterMap.  
--- Check the statement (update failed).  
--- Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'errinfo' in 'field list'
    at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeUpdate(MappedStatement.java:107)
    at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.update(SqlMapExecutorDelegate.java:457)
    at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.update(SqlMapSessionImpl.java:90)
    at org.springframework.orm.ibatis.SqlMapClientTemplate$9.doInSqlMapClient(SqlMapClientTemplate.java:380)
    at org.springframework.orm.ibatis.SqlMapClientTemplate$9.doInSqlMapClient(SqlMapClientTemplate.java:1)
    at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:200)
    ... 49 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'errinfo' in 'field list'
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
    at com.mysql.jdbc.Util.getInstance(Util.java:381)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1031)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3376)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3308)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1837)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1961)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2543)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1737)
    at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:998)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:169)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.ibatis.common.jdbc.logging.PreparedStatementLogProxy.invoke(PreparedStatementLogProxy.java:62)
    at $Proxy21.execute(Unknown Source)
    at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeUpdate(SqlExecutor.java:80)
    at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.sqlExecuteUpdate(MappedStatement.java:216)
    at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeUpdate(MappedStatement.java:94)
    ... 54 more
測試結束!!
2011-10-25 23:10:59  TestContextManager - Caught exception 
          
            while
          
           allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@6798eb] to process 'after' execution 
          
            for
          
           test: method [
          
            public
          
          
            void
          
           cn.com.sharpxiajun.junittest.service.UsersServiceImplTest.testUpdateUsers()], instance [cn.com.sharpxiajun.junittest.service.UsersServiceImplTest@168989e], exception [
          
            null
          
          ]
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:717)
    at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:516)
    at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:291)
    at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:184)
    at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:406)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:90)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
        

  結果如下:

java筆記:自己動手寫javaEE框架(五)--Spring事務管理學習

  沒有新的記錄被添加,事務被成功綁定了~~~。

  那么如果我們寫在Service里面的方法沒有用applicationContext.xml里面設置的前綴,效果會如何了?

  我在cn.com.sharpxiajun.service包的UsersService接口下添加新方法,代碼如下:

          
            public
          
          
            void
          
           noTransactionMethod(Map<String, Object> map) 
          
            throws
          
           Exception;
        

  在cn.com.sharpxiajun.service.impl包里UsersServiceImpl類實現該方法,代碼如下:

              @Override
    
          
            public
          
          
            void
          
           noTransactionMethod(Map<String, Object> map) 
          
            throws
          
           Exception {
        usersDao.addUsers(map);
        usersDao.updateUsers(map);
        
    }
        

  最后在cn.com.sharpxiajun.junittest.service包下,修改UsersServiceImplTest測試類,代碼如下:

          
            //
          
          
                @Test

          
          
            //
          
          
                public void testAddUsers()

          
          
            //
          
          
                {

          
          
            //
          
          
                    Map<String, Object> map = new HashMap<String, Object>();

          
          
            //
          
          
                    map.put("username", "xiajun");

          
          
            //
          
          
                    map.put("password", "xiajun");

          
          
            //
          
          
                    map.put("enabled", 1);

          
          
            //
          
          
          
          
            //
          
          
                    try {

          
          
            //
          
          
                        Object obj = usersService.addUsers(map);

          
          
            //
          
          
                        log.info("testAddUsers:" + obj);

          
          
            //
          
          
                    } catch (Exception e) {

          
          
            //
          
          
                        e.printStackTrace();

          
          
            //
          
          
                    }

          
          
            //
          
          
                }
          
          
          
          
    @Test
    
          
            public
          
          
            void
          
           testNoTransactionMethod()
    {
        Map<String, Object> map = 
          
            new
          
           HashMap<String, Object>();
        map.put("username", "sharp");
        map.put("password", "sharp");
        map.put("enabled", 1);
        
        
          
            try
          
           {
            usersService.noTransactionMethod(map);
        } 
          
            catch
          
           (Exception e) {
            e.printStackTrace();
        }
    }
    

          
            //
          
          
                @Test

          
          
            //
          
          
                public void testUpdateUsers()

          
          
            //
          
          
                {

          
          
            //
          
          
                    Map<String, Object> map = new HashMap<String, Object>();

          
          
            //
          
          
                    map.put("username", "sharp");

          
          
            //
          
          
                    map.put("password", "sharp");

          
          
            //
          
          
                    map.put("enabled", 1);

          
          
            //
          
          
          
          
            //
          
          
                    try {

          
          
            //
          
          
                        usersService.updateUsers(map);

          
          
            //
          
          
                    } catch (Exception e) {

          
          
            //
          
          
                        e.printStackTrace();

          
          
            //
          
          
                    }

          
          
            //
          
          
                }
          
        

  運行測試類,控制臺打印出的異常是:

          
            2011
          
          -
          
            10
          
          -
          
            25
          
          
            23
          
          :
          
            28
          
          :
          
            00
          
            SQLErrorCodesFactory - SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
org.springframework.jdbc.BadSqlGrammarException: SqlMapClient operation; bad SQL grammar []; nested exception 
          
            is
          
           com.ibatis.common.jdbc.exception.NestedSQLException:   
--- The error occurred 
          
            in
          
           cn/com/sharpxiajun/dao/sqlmap/USERS.xml.  
--- The error occurred 
          
            while
          
           applying a parameter map.  
--- Check the USERS.updateUsers-InlineParameterMap.  
--- Check the statement (update failed).  
--- Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 
          
            '
          
          
            errinfo
          
          
            '
          
          
            in
          
          
            '
          
          
            field list
          
          
            '
          
          
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:
          
            233
          
          )
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:
          
            72
          
          )
    at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:
          
            203
          
          )
    at org.springframework.orm.ibatis.SqlMapClientTemplate.update(SqlMapClientTemplate.java:
          
            378
          
          )
    at cn.com.sharpxiajun.dao.impl.UsersDaoImpl.updateUsers(UsersDaoImpl.java:
          
            36
          
          )
    at cn.com.sharpxiajun.service.impl.UsersServiceImpl.noTransactionMethod(UsersServiceImpl.java:
          
            38
          
          )
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
          
            39
          
          )
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
          
            25
          
          )
    at java.lang.reflect.Method.invoke(Method.java:
          
            597
          
          )
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:
          
            309
          
          )
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:
          
            183
          
          )
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
          
            150
          
          )
    at cn.com.sharpxiajun.common.aop.MethodServiceAdvisor.invoke(MethodServiceAdvisor.java:
          
            31
          
          )
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
          
            172
          
          )
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:
          
            110
          
          )
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
          
            172
          
          )
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:
          
            89
          
          )
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:
          
            172
          
          )
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:
          
            202
          
          )
    at $Proxy18.noTransactionMethod(Unknown Source)
    at cn.com.sharpxiajun.junittest.service.UsersServiceImplTest.testNoTransactionMethod(UsersServiceImplTest.java:
          
            88
          
          )
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
          
            39
          
          )
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
          
            25
          
          )
    at java.lang.reflect.Method.invoke(Method.java:
          
            597
          
          )
    at org.junit.runners.model.FrameworkMethod$
          
            1
          
          .runReflectiveCall(FrameworkMethod.java:
          
            44
          
          )
    at org.junit.
          
            internal
          
          .runners.model.ReflectiveCallable.run(ReflectiveCallable.java:
          
            15
          
          )
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:
          
            41
          
          )
    at org.junit.
          
            internal
          
          .runners.statements.InvokeMethod.evaluate(InvokeMethod.java:
          
            20
          
          )
    at org.junit.
          
            internal
          
          .runners.statements.RunBefores.evaluate(RunBefores.java:
          
            28
          
          )
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:
          
            74
          
          )
    at org.junit.
          
            internal
          
          .runners.statements.RunAfters.evaluate(RunAfters.java:
          
            31
          
          )
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:
          
            82
          
          )
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:
          
            72
          
          )
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:
          
            240
          
          )
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:
          
            50
          
          )
    at org.junit.runners.ParentRunner$
          
            3
          
          .run(ParentRunner.java:
          
            193
          
          )
    at org.junit.runners.ParentRunner$
          
            1
          
          .schedule(ParentRunner.java:
          
            52
          
          )
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:
          
            191
          
          )
    at org.junit.runners.ParentRunner.access$
          
            000
          
          (ParentRunner.java:
          
            42
          
          )
    at org.junit.runners.ParentRunner$
          
            2
          
          .evaluate(ParentRunner.java:
          
            184
          
          )
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:
          
            61
          
          )
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:
          
            70
          
          )
    at org.junit.runners.ParentRunner.run(ParentRunner.java:
          
            236
          
          )
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:
          
            180
          
          )
    at org.eclipse.jdt.
          
            internal
          
          .junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:
          
            49
          
          )
    at org.eclipse.jdt.
          
            internal
          
          .junit.runner.TestExecution.run(TestExecution.java:
          
            38
          
          )
    at org.eclipse.jdt.
          
            internal
          
          .junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:
          
            467
          
          )
    at org.eclipse.jdt.
          
            internal
          
          .junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:
          
            683
          
          )
    at org.eclipse.jdt.
          
            internal
          
          .junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:
          
            390
          
          )
    at org.eclipse.jdt.
          
            internal
          
          .junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:
          
            197
          
          )
Caused by: com.ibatis.common.jdbc.exception.NestedSQLException:   
--- The error occurred 
          
            in
          
           cn/com/sharpxiajun/dao/sqlmap/USERS.xml.  
--- The error occurred 
          
            while
          
           applying a parameter map.  
--- Check the USERS.updateUsers-InlineParameterMap.  
--- Check the statement (update failed).  
--- Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 
          
            '
          
          
            errinfo
          
          
            '
          
          
            in
          
          
            '
          
          
            field list
          
          
            '
          
          
    at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeUpdate(MappedStatement.java:
          
            107
          
          )
    at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.update(SqlMapExecutorDelegate.java:
          
            457
          
          )
    at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.update(SqlMapSessionImpl.java:
          
            90
          
          )
    at org.springframework.orm.ibatis.SqlMapClientTemplate$
          
            9
          
          .doInSqlMapClient(SqlMapClientTemplate.java:
          
            380
          
          )
    at org.springframework.orm.ibatis.SqlMapClientTemplate$
          
            9
          
          .doInSqlMapClient(SqlMapClientTemplate.java:
          
            1
          
          )
    at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:
          
            200
          
          )
    ... 
          
            49
          
           more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 
          
            '
          
          
            errinfo
          
          
            '
          
          
            in
          
          
            '
          
          
            field list
          
          
            '
          
          
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:
          
            39
          
          )
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:
          
            27
          
          )
    at java.lang.reflect.Constructor.newInstance(Constructor.java:
          
            513
          
          )
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:
          
            406
          
          )
    at com.mysql.jdbc.Util.getInstance(Util.java:
          
            381
          
          )
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:
          
            1031
          
          )
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:
          
            957
          
          )
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:
          
            3376
          
          )
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:
          
            3308
          
          )
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:
          
            1837
          
          )
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:
          
            1961
          
          )
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:
          
            2543
          
          )
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:
          
            1737
          
          )
    at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:
          
            998
          
          )
    at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:
          
            169
          
          )
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
          
            39
          
          )
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
          
            25
          
          )
    at java.lang.reflect.Method.invoke(Method.java:
          
            597
          
          )
    at com.ibatis.common.jdbc.logging.PreparedStatementLogProxy.invoke(PreparedStatementLogProxy.java:
          
            62
          
          )
    at $Proxy21.execute(Unknown Source)
    at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeUpdate(SqlExecutor.java:
          
            80
          
          )
    at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.sqlExecuteUpdate(MappedStatement.java:
          
            216
          
          )
    at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeUpdate(MappedStatement.java:
          
            94
          
          )
    ... 
          
            54
          
           more
        

  我們發現這里面少了事務回滾的異常,數據庫查詢結果如下:

java筆記:自己動手寫javaEE框架(五)--Spring事務管理學習

  有記錄被新增了~~~

第六章 通過注解綁定事務管理

  聲明式事務咋看一下還是十分簡單的,但是Spring引入注解后還有更加簡單的配置,請看修改后新的applicationContext.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:context
          
          
            ="http://www.springframework.org/schema/context"
          
          
            
  xmlns:aop
          
          
            ="http://www.springframework.org/schema/aop"
          
          
            
  xmlns:tx
          
          
            ="http://www.springframework.org/schema/tx"
          
          
            
  xsi:schemaLocation
          
          
            ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
          
          
            >
          
          
            <!--
          
          
             掃描該路徑下的spring組件 
          
          
            -->
          
          
            <
          
          
            context:component-scan 
          
          
            base-package
          
          
            ="cn.com.sharpxiajun"
          
          
          
          
            />
          
          
            <!--
          
          
             讀取資源文件 
          
          
            -->
          
          
            <
          
          
            bean 
          
          
            id
          
          
            ="propertyConfigurer"
          
          
             class
          
          
            ="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
          
          
            >
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="locations"
          
          
            >
          
          
            <
          
          
            list
          
          
            >
          
          
            <
          
          
            value
          
          
            >
          
          classpath:conf/constants.properties
          
            </
          
          
            value
          
          
            >
          
          
            </
          
          
            list
          
          
            >
          
          
            </
          
          
            property
          
          
            >
          
          
            </
          
          
            bean
          
          
            >
          
          
            <!--
          
          
             配置數據源 
          
          
            -->
          
          
            <!--
          
          
              <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
             <property name="driverClass" value="${db.driverClass}"/>
             <property name="jdbcUrl" value="${db.jdbcUrl}"/>
             <property name="user" value="${db.user}"/>
             <property name="password" value="${db.password}"/>
         </bean>
          
          
            -->
          
          
            <
          
          
            bean 
          
          
            id
          
          
            ="myDataSource"
          
          
             class
          
          
            ="org.apache.commons.dbcp.BasicDataSource"
          
          
             destroy-method
          
          
            ="close"
          
          
            >
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="driverClassName"
          
          
             value
          
          
            ="${db.driverClass}"
          
          
            />
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="url"
          
          
             value
          
          
            ="${db.jdbcUrl}"
          
          
            />
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="username"
          
          
             value
          
          
            ="${db.user}"
          
          
            />
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="password"
          
          
             value
          
          
            ="${db.password}"
          
          
            />
          
          
            </
          
          
            bean
          
          
            >
          
          
            <
          
          
            bean 
          
          
            id
          
          
            ="sqlMapClient"
          
          
             class
          
          
            ="org.springframework.orm.ibatis.SqlMapClientFactoryBean"
          
          
            >
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="configLocation"
          
          
            >
          
          
            <
          
          
            value
          
          
            >
          
          classpath:conf/SqlMapConfig.xml
          
            </
          
          
            value
          
          
            >
          
          
            </
          
          
            property
          
          
            >
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="dataSource"
          
          
             ref
          
          
            ="myDataSource"
          
          
            />
          
          
            </
          
          
            bean
          
          
            >
          
          
            <
          
          
            bean 
          
          
            id
          
          
            ="sqlMapClientTemplate"
          
          
             class
          
          
            ="org.springframework.orm.ibatis.SqlMapClientTemplate"
          
          
            >
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="sqlMapClient"
          
          
            >
          
          
            <
          
          
            ref 
          
          
            local
          
          
            ="sqlMapClient"
          
          
            />
          
          
            </
          
          
            property
          
          
            >
          
          
            </
          
          
            bean
          
          
            >
          
          
            <
          
          
            bean 
          
          
            id
          
          
            ="transactionManager"
          
          
             class
          
          
            ="org.springframework.jdbc.datasource.DataSourceTransactionManager"
          
          
            >
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="dataSource"
          
          
            >
          
          
            <
          
          
            ref 
          
          
            local
          
          
            ="myDataSource"
          
          
            />
          
          
            </
          
          
            property
          
          
            >
          
          
            </
          
          
            bean
          
          
            >
          
          
            <!--
          
          
             聲明式事務 
          
          
            -->
          
          
            <!--
          
          
              <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="get*" read-only="true" propagation="REQUIRED"/>
                <tx:method name="query*" read-only="true" propagation="REQUIRED"/>
                <tx:method name="find*" read-only="true"  propagation="REQUIRED"/>
                <tx:method name="list*" read-only="true"  propagation="REQUIRED"/>
                <tx:method name="search*" read-only="true"  propagation="REQUIRED"/>
                <tx:method name="add*"  propagation="REQUIRED" isolation="READ_COMMITTED"/>
                <tx:method name="insert*"  propagation="REQUIRED" isolation="READ_COMMITTED"/>
                <tx:method name="del*"  propagation="REQUIRED" isolation="READ_COMMITTED"/>
                <tx:method name="save*"  propagation="REQUIRED" isolation="READ_COMMITTED"/>
                <tx:method name="update*"  propagation="REQUIRED" isolation="READ_COMMITTED"/>
                <tx:method name="modify*"  propagation="REQUIRED" isolation="READ_COMMITTED"/>
            </tx:attributes>
        </tx:advice>
          
          
            -->
          
          
            <
          
          
            bean 
          
          
            id
          
          
            ="transactionTemplate"
          
          
             class
          
          
            ="org.springframework.transaction.support.TransactionTemplate"
          
          
            >
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="transactionManager"
          
          
            >
          
          
            <
          
          
            ref 
          
          
            bean
          
          
            ="transactionManager"
          
          
            />
          
          
            </
          
          
            property
          
          
            >
          
          
            <
          
          
            property 
          
          
            name
          
          
            ="propagationBehaviorName"
          
          
            >
          
          
            <
          
          
            value
          
          
            >
          
          PROPAGATION_REQUIRED
          
            </
          
          
            value
          
          
            >
          
          
            </
          
          
            property
          
          
            >
          
          
            </
          
          
            bean
          
          
            >
          
          
            <!--
          
          
             將我自己定義的攔截器生成bean 
          
          
            -->
          
          
            <
          
          
            bean 
          
          
            id
          
          
            ="methodServiceAdvisor"
          
          
             class
          
          
            ="cn.com.sharpxiajun.common.aop.MethodServiceAdvisor"
          
          
            />
          
          
            <
          
          
            aop:config
          
          
            >
          
          
            <!--
          
          
            配置規則,滿足以下規則的將攔截,第一個*表示所有返回類型,第二個表示service包下的所有class,第三個表示所有方法
          
          
            -->
          
          
            <
          
          
            aop:pointcut 
          
          
            id
          
          
            ="baseServiceMethods"
          
          
             expression
          
          
            ="execution(* cn.com.sharpxiajun.service.*.*(..))"
          
          
            />
          
          
            <!--
          
          
             聲明式事務 
          
          
            -->
          
          
            <!--
          
          
              <aop:advisor advice-ref="txAdvice" pointcut-ref="baseServiceMethods" />
          
          
            -->
          
          
            <!--
          
          
             符合上面規則的攔截器都會調用到methodServiceAdvisor 
          
          
            -->
          
          
            <
          
          
            aop:advisor 
          
          
            advice-ref
          
          
            ="methodServiceAdvisor"
          
          
             pointcut-ref
          
          
            ="baseServiceMethods"
          
          
            />
          
          
            </
          
          
            aop:config
          
          
            >
          
          
            <
          
          
            tx:annotation-driven 
          
          
            transaction-manager
          
          
            ="transactionManager"
          
          
            />
          
          
            </
          
          
            beans
          
          
            >
          
        

  配置文件里我把原來的聲明式配置內容注釋掉了,然后加入了<tx:annotation-driven transaction-manager="transactionManager"/>。

  然后在cn.com.sharpxiajun.service.impl包下的UsersServiceImpl類加入@Transactional注解,代碼如下:

          @SuppressWarnings("unchecked")
@Scope("prototype")
@Transactional
@Service("userService")

          
            public
          
          
            class
          
           UsersServiceImpl 
          
            implements
          
           UsersService {
......................................................
        

  將數據庫里的數據都清除掉,運行測試類UsersServiceImplTest,測試service下的noTransactionMethod方法和updateUsers方法,結果顯示數據都沒有新增成功,這就說明事務綁定是成功了,這個簡單吧。

  總結下了:事務很重要,我希望我這兩篇博客能給童鞋們一點幫助。

  下一篇文章將把struts2框架引入到我寫的框架。

java筆記:自己動手寫javaEE框架(五)--Spring事務管理學習


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 色啦啦影院 | 一级无毛 | 99视频九九精品视频在线观看 | 久久综合草 | 一级视频片 | 酒色网站| 亚洲成人免费观看 | 亚洲综合伦理 | 99re热这里只有精品视频 | 99热这里只有精品7 99热这里只有精品8 | 激情五月社区 | 亚洲国产成a人v在线 | 国产在线激情 | 欧美中文字幕在线 | 午夜国产精品久久久久 | 涩涩视频免费观看 | 国产精品9999久久久久仙踪林 | 香蕉网站在线观看影院 | 国产成人综合95精品视频免费 | 亚洲国产欧美日韩 | 干美女在线视频 | 一级做a爱片特黄在线观看 一级做a爱片特黄在线观看免费看 | 国产成人久久精品二区三区牛 | 七次郎在线视频精品视频 | 超91视频| 久久视频一区 | 114一级毛片免费 | 久久精品男人的天堂 | 人人爽影院 | 国产在线精品一区二区三区 | 狠狠躁天天躁夜夜躁婷婷 | 亚洲精国产一区二区三区 | 国产免费不卡视频 | 国产福利视频 | 天天操夜夜夜 | 狠狠色综合久久婷婷色天使 | 日日摸夜夜摸狠狠摸日日碰夜夜做 | 91av国产精品| 九九热思思 | 久久青草91免费观看 | 亚洲国产欧洲精品路线久久 |