Mybatis(4)之跟着老杜做一个简单的银行转账会话

news2024/11/14 16:55:23

这是个MVC项目,我不一定可以完整的实现这个项目,但力求把这个复现出来,尽量的复现细节。

第一步:创建数据库  表

创建表如下:

我们使用 int 是为了方便 然后采用  demcial,精确度较高

添加两个用户

然后开始构建Web项目

然后完善  依赖

加上 mysql  mybatis         log4j       servlet的依赖

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.10</version>
    </dependency>
    <dependency>
      <groupId>com.mysql</groupId>
      <artifactId>mysql-connector-j</artifactId>
      <version>8.0.31</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>

然后配置 mybatis.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value=""/>
                <property name="url" value=""/>
                <property name="username" value=""/>
                <property name="password" value=""/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
    </mappers>
</configuration>

我们如果将数据库的配置信息直接写到里面的话会导致后期修改过于麻烦,因此我们可以写到xx.properties中,后期修改方便

主要是使用 ${}里面填写相应的名字,就可以获取到db.properties的数据了,写法如下:

<configuration>
    <properties resource="database.properties" ></properties>
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
    </mappers>
</configuration>

db的内容如下:

driver = com.mysql.cj.jdbc.Driver
url  = jdbc:mysql://localhost:3306/prostudydb
username = 
password = 

然后我们先来写个简单的查询语句测试一下,看是否可以获得对应的数据,是否数据库部分配置好。

那么我们就需要先粗步的完善项目构造,首先需要一个pojo类,或者叫做entiry类

public class account {
    private  Integer id;
    private  Integer actno;
    private  Long  balance; 
    public  account(){}
    public account(Integer id, Integer actno, Long balance) {
        this.id = id;
        this.actno = actno;
        this.balance = balance;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getActno() {
        return actno;
    }

    public void setActno(Integer actno) {
        this.actno = actno;
    }

    public Long getBalance() {
        return balance;
    }

    public void setBalance(Long balance) {
        this.balance = balance;
    }

    @Override
    public String toString() {
        return "account{" +
                "id=" + id +
                ", actno=" + actno +
                ", balance=" + balance +
                '}';
    }
}

完成有参 无参 get set tostring的方法,然后我们需要创建util层,提供一个静态的工具类,提供我们需要的sqlsession 。

然后是utils类,请注意,utils类中需要使用静态方法,因为工具类我们只需要使用就可以了,不需要实例化对象,因此在类加载的时候编译一次即可

public class sqlSession {
//    一个静态的 SqlSessionFactory ,我们需要它在opensession中使用,因此需要声明一下
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
//            类加载的时候初始化sqlsessionfactory
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
          sqlSessionFactory =    sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (IOException e) {
            throw new RuntimeException("在utils下的sqlsessionfactorybuilder中出现的异常"+ e);
        }
    }
//    返回sqlsession的方法  返回需要的sqlsession
    public  static SqlSession           openSession    (){
          return   sqlSessionFactory.openSession();
    }

//    执行selectone的方法
    /**
     * int id
     * sqlsession sqlsession
     * 因为要返回pojo对象,所以我们需要返回account ,通过传入id + 一个session,我们就可以得到需要的数据
     * */
    public  static    account getOneAccount(SqlSession sqlSession,Integer id ){
        account  account = new account();
          account   =    sqlSession.selectOne("account.selectById",id);
        return  account;
    }
}

然后我们看一下测试方法

   public  void  get(){
//    调用静态方法获取对象
     SqlSession sqlsession = sqlSession.openSession();
     System.out.println(sqlsession);
//   得到值
    account a =       sqlSession.getOneAccount(sqlsession,1);
   System.out.println(a);
}
}

看一下xxxmapper的内容

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="account">
    <select id="selectById" resultType="pojo.account">
        select *  from try where id = #{id}
    </select>

</mapper>

成功获取到数据,证明数据库和后端交流通常

然后我们来完成简单的前端部分和tomcat的配置

首先是一个简单的inex.html 一个web.xml请注意web.xml的版本尽可能高,最好是4

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>账户尝试</title>
</head>
<body>
  <h1>阿达是大大大是</h1>
