spring boot + mybatis 模擬銀行系統余額查詢、轉賬、存取錢功能實現


實現銀行系統的余額查詢在我們之前寫的token認證登陸功能完成的基礎上實現,token認證登陸功能代碼地址:https://github.com/yeyuting-1314/selectFuPan_tokenAndRedisfengzhuagn.git

銀行系統余額查詢、轉賬、入賬、出賬功能項目代碼地址:https://github.com/yeyuting-1314/tokenLogin1.0.git

一、准備工作

新建一個數據庫,數據庫名字是tokenLogin,數據庫內新建兩張表,第一張是用戶賬戶信息表,第二張是轉賬、入賬、出賬記錄表,分別如下所示:

1. sys_user用戶賬戶信息表:

CREATE TABLE tokenLogin.sys_user(
    `id` bigint NOT NULL comment 'ID ',
    `username` varchar(50) comment '用戶名',
    `password` varchar(50) comment '密碼',
    PRIMARY KEY (`id`)
);


insert into tokenLogin.sys_user values('1' , 'admmin' , '1')
insert into tokenLogin.sys_user values('2' , 'superadmmin' , '11')
insert into tokenLogin.sys_user values('3' , 'user' , '111')

alter table tokenLogin.sys_user add column account double default null;

接着對account進行賦值,賦值完成后表內容如下:

 2. 轉賬記錄表:

CREATE TABLE tokenLogin.trasf_record(
    `id` int NOT NULL AUTO_INCREMENT, 
    `username` varchar(50) default null,
    `account_time` TIMESTAMP DEFAULT now() , /*交易時間,默認是幾率生成的時間,也就是交易操作完成的時間*/
    `old_account` double default null, /*原賬戶的余額*/
    `new_account` double default null, /*交易后賬戶最新余額*/
    `target_account` varchar(50) default null ,  /*交易對方賬戶*/
    `account_type` varchar(50) default null , /*交易類型*/
    PRIMARY KEY (`id`)
);


alter table tokenLogin.trasf_record add column transaction_amount double default null after old_account ; /*在原賬戶余額和交易后賬戶余額中間插入交易余額*/

創建一張空表即可,后面產生交易的時候將數據插入,實現資金追溯。

 3. 常量設置:在轉賬記錄表中,有一個字段account_type , 這個字段無非有兩個結果,要么是入賬類型,要么是出賬類型,所以這里我們進行常量設置。

在constants包下面新建TransactionType類,類下內容如下:

/**
 * @author yeyuting
 * @create 2021/2/18
 */
public class   TransactionType {
    public static final String SAVEMONEY = "入賬" ;
    public static final String WITHDRAWMONEY = "出賬" ;
}

這樣一來,准備工作就做好了,現在我們依次來實現賬戶余額查詢、轉賬、入賬和出賬記錄。

二、賬戶余額查詢

1. 首先控制層創建余額查詢接口:

 @GetMapping("/selectByUserName")
    public Result selectByUserName(@RequestParam("userName") String username){
        return Results.successWithData(userService.selectByUserName(username) , BaseEnums.SUCCESS.code()) ;
    }

2. service層進行數據傳遞:

//UserService類:
public User selectByUserName(String username)  ; 

//UserServiceImpl類:
//查詢金額
    public User selectByUserName(String username) {
        return userMapper.selectByUserName(username) ;
    }

3. mapper層,將參數進行傳遞並和數據庫打交道:

UserMapper.java:

public User selectByUserName(String username) ;

userMapper.xml:

<!--查詢金額-->
    <select id="selectByUserName" resultType="User">
        select * from sys_user where username = #{userName}
    </select>

4. 進行登陸操作,訪問LoginCheck接口,生成對應的token,將token塞到余額查詢接口的頭信息中,過攔截器,進而順利執行接口代碼邏輯。

 

 

4. postman前端模擬:

 這樣一來,最簡單的賬戶余額查詢就實現了。

三、轉賬功能實現:

1. controller層創建轉賬接口:

 @PostMapping("/transferAccount")
    public Result transferAccount (@RequestParam("accountMoney") Double accountMoney ,
                                   @RequestParam("targetAccount") String targetAccount , HttpServletRequest request){
        return Results.successWithData(userService.transferAccount(accountMoney , targetAccount , request) , BaseEnums.SUCCESS.code()) ;

    }

2. service層實現:

service接口:

//轉賬
    public String  transferAccount(Double accountMoney , String targetAccount , HttpServletRequest request) ;

serviceImpl實現:

 //轉賬
    public String transferAccount(Double accountMoney , String targetAccount , HttpServletRequest request){
        Jedis jedis = jedisUtil.getSource() ;
        String token = request.getHeader("token") ;
        String userName = jedis.get(token) ;
        User user = userMapper.selectByName(userName) ;
        double nowAccountMoney = user.getAccount() ;
        if(accountMoney > nowAccountMoney){
            return "余額不足" ;
        }
        User user1 = userMapper.selectByName(targetAccount) ;
        if (user1.equals(null)){
            return "對方賬戶不存在" ;
        }
        //轉出賬戶余額更新
        boolean result = userMapper.updateAccountOut(accountMoney , userName) ;
        //轉入賬戶余額更新
        boolean result1 = userMapper.updateAccountIn(accountMoney , user1.getUserName()) ;
        if ((result == false)||(result1 == false) ){
            return "轉賬操作失敗" ;
        }
        //轉賬記錄生成------------
        //String accountType = TransactionType.WITHDRAWMONEY ;
        //出賬記錄生成
        boolean insertReult = userMapper.accountOutInsert(userName ,user.getAccount() ,  accountMoney , targetAccount , TransactionType.WITHDRAWMONEY ) ;
        //入賬記錄生成
        //String accountType1 = TransactionType.SAVEMONEY ;
        boolean insertReult1 = userMapper.accountInInsert(user1.getUserName() , user1.getAccount() , accountMoney , user.getUserName() , TransactionType.SAVEMONEY ) ;

        if((insertReult == false) || (insertReult1 == false)){
            return "轉賬記錄生成失敗" ;
        }

        return "轉賬成功!" ;
    }

