美文网首页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 ( 第三讲 ) 转账案例

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

  • Spring(三)事务

    Spring 事务 案例 转账案例 IAccountDao 接口 AccountDaoImpl 实现类 IAcco...

  • Spring(二):AOP 面向切面编程

    转账案例 需求:使用 spring 框架整合 DBUtils 技术,实现用户转账功能 基础功能 步骤分析: 创建 ...

  • JDBC(四)事务管理

    1.银行转账案例 案例:银行转账:从张无忌账户上给赵敏转1000块钱.准备:account(账户表): 转账操作步...

  • Spring事务管理---转账案例搭建

    上一篇文章总结了Spring事务管理的相关知识点。接下来写一个模拟银行转账的案例来实际操作一下。 一、转账环境搭建...

  • Spring(5)-(20)事务相关之转账案例

    一.代码演示,引出事务的概念 (1)Accout类 (2)IAccoutDAO接口 (3)IAccoutDAO实现...

  • 小案例-转账

    转账 1.1 搭建环境 创建表 1.2.1 Dao层 1.2.2 service层 1.2.3 spring配置文...

  • Spring -- 手写 IOC 和 AOP

    一、银行转账案例 先使用原始 servlet 方式模拟一个银行转账的功能,关键代码如下: TransferServ...

  • 07.银行转账案例

    2.案例中添加转账方法并演示事务问题新建一个工程,仍然复制以前的代码在这个新工程中,现在是一个银行转账案例,需要添...

  • SpringBootSamples

    spring boot 学习案例

网友评论

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

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