</body>
</html>
<web-app
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
						http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
        id="WebApp_ID" version="4.0">

</web-app>

配置好tomcat后运行一下发现ok,接下来就是完善表格 获取http传来的会话

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>账户尝试</title>
</head>
<body>
  <h1>阿达是大大大是</h1>
                           <form action="/tranfser"  method="post">
                        <span>账号1</span>       <input  type="text"    name="shuzhi1"      >
                               <br>
                         <span>账户2</span>      <input   type="text"  name="shuzhi2"     >
                              <input  type="submit" value="提交" >
                           </form>
</body>
</html>

请在这里暂停,捋一下思路。

前端发送数据  通过 transfer 转交json数据给后端,我们可以通过req.getParmare通过name获得数据,那么我们就需要重写HttpServlet。

我们需要在controller中获取前端传来的数据,然后包装在一个新的account对象中。

并且通过方法完成字符串的转变为int long的转变

@WebServlet("/tranfser")
public class transeferOnetoAnother extends  HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                  String shuzhi =  req.getParameter("shuzhi2");
                Long shuzhi1 = Long.parseLong(req.getParameter("shuzhi1"));
        System.out.println(shuzhi1);
        System.out.println("3333333333333333333333333333");
//               通过parseLong将字符串转变为long
               Long shuzhi2 = Long.parseLong(shuzhi);
               account account01 = new account();
               account01.setBalance(shuzhi1);
               account01.setId(1);
               account account02 = new account();
               account02.setBalance(shuzhi2);
               account02.setId(2);

然后我们就要调用service中处理转账的方法,我们就可以传递两个account对象。

请注意service中我们要先写接口,在实现方法,通过接口命名方法有好处如下:方便设计和沟通,我们可以由一个人设计出接口,分给每个人实现,这样可以提高效率并且控制。2.可以解耦合,实现更高的耦合度,需要增加功能的话,我们不需要改动原来的代码,只需要正在接口中增加一个新的抽象方法,然后在用一个新的实现类实现它,保障原代码的安全性。

public interface transfer {
//    通过返回int看是否成功,我们可以通过两个实体类,然后查看它的值,来判断是否转账
  int transferOneToAnother(account account1, account account2);
}


public class  transferImpl    implements transfer {
    @Override
    public int transferOneToAnother(account account1, account account2) {
//           第一步,将后端的两个数据查询出来
//        我们需要查询所有,通过list来获取,完善select
/**        第一步 在accountMapper中完善Select语句,填写好id  selectAll
 *       第二步 前往utils中,编写查询所有的方法 输入  sqlsession 返回list集合,
 *       第三步  回到这里  完善业务处理方法
 *
 * **/
        SqlSession sqls = sqlSession.openSession();
/*        请注意,我们这里是静态方法,必须调用类,我们通过调用静态方法获得session 在传值,这样是不是多次一举呢?
  * 事实上,mybatis默认在数据库连接池中维护了10个数据库连接,我们需要保证每次获取的session相同,这点我也不清楚,QAQ
  * **/
        List<account> list =  sqlSession.getAll(sqls);
       account a01 = list.get(0);
       account a02  = list.get(1);
//       比较数值 假如是从  1  转账给 2   那我们怎么知道是从 1 转账给 2 呢??
/*
* 模拟的话就是只要其中一个有数字 ,那么加 另一个减少只实现一个加的功能不提供减的
* */
        /*
        *
        * 请注意这里   account1  和 a01 的区别,一个是我们从前端传递后来包装的  一个是从数据库中包装的
        * */
        if (account1.getBalance()   > a01.getBalance() ){
            System.out.println("钱不够");
        }else {
//            那么账户1需要更新,然后我们需要调用更新语句  更新数据库的值
//            返回到mapper完善更新语句  sqlsession完善更新需要的方法
            /*
            * 更新语句  需要  sqlSession   id   balance  通过返回int值看是否成功 int <1 则是失败
            * */
               if ((sqlSession.updateOne(sqls,a01.getId(), a01.getBalance()-account1.getBalance()) < 1)){
                System.out.println("更新语句失败");
            }else{
//                   session提交 session关闭
                   sqls.commit();
                   sqls.close();
            }
        }
        return 0;
    }
}