service實現中每一行代碼都有詳細的講解,總的來說,就是要實現出賬方賬戶余額相應減少,入賬方賬戶余額相應增加,同時生成對應的轉賬記錄。

3. mapper層實現:

//轉出更新
    public boolean updateAccountOut (Double accountMoney , String userName) ;
    //轉入更新
    public boolean updateAccountIn (Double accountMoney , String userName) ;

    //轉出記錄插入
    public boolean accountOutInsert(String userName ,Double account , Double accountMoney , String targetAccount , String accountType) ;

    //轉入記錄插入
    public boolean accountInInsert(String userName ,Double account , Double accountMoney , String targetAccount , String accountType) ;
<update id="updateAccountOut">
        update sys_user set account = (account - #{accountMoney}) where username = #{userName}
    </update>

    <update id="updateAccountIn">
        update sys_user set account = (account + #{accountMoney}) where username = #{userName}
    </update>

    <insert id="accountOutInsert">
        insert into trasf_record
        ( username , old_account ,transaction_amount , new_account , target_account , account_type )
        values
        ( #{userName} ,#{account} , #{accountMoney} , (#{account} - #{accountMoney}) , #{targetAccount} , #{accountType})
    </insert>

    <insert id="accountInInsert">
        insert into trasf_record
        (username , old_account ,transaction_amount , new_account , target_account , account_type )
        values
        (#{userName} ,#{account} , #{accountMoney} , (#{account} + #{accountMoney}) , #{targetAccount} , #{accountType})
    </insert>

4. postman前端模擬:

 將上面生成的token塞到轉賬接口頭信息中,訪問數據庫:

 

 數據庫信息刷新:

 

 

 這樣一來,轉賬功能也就實現了,在充分理解了轉賬功能后,入賬出賬功能就迎刃而解了。接下來繼續實現賬戶入賬和出賬功能。

四、入賬功能

 1. controller層:

//存錢
    @PostMapping("/saveMoney")
    public Result saveMoney (@RequestParam("accountMoney") Double accountMoney , HttpServletRequest request){
        return  Results.successWithData(userService.saveMoney(accountMoney , request) , BaseEnums.SUCCESS.code()) ;
    }

2. service層:

service接口:

 //存錢
    public String saveMoney(Double accountMoney , HttpServletRequest request) ;

serviceImpl實現:

//存錢
    public String saveMoney(Double accountMoney , HttpServletRequest request){
        Jedis jedis = jedisUtil.getSource() ;
        String token = request.getHeader("token") ;
        String userName = jedis.get(token) ;
        User user = userMapper.selectByName(userName) ;
        //存入余額更新
        boolean result = userMapper.updateAccountIn(accountMoney , userName) ;
        if(result = false){
            return "存入失敗" ;
        }
        //存入記錄生成
        boolean insertResult = userMapper.accountInInsert(userName ,user.getAccount() , accountMoney , userName , TransactionType.SAVEMONEY) ;
        if((insertResult == false)){
            return "入賬記錄生成失敗" ;
        }
        return "成功存入" + accountMoney + "元!"  ;
    }

3. mapper層和轉賬公用一套代碼。

4. postman前端實現:

和轉賬一樣,要記得將token塞進頭信息中。

 

 執行后結果如下:

 

 數據庫刷新結果如下:

 

 

 

 五、出賬功能

1. controller層:

//取錢
    @PostMapping("withdrawMoney")
    public Result withdrawMoney (@RequestParam("accountMoney") Double accountMoney , HttpServletRequest request){
        return  Results.successWithData(userService.withdrawMoney(accountMoney , request) , BaseEnums.SUCCESS.code()) ;
    }

2. service層:

service接口:

//取錢
    public String withdrawMoney(Double accountMoney , HttpServletRequest request) ;

serviceImpl具體實現:

//取錢
    public String withdrawMoney(Double accountMoney , HttpServletRequest request){
        Jedis jedis = jedisUtil.getSource() ;
        String token = request.getHeader("token") ;
        String userName = jedis.get(token) ;
        User user = userMapper.selectByName(userName) ;
        double nowAccountMoney = user.getAccount() ;
        if(accountMoney > nowAccountMoney){
            return "余額不足" ;
        }
        boolean result = userMapper.updateAccountOut(accountMoney , userName) ;
        if(result = false){
            return "取錢失敗" ;
        }
        //出賬記錄生成
        boolean insertResult = userMapper.accountOutInsert(userName ,user.getAccount() , accountMoney , userName , TransactionType.WITHDRAWMONEY) ;
        if((insertResult == false)){
            return "出賬記錄生成失敗" ;
        }
        return "成功取出" + accountMoney + "元!"  ;
    }

3. mapper層和轉賬公用一套代碼。

4. postman前端實現:

和轉賬一樣,要記得將token塞進頭信息中。

 

 

 

 

 這樣一來,出賬功能也就實現了。

待解決問題:

1. redis暫未實現redis緩存對象,因此每次訪問redis只是為了拿到token和對應的value,並未真正的利用到redis,因此,后期要將對象完整的存入到redis中,便於后期數據的獲取。

2. 這里的轉賬記錄表還可以做成索引表,每個用戶單列一張表出來,更加的淺顯易懂,但是任務量過大,需商榷后再決定是否將整表分開。

至此,結束。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM