mybatis web使用02

news2024/9/30 3:23:08

 处理 transfer 请求的 servlet

package com.wsd.web;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @description:
 * @author: Mr.Wang
 * @create: 2023-07-02 00:52
 **/
@WebServlet("transfer")
public class AccountServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取页面表单数据
        String fromActno = req.getParameter("fromActno");
        String toActno = req.getParameter("toActno");
        Double money = Double.parseDouble( req.getParameter("money") ) ;
        //调用service


    }
}

AccountService interface: 

package com.wsd.service;

public interface AccountService {

    
    void transfer(String fromActno, String toActno, double money);
}

dao interface 

package com.wsd.dao;

import com.wsd.pojo.Account;

/**
 * @author: Mr.Wang
 * @create: 2023-07-02 01:30
 **/
public interface AccountDao {

    /**
     * 根据账号获取账户信息
     * @param actno 账号
     * @return 账户信息
     */
    Account selectByActno(String actno);

    /**
     * 更新账户信息
     * @param act 账户信息
     * @return 1表示更新成功,其他值表示失败
     */
    int update(Account act);
}

实现类: 

package com.wsd.dao.impl;

import com.wsd.dao.AccountDao;
import com.wsd.pojo.Account;
import com.wsd.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;

/**
 * @author: Mr.Wang
 * @create: 2023-07-02 01:36
 **/
public class AccountDaoImpl implements AccountDao {


    @Override
    public Account selectByActno(String actno) {
        //Get a SqlSession instance
        SqlSession sqlSession = SqlSessionUtil.openSession();
        //执行 selectByActno
        Account act = (Account)sqlSession.selectOne("selectByActno", actno);
        sqlSession.close();
        return act;
    }

    @Override
    public int update(Account act) {
        //Get a SqlSession instance
        SqlSession sqlSession = SqlSessionUtil.openSession();
        //执行 update
        int count = sqlSession.update("update", act);
        sqlSession.commit();
        sqlSession.close();
        return count;
    }
}

AccountMapper.xml: 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="account">
    <select id="selectByActno" resultType="com.wsd.pojo.Account">
        select * from t_act where actno = #{actno}
    </select>
    <update id="update">
        update t_act set balance = #{balance} where actno = #{actno}
    </update>
</mapper>

定义 MoneyNotEnoughExcecption 

转账操作时,余额不足的情况下使用

package com.wsd.exception;

/**
 * @author: Mr.Wang
 * @create: 2023-07-02 09:06
 **/
public class MoneyNotEnoughExcecption extends Exception{
    public MoneyNotEnoughExcecption() {
    }

    public MoneyNotEnoughExcecption(String message) {
        super(message);
    }
}

修改接口,抛出异常 

package com.wsd.service;

public interface AccountService {


    void transfer(String fromActno, String toActno, double money) throws Exception;
}

操作数据库失败时使用的异常 

package com.wsd.exception;

/**
 * @author: Mr.Wang
 * @create: 2023-07-02 11:57
 **/
public class AppException extends Exception {

    public AppException() {
    }

    public AppException(String message) {
        super(message);
    }
}

service 实现类 

package com.wsd.service.impl;

import com.wsd.dao.AccountDao;
import com.wsd.dao.impl.AccountDaoImpl;
import com.wsd.exception.AppException;
import com.wsd.exception.MoneyNotEnoughException;
import com.wsd.pojo.Account;
import com.wsd.service.AccountService;

/**
 * @author: Mr.Wang
 * @create: 2023-07-02 01:19
 **/
public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao = new AccountDaoImpl();

    @Override
    public void transfer(String fromActno, String toActno, double money) throws MoneyNotEnoughException,AppException{
        // 查询转出账户的余额
        Account fromAct = accountDao.selectByActno(fromActno);
        //余额不足,抛出异常
        if (fromAct.getBalance() < money) {
            throw new MoneyNotEnoughException("对不起,您的余额不足。");
        }

        // 程序如果执行到这里说明余额充足
        // 修改账户余额
        Account toAct = accountDao.selectByActno(toActno);
        fromAct.setBalance(fromAct.getBalance() - money);
        toAct.setBalance(toAct.getBalance() + money);
        // 更新数据库
        int count = accountDao.update(fromAct);
        count += accountDao.update(toAct);
        if (count != 2) {
            throw new AppException("转账失败,未知原因!");
        }
    }
}

修改接口抛出的异常:

package com.wsd.service;

import com.wsd.exception.AppException;
import com.wsd.exception.MoneyNotEnoughException;

public interface AccountService {


    void transfer(String fromActno, String toActno, double money) throws MoneyNotEnoughException, AppException;
}

继续实现servlet:

package com.wsd.web;

import com.wsd.exception.AppException;
import com.wsd.exception.MoneyNotEnoughException;
import com.wsd.service.AccountService;
import com.wsd.service.impl.AccountServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @description:
 * @author: Mr.Wang
 * @create: 2023-07-02 00:52
 **/
@WebServlet("/transfer")
public class AccountServlet extends HttpServlet {

    private AccountService accountService = new AccountServiceImpl();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取页面表单数据
        String fromActno = req.getParameter("fromActno");
        String toActno = req.getParameter("toActno");
        Double money = Double.parseDouble( req.getParameter("money") ) ;
        //调用service
        try {
            accountService.transfer(fromActno,toActno,money);
            //Show the result after transfer success
            resp.sendRedirect(req.getContextPath()  + "/success.html");
        } catch (MoneyNotEnoughException e) {
            resp.sendRedirect(req.getContextPath()  + "/error1.html");
        } catch (AppException e) {
            resp.sendRedirect(req.getContextPath() + "/error2.html");
        }

    }
}

error1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>transfer result</title>
</head>
<body>
<h1>The transfer failed because of insufficient balance</h1>
</body>
</html>

error2.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>transfer result</title>
</head>
<body>
<h1>The transfer failed, error occurred</h1>
</body>
</html>

success.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>transfer result</title>
</head>
<body>
<h1>The transfer success</h1>
</body>
</html>

运行: 

tomcat 乱码 

tomcat的/conf/logging.properties 

 Restart server

或则 修改idea 控制台的 编码方式为 utf-8,使与tomcat log 使用的 编码方式保持一致

在IDEA里修改idea64.exe.vmoptions

菜单Help -> Edit Custom VM Options,在末尾增加如下代码,重启 idea

-Dfile.encoding=UTF-8

 test:

模拟异常

package com.wsd.service.impl;

import com.wsd.dao.AccountDao;
import com.wsd.dao.impl.AccountDaoImpl;
import com.wsd.exception.AppException;
import com.wsd.exception.MoneyNotEnoughException;
import com.wsd.pojo.Account;
import com.wsd.service.AccountService;

/**
 * @author: Mr.Wang
 * @create: 2023-07-02 01:19
 **/
public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao = new AccountDaoImpl();

    @Override
    public void transfer(String fromActno, String toActno, double money) throws MoneyNotEnoughException,AppException{
        // 查询转出账户的余额
        Account fromAct = accountDao.selectByActno(fromActno);
        //余额不足,抛出异常
        if (fromAct.getBalance() < money) {
            throw new MoneyNotEnoughException("对不起,您的余额不足。");
        }

        // 程序如果执行到这里说明余额充足
        // 修改账户余额
        Account toAct = accountDao.selectByActno(toActno);
        fromAct.setBalance(fromAct.getBalance() - money);
        toAct.setBalance(toAct.getBalance() + money);
        // 更新数据库
        int count = accountDao.update(fromAct);
        
        //模拟异常
        String s = null;
        s.toString();
        
        count += accountDao.update(toAct);
        if (count != 2) {
            throw new AppException("转账失败,未知原因!");
        }
    }
}

 retest :

before test

 

出现异常

 

 

 

after test:

数据不一致

reason:

public void transfer(String fromActno, String toActno, double money) throws MoneyNotEnoughException,AppException{
        // 查询转出账户的余额
        Account fromAct = accountDao.selectByActno(fromActno);
        //余额不足,抛出异常
        if (fromAct.getBalance() < money) {
            throw new MoneyNotEnoughException("对不起,您的余额不足。");
        }

        // 程序如果执行到这里说明余额充足
        // 修改账户余额
        Account toAct = accountDao.selectByActno(toActno);
        fromAct.setBalance(fromAct.getBalance() - money);
        toAct.setBalance(toAct.getBalance() + money);
        // 更新数据库
        int count = accountDao.update(fromAct);

        //模拟异常
        String s = null;
        s.toString();

        count += accountDao.update(toAct);
        if (count != 2) {
            throw new AppException("转账失败,未知原因!");
        }
    }

 1.更新 table

2.模拟异常

3.更新table

2 出现异常后,3没有执行

1.3 没有形成一个事务

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/711400.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GAMES101 笔记 Lecture08 Shading 2(Shading, Pipeline and Texture Mapping)

目录 Specular Term(高光项)Ambient Term(环境光照项)Blinn-Phong Reflection ModelShading Frequencies(着色频率)Shade each triangle(flat shading)在每个三角形上进行着色Shade each vertex (Gouraud shading)(顶点着色)Shade each pixel (Phong shading)Defining Per-Vert…

【C++详解】——哈希

目录 unordered系列关联式容器 unordered_map unordered_map的接口说明 1.unordered_map的构造 2.unordered_map的容量 3.迭代器相关 4.unordered_map的元素访问 5. unordered_map的查询 6.unordered_map的修改操作 unordered_set 性能测试 底层结构——Hash 哈希…

copula简介

二元正态copula最为重要

MySQL - 自连接查询

1. 测试数据 创建 category 表 : CREATE TABLE category(categoryid INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 主题id,pid INT(10) NOT NULL COMMENT 父id,categoryName VARCHAR(50) NOT NULL COMMENT 主题名字,PRIMARY KEY(categoryid) ) ENGINEINNODB AUTO_INCREM…

cmd的学习

目录 常用的cmd命令 使用cmd的例子 常用的cmd命令 指令作用盘符名称:盘符切换dir查看当前路径下的内容tree以树形结构输出当前路径下的内容cd进入单级目录cd ..回退到上一级目录cd 目录1\目录2\...进入多级目录cd \回退到盘符目录cls清屏exit退出窗口 &#xff08;值得注意的…

Android AlertDialog setView,kotlin

Android AlertDialog setView&#xff0c;kotlin <?xml version"1.0" encoding"utf-8"?> <com.google.android.material.textfield.TextInputLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width…

MySQL数据库——主从复制和读写分离

MySQL数据库——主从复制和读写分离 一、主从复制和读写分离的相关知识1.什么是读写分离&#xff1f;2.为什么要读写分离呢&#xff1f;3.什么时候要读写分离&#xff1f;4.主从复制与读写分离5.mysql支持的复制类型6.主从复制的工作过程7.MySQL 读写分离原理8.目前较为常见的 …

前端实现俄罗斯方块游戏(内含源码)

目录 一、前言 二、功能介绍 三、页面搭建 四、样式设置 五、逻辑部分 一、前言 今天带领大家完成俄罗斯方块游戏&#xff0c;功能也比较简单&#xff0c;也是想借助这样一个简单的功能&#xff0c;然后来帮助大家了解我们JavaScript在前端中的作用&#xff0c; 后续也会带…

【服务器】ASP.Net Core(C#)创建Web站点

简单几步实现本地ASP.Net.Core web 站点结合cpolar内网穿透工具实现远程访问 1. 创建站点 *环境搭建,这边测试,使用.NET 6.0 SDK,可以点击跳转到官网下载,下载后安装即可. 安装完成后,进入到某个文件夹,打开powershell执行下面命令,创建新的 Web 应用,名称叫:aspnetcoreapp …

机器学习 day22(ReLU激活函数)

ReLU激活函数 如果想让a取更大的非负数&#xff0c;激活函数g(z)可以选用ReLU激活函数&#xff0c;他在z&#xff1c;0时取0&#xff0c;在z ≥ 0时取z 常见的激活函数 左侧的为线性激活函数&#xff0c;因为f(x) wxb&#xff0c;使用激活函数后f(x) g(z)&#xff0c;此…

综合评价算法 | Matlab实现基于TOPSIS法的综合评价算法

文章目录 效果一览文章概述研究内容源码设计参考资料效果一览 文章概述 综合评价算法 | Matlab实现基于TOPSIS法的综合评价算法 研究内容 C.L.Hwang 和 K.Yoon 于1981年首次提出 TOPSIS (Technique for Order Preference by Similarity to an Ideal Solution)。TOPSIS 法是一种…

卷积神经网络--猫狗系列【CNN】

数据集&#xff0c;这次这个是分了类的【文末分享】 各12500张&#xff1a; 两点需要注意&#xff1a; ①猫狗分类是彩色图片&#xff0c;所以是3个channel&#xff1b; ②猫狗分类的图片大小不一&#xff0c;但是CNN的输入要求是固定大小&#xff0c;所以要resize。 划分训练…

【动态规划】子数组系列(下)

子数组问题 文章目录 【动态规划】子数组系列&#xff08;下&#xff09;1. 等差数组划分1.1 题目解析1.2 算法原理1.2.1 状态表示1.2.2 状态转移方程1.2.3 初始化1.2.4 填表顺序1.2.5 返回值 1.3 代码实现 2. 最长湍流子数组2.1 题目解析2.2 算法原理2.2.1 状态表示2.2.2 状态…

初学spring5(五)使用注解开发

学习回顾&#xff1a;初学spring5&#xff08;四&#xff09;自动装配 一、使用注解开发 二、说明 在spring4之后&#xff0c;想要使用注解形式&#xff0c;必须得要引入aop的包 在配置文件当中&#xff0c;还得要引入一个context约束 <beans xmlns"http://www.sprin…

Node.js模块化加载机制

优先从缓存中加载 模块在第一次加载后会被缓存。这也意味着多次调用 require() 不会导致模块的代码被执行多次 注意:不论是内置模块、用户自定义模块、还是第三方模块&#xff0c;它们都会优先从缓存中加载&#xff0c;从而提高模块的加载效率 $就像下方图中测试 内置模块…

【软件测试】MySQL操作数据表常用sql语句(汇总)

目录&#xff1a;导读 前言 一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 数据表有哪些操作…

【JavaEE初阶】HTML

摄影分享~ 文章目录 一.第一个HTML程序1.创建一个HTML文件并运行2.在vscode中创建HTML文件并运行HTML代码的特点 二.HTML中的标签1.注释标签2.标题标签3.段落标签4.换行标签5.格式化标签6.图片标签&#xff1a;img7.超链接标签8.表格标签9.列表标签10.from标签input标签selec…

Tomcat概念及部署

一.Tomcat的概述 1.Tomcat介绍 &#xff08;1&#xff09;免费的、开放源代码的web应用服务器。 &#xff08;2&#xff09;主要处理的是动态页面&#xff08;做一个运行后端的程序&#xff09;可以处理静态页面&#xff0c;处理效果不及apache和nginx。 &#xff08;3&…

类变量和类方法的基本使用

什么是类变量 类变量也叫静态变量/静态属性&#xff0c;是该类的所有对象共享的变量&#xff0c;任何一个该类的对象访问它时&#xff0c;取到的都是相同的值&#xff0c;同样任何一个该类的对象去修改它时&#xff0c;修改的也是同一个变量。 如何定义类变量 定义语法&…