同时,我们需要在service的实现类中调用实现好的Select 和 update方法,实现查找和更改

    public  static  int  updateOne(  SqlSession sqlSession,      int id,Long balance   ){
        account account = new account();
        account.setId(id);
        account.setBalance(balance);
        int   count =          sqlSession.update("updatesOne",account);
        return   count;
    }

最主要的就是形式参数的确定和一致

我们给出更新语句

<update id="updatesOne">
    update try set balance = #{balance} where id = #{id}
</update>

请注意 务必封装成一个完整的account类,我们才能调用session.update方法进行自动匹配传递值。

然后基本上就实现了更改。

 

 

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

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

相关文章

JVM学习笔记二:运行时数据区概述及JVM线程

目录 概述 JVM各区域划分 JVM线程 线程的内存空间 JVM系统线程 概述 运行时数据区是JVM非常重要的组成部分&#xff0c;这一篇主要介绍运行时数据区各个区域的划分&#xff0c;以及JVM中的线程。 JVM各区域划分 学习JVM&#xff0c;必须牢记下图各个区域的分类&#xff…

【5G RRC】5G系统消息SIB2介绍

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

九龙证券|动力锂离子电池的能量密度可达多少?

现在&#xff0c;我国车用动力锂电池技能道路挑选的是与美国相同的磷酸铁锂道路。毫无疑问&#xff0c;磷酸铁锂离子电池有着许多优势&#xff1a;稳定性高、价格相对便宜&#xff0c;然而其能量密度&#xff08;能量密度更大&#xff0c;才能更好地解决路程问题&#xff09;提…

RabbitMQ 入门到应用 ( 五 ) 基本应用

6.更多应用 6.1.AmqpAdmin 工具类 可以通过Spring的Autowired 注入 AmqpAdmin 工具类 , 通过这个工具类创建 队列, 交换机及绑定 import org.springframework.amqp.core.AmqpAdmin; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.Di…

linux xargs 删除名字中包含某字符串的文件

xargs的作用 格式化输出 可以把多行文本变成一行&#xff0c;或者指定行数和列数。每一列用空格作分隔符号。 test.txt中的内容 例子1&#xff1a; 用xargs格式化输出后,多行变成了一行&#xff0c;而且多个空格变成了一个空格。 cat test|xargs例子2&#xff1a; 当然也可…

go size class 内存块思考

浏览到的一篇文章&#xff0c;让我也有机会反思一下 go 内存管理。网络上&#xff0c;go 内存管理方面的介绍挺多的&#xff0c;面试的时候&#xff0c;偶尔也会被问到内存管理。 而且&#xff0c;从 go1.15 到 go1.16 在 size class 上引入了新的内存块&#xff0c;能直观的看…

信奥一本通1365

1365&#xff1a;FBI树(fbi) 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 6443 通过数: 4366 【题目描述】 我们可以把由“0”和“1”组成的字符串分为三类&#xff1a;全“0”串称为B串&#xff0c;全“1”串称为I串&#xff0c;既含“0”又含“1”的串则称为…

C语言——动态内存管理(详解)

1.动态内存管理存在的意义 在前面的C语言的学习中&#xff0c;我们已经掌握的空间开辟的方式有如下两种 int i 0; //开辟了4字节大小的空间存放i int arr[5] {0}; //开辟了20字节的空间存放数组arr这样开辟空间有两个显著的特点&#xff1a; 1、每次开辟空间的大小都是固定…

K8S集群将Docker切换到Containerd

文章目录1. 开启节点维护1.1 将节点设置成不可调度1.2 驱逐节点上的 Pod1.3 停止相关服务2. 升级到 containerd2.1 安装 containerd2.2 调整 containerd 配置2.3 修改 kubelet 启动配置参数3. 重启节点服务4. 验证升级后的节点5. 容器管理工具5.1 容器管理命令行工具对比5.2 cr…

【JavaScript】ES6模块化与异步编程高级用法

