美文网首页Spring
Spring ( 第三讲 ) 转账案例

Spring ( 第三讲 ) 转账案例

作者: superNeil | 来源:发表于2020-06-06 08:26 被阅读0次
    搞笑.jpeg
    WHAT ?

    我们先来说说 , 什么是正确的转账 . 单纯的sql 语句是不能实现事务处理的 , 需要加上事务处理才能保证转账的成功和失败 .

    WHY ?

    为什么这么说呢 ? 如果 转账过程中出现错误或者中止程序 , 难不成钱还要继续转过去吗 ? 这时应该出现 事务回滚才是 .

    那么 , 我们接下来就来 看看转账案例 !

    首先我们来分析一下 , 要怎么去实现 ? ( 做什么事都要做好准备 ! )

    思路分析 :

    1. 明需求 -->2. 建项目 -->3.备好 需要 添加的依赖和插件 -->4.类设计 -->5.编写Mapper接口 和 Mapper.xml -->6.编写测试类

    废话不多说 , 那我们开始吧 !

    添加 依赖和插件 |||

    <dependencies> <!-- 数据库驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.45</version>
                <scope>runtime</scope>
            </dependency> <!-- 数据库连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.9</version>
            </dependency> <!-- MyBatis 相关 -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.4.5</version>
            </dependency> <!-- Spring 集成 MyBatis 的依赖 -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>1.3.1</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.7.25</version>
            </dependency> <!-- Spring 相关 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>5.0.8.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.8.13</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>5.0.8.RELEASE</version>
            </dependency> <!-- 测试相关 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>5.0.8.RELEASE</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency> <!-- web 项目共用 -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.16.22</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.0.1</version>
                <scope>provided</scope>
            </dependency> <!-- 页面标签 -->
            <dependency>
                <groupId>org.apache.taglibs</groupId>
                <artifactId>taglibs-standard-spec</artifactId>
                <version>1.2.5</version>
            </dependency>
            <dependency>
                <groupId>org.apache.taglibs</groupId>
                <artifactId>taglibs-standard-impl</artifactId>
                <version>1.2.5</version>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.1</version>
                    <configuration>
                        <port>8080</port> <!-- 端口 -->
                        <path>/</path> <!-- 上下路径 -->
                        <uriEncoding>UTF-8</uriEncoding> <!-- 针对 GET 方式乱码处理 -->
                    </configuration>
                </plugin>
            </plugins>
        </build>
    

    准备好数据库 |||

    这是一张 账户模拟表

    CREATE TABLE `account` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `balance` decimal(10,2) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    编写实体类 |||

    @Getter
    @Setter
    public class Account {
        private Long id;
        private BigDecimal balance;
    }
    

    编写Mapper接口 和 Mapper.xml

    public interface AccountMapper {
        //加钱
        void addBalance(@Param("inId") Long inId, @Param("amount") BigDecimal amount);
        
        //减钱
        void subtractBalance(@Param("oldId") Long oldId, @Param("amount") BigDecimal amount);
    }
    
    <mapper namespace="cn.wolfcode.mapper.AccountMapper">
        <update id="addBalance">
            update account SET balance=balance + #{amount} where id=#{inId}
        </update>
    
        <update id="subtractBalance">
            update account SET balance=balance - #{amount} where id=#{oldId}
        </update>
    </mapper>
    

    到了这里 , 我们要写 service 要写impl 了吗 ? ( 必须看完这段 , 否则你都不知 why ? )

    我们要 用到 MyBatis 框架 的 sqlSessionFactory , 而且我们只需要一个 , 那么我们把 创建sqlSessionFactory就交给Spring 管理好了 . 那么 问题 又来了, 创建 sqlSessionFactory 又需要什么? 数据源 datasource . 那我们就先创建好 datasource , 然后在datasource的基础上 创建sqlSessionFactory .

    这里 我们可以关联 db.properties 文件

     <!--配置 db.properties-->
        <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
    
        <!--配置 DataSource-->
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
            <property name="driverClassName" value="${jdbc.driver}"></property>
            <property name="url" value="${jdbc.url}"></property>
            <property name="username" value="${jdbc.username}"></property>
            <property name="password" value="${jdbc.password}"></property>
        </bean>
    
        <!--配置sqlSessionFactory-->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <!--数据源-->
            <property name="dataSource" ref="dataSource"></property>
            <!--配置别名-->
            <property name="typeAliasesPackage" value="cn.wolfcode.domain"></property>
    
        </bean>
    
        <!--*****************************************************************************************-->
        <!--配置 AccountMapper接口-->
        <!--<bean id="accountMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">-->
        <!--&lt;!&ndash;借 sqlSessionFactory 来创建&ndash;&gt;-->
        <!--<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>-->
        <!--&lt;!&ndash;具体创建 什么接口类型的代理对象&ndash;&gt;-->
        <!--<property name="mapperInterface" value="cn.wolfcode.mapper.AccountMapper"></property>-->
        <!--</bean>-->
        <!--*****************************************************************************************-->
        <!--批量创建 Mapper 接口-->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="cn.wolfcode.mapper"></property>
        </bean>
        <context:component-scan base-package="cn.wolfcode.service.impl"/>
    

    service

    public interface IAccountService {
        //转账方法
        void transfer(Long oldId, Long inId, BigDecimal amount);
    }
    
    @Service
    @Transactional//事务注解
    public class AccountServiceImpl implements IAccountService {
        @Autowired
        private AccountMapper accountMapper;
    
        public void setAccountMapper(AccountMapper accountMapper) {
            this.accountMapper = accountMapper;
        }
    
    
        @Override
        public void transfer(Long oldId, Long inId, BigDecimal amount) {
            accountMapper.addBalance(oldId, amount);
            //int i=1/0;
            accountMapper.subtractBalance(inId, amount);
        }
    
        @Override
        public void delete(Long id) {
            accountMapper.delete(id);
        }
    }
    

    使用注解配置事务

    @Service
    @Transactional//事务注解
    public class AccountServiceImpl implements IAccountService {
        @Autowired
        private AccountMapper accountMapper;
    
        public void setAccountMapper(AccountMapper accountMapper) {
            this.accountMapper = accountMapper;
        }
    
    
        @Override
        public void transfer(Long oldId, Long inId, BigDecimal amount) {
            accountMapper.addBalance(oldId, amount);
            //int i=1/0;
            accountMapper.subtractBalance(inId, amount);
        }
    
        @Override
        public void delete(Long id) {
            accountMapper.delete(id);
        }
    }
    

    配置事务管理器

    <!--配置事务管理器-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
        </bean>
        <!--配置事务解析器-->
        <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
    

    相关文章

      网友评论

        本文标题:Spring ( 第三讲 ) 转账案例

        本文链接:https://www.haomeiwen.com/subject/knxazhtx.html