一、ES6模块化 1、回顾&#xff1a;node.js遵循了ComminJS的模块化规范。 其中&#xff1a; 导入其他模块使用require()方法模块对外共享成员使用module.exports对象 模块化的好处&#xff1a; 遵守同样的模块化规范写代码&#xff0c;降低了沟通成本&#xff0c;极大方便了…

使用 ApiPost进行WebService 调试,就是这样简单

文章目录5.1 新建一个 HTTP 接口5.2 添加请求Body5.3 设置请求Header5.4 发送请求Apipost 可以用于调试 WebService 请求。具体步骤如下&#xff1a;5.1 新建一个 HTTP 接口 新建一个 HTTP接口&#xff0c;URL 部分填写 endpoint&#xff0c;请求方式选择 POST。以下 URL 为示…

SpringBoot自动装配的原理

前言 在开发SpringBoot项目时&#xff0c;当我们引入spring-boot-starter-xxx依赖后&#xff0c;想要使用依赖中的bean&#xff0c;直接就用Autowired拿来用了&#xff0c;不需要用xml或者注解的方式把它先注入到Spring容器中。这就是自动装配的特性&#xff0c;本文来讲述Spri…

Spring Bean循环依赖

解决SpringBean循环依赖为什么需要3级缓存&#xff1f;回答&#xff1a;1级Map保存单例bean。2级Map 为了保证产生循环引用问题时&#xff0c;每次查询早期引用对象&#xff0c;都拿到同一个对象。3级Map保存ObjectFactory对象。数据结构1级Map singletonObjects2级Map earlySi…

CMake option选项使用方式及注意事项

CMAKE官网 &#x1f358; 在复习 CMake 的时候&#xff0c;使用了 option 功能&#xff0c;发现修改了参数的值之后&#xff0c;和未修改的效果一样&#xff0c;然后不断的查找 option 的使用方法&#xff0c;最后发现并非 option 使用方式而错误&#xff0c;而是 option 第一…

SpringCloudAlibaba-分布式事务Seata

一、介绍官网&#xff1a;http://seata.io/zh-cn/index.html TC (Transaction Coordinator) - 事务协调者维护全局和分支事务的状态&#xff0c;驱动全局事务提交或回滚。TM (Transaction Manager) - 事务管理器定义全局事务的范围&#xff1a;开始全局事务、提交或回滚全局事务…

Mac Appium iOS自动化测试环境搭建教程

目录Appium环境搭建Mac iOS环境搭建Appium基础Appium进阶环境搭建安装brewCopyruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"安装javaCopybrew install java安装python3 及相关包Copybrew install python3 pip install selenium pip install app…

实现8086虚拟机(四)——mov 和 jmp 指令解码

文章目录mov 指令解码jmp 指令解码这篇文章举例来讲讲 mov 指令和 jmp 指令解码函数的实现&#xff0c;其他的指令解码函数都与这些类似。mov 指令解码 以 mov 指令中的一类&#xff1a;寄存器/内存 到/从 寄存器&#xff0c;来详细说明解码函数的实现。 机器指令格式如下&am…

联想M7268激光打印机开机红绿灯双闪报错不打印

故障现象: 一台联想M7268激光打印机开机后电源键、复印键一起双闪,电源键闪红灯、复印键闪绿灯; 检测维修: 根据闪灯故障判断如果无卡纸异常情况下可能是激光器故障,因为以前曾经维修过一台一模一样的机器故障基本相同,先打开机器吧,把硒鼓拿出来先看看有没有卡纸,进纸…

php小程序餐馆点餐订餐外卖系统

目录 1 绪论 1 1.1课题背景 1 1.2课题研究现状 1 1.3初步设计方法与实施方案 2 1.4本文研究内容 2 2 系统开发环境 4 2.2MyEclipse环境配置 4 2.3 B/S结构简介 4 2.4MySQL数据库 5 3 系统分析 6 3.1系统可行性分析 6 3.1.1经济可行性 6 3.1.2技术可行性 6 3.1.3运行可行性 6 …

c++11 标准模板(STL)(std::unordered_set)(二)

定义于头文件 <unordered_set> template< class Key, class Hash std::hash<Key>, class KeyEqual std::equal_to<Key>, class Allocator std::allocator<Key> > class unordered_set;(1)(C11 起)namespace pmr { templ…