银行转账案例

[1] 案例需求

用户访问登录页面,在页面中输入用户名和密码点击登录,登录成功后 进入到主页中。如果登录败,则在登录页面中提示用户用户名或密码错误。在主页面中,用户在填写银行转账信息,包括:转账账户,转账账 户密码,转账金额,收款账号,收款人姓名。点击开始转账,完成转账。但是有如下特殊需求:
① 需要用户的登录日志。
② 当转账账户的密码失去焦点时,检验转账账户信息是否存在。
③在转账金额失去焦点时,校验金额是否正确。
④ 收款人姓名失去焦点时,校验收款人信息是否正确
⑤ 当所有的信息验证无误后,才能转账。

[2] 案例页面效果图

① 登录页面效果图
在这里插入图片描述

② 转账主页面效果图
在这里插入图片描述

[3] 功能分析

① 创建登录页面
② 用户登录以及登录失败提示语
③ 登录日志
④ 创建银行转账页面
⑤ 转账账户信息校验
⑥ 金额校验
⑦ 入账账户信息校验
⑧ 转账功能

[4] 数据库设计

① 用户信息表: t_user

字段名 中文名 类型 大小 约束
uid 用户编号 int 10 主键、非空
uname 用户名 varchar 100 非空
pwd 密码 varchar 100 非空

② 银行账户信息表:t_account

字段名 中文名 类型 大小 约束
aid 账户编号 int 10 主键、非空
apwd 支付密码 varchar 100 非空
money 账户金额 double
uid 用户编号 int 10 非空

[5] 功能实现

1. 完成数据库的变现
-- ----------------------------
-- Table structure for `t_account`
-- ----------------------------
DROP TABLE IF EXISTS `t_account`;
CREATE TABLE `t_account` (
  `aid` int(10) NOT NULL AUTO_INCREMENT,
  `apwd` varchar(100) NOT NULL,
  `money` double DEFAULT NULL,
  `uid` int(10) NOT NULL,
  PRIMARY KEY (`aid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of t_account
-- ----------------------------
INSERT INTO `t_account` VALUES ('1', '123', '10000', '1');
INSERT INTO `t_account` VALUES ('2', '456', '10000', '2');

-- ----------------------------
-- Table structure for `t_user`
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
  `uid` int(10) NOT NULL AUTO_INCREMENT,
  `uname` varchar(100) NOT NULL,
  `pwd` varchar(100) NOT NULL,
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES ('1', '张三', '123');
INSERT INTO `t_user` VALUES ('2', '李四', '456');
2. 搭建Spring+Mybatis项目开发的环境

(1) 创建web项目
(2) 在web-inf下创建lib文件夹,并导入整合的jar包
(3) 在src创建MVC的包结构
注意:将表的实体类文件创建
(4) 在src下创建spring的配置文件
(5) 在web.xml文件中配置Spring文件路径和监听器

3. 创建登录页面

效果图:
在这里插入图片描述

代码示例:

<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="<%=basePath %>"/>
    <title>Title</title>
</head>
<body>
    <h3 align="center">欢迎登录502班级银行转账系统</h3>
    <hr>
    <div style="width: 400px;margin: auto">
        <form action="userLogin" method="post">
            <table style="margin: auto;margin-top: 30px;" cellpadding="10px">
                <tr>
                    <td>用户名:</td>
                    <td>
                        <input type="text" name="uname" value="">
                    </td>
                </tr>
                <tr>
                    <td>密码:</td>
                    <td>
                        <input type="password" name="pwd" value="">
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                        <input type="submit" value="点击登录">
                    </td>
                </tr>
            </table>
        </form>
    </div>
</body>
</html>
4. 完成登录功能
(1) 创建UserServlet,处理登录请求
package com.java.controller;
import com.java.pojo.User;
import com.java.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
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 javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet(value = "/userLogin",loadOnStartup = 1)
public class UserServlet extends HttpServlet {
    //声明init方法,完成Spring资源的初始化加载
    private UserService us;
    @Override
    public void init() throws ServletException {
        //获取Spring容器对象
        ApplicationContext ac= WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
        //获取业务层对象
         us= (UserService) ac.getBean("us");
    }
    //声明service方法,完成请求的处理
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置请求编码格式
            req.setCharacterEncoding("utf-8");
        //设置响应编码格式
            resp.setContentType("text/html;charset=utf-8");
            resp.setCharacterEncoding("utf-8");
        //获取请求信息
            String uname=req.getParameter("uname");
            String pwd=req.getParameter("pwd");
        //处理请求
            //调用业务层方法根据用户名和密码获取用户信息
            User user = us.userLoginService(uname, pwd);
        //响应处理结果
            //获取Session对象
             HttpSession session=req.getSession();
            //响应
            if(user!=null){
                //将用户信息存储到session中
                session.setAttribute("user",user);
                //重定向到主页面
                resp.sendRedirect(req.getContextPath()+"/main.jsp");
            }else{
                //增加失败标记
                session.setAttribute("flag","userFail");
                //重定向到登录页面
                resp.sendRedirect(req.getContextPath()+"/login.jsp");
            }
    }
}
(2) 创建UserService,处理登录请求
package com.java.service.impl;
import com.java.mapper.UserMapper;
import com.java.pojo.User;
import com.java.service.UserService;
public class UserServiceImpl implements UserService {
    //声明mapper层属性
    private UserMapper userMapper;

    public UserMapper getUserMapper() {
        return userMapper;
    }
    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }
    //用户登录
    @Override
    public User userLoginService(String uname, String pwd) {
        return userMapper.userLoginMapper(uname,pwd);
    }
}
(3) 创建UserMapper,根据用户名和密码获取用户信息
package com.java.mapper;
import com.java.pojo.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
public interface UserMapper {
    //根据用户名和密码获取用户信息
    @Select("select * from t_user where uname=#{uname} and pwd=#{pwd}")
    User userLoginMapper(@Param("uname") String uname, @Param("pwd") String pwd);
}
(4) 在applicationcontext.xml文件中配置业务层bean
<!--配置业务层bean-->
    <bean id="us" class="com.bjsxt.service.impl.UserServiceImpl">
        <property name="userMapper" ref="userMapper"></property>
    </bean>
5. 创建main.jsp主页面

① 页面示例图:
在这里插入图片描述

② 代码示例:

<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="<%=basePath %>"/>
    <title>Title</title>
    <%--引入jquery文件--%>
    <script type="text/javascript" src="js/j.js"></script>
    <%--声明js代码域--%>
    <script type="text/javascript">
        //声明页面加载事件
        $(function () {
            //创建颜色数组
            var colors=["red","yellow","black","green","gray","blue","brown","darhorchid"];
            //使用间隔执行
            window.setInterval(function () {
                //获取0-8的随机整数,含0不含8
                var index=Math.floor(Math.random()*colors.length);
                //设置标题颜色
                $("#title").css("color",colors[index]);
            },100)
        })
    </script>
</head>
<body>
    <%--网页的主题--%>
    <h3 align="center">
            <%--跑马灯效果--%>
            <marquee width=400 behavior=alternate direction=left align=middle>
                <font color="r" id="title">欢迎${sessionScope.user.uname}登录502班级银行转账系统</font>
            </marquee>
    </h3>
    <%--水平线--%>
    <hr>
    <%--银行转账表单--%>
    <div style="width: 400px;margin: auto;">
        <form action="">
            <table style="margin: auto;margin-top: 30px;" cellpadding="10px">
                <tr>
                    <td>转账账户:</td>
                    <td>
                        <input type="text" name="outId" value="">
                    </td>
                </tr>
                <tr>
                    <td>转账账户密码:</td>
                    <td>
                        <input type="password" name="outPwd" value="">
                    </td>
                </tr>
                <tr>
                    <td>金额:</td>
                    <td>
                        <input type="text" name="money" value="">
                    </td>
                </tr>
                <tr>
                    <td>收款账号:</td>
                    <td>
                        <input type="text" name="inId" value="">
                    </td>
                </tr>
                <tr>
                    <td>收款人姓名:</td>
                    <td>
                        <input type="text" name="inName" value="">
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                        <input type="submit" value="开始转账">
                    </td>
                </tr>
            </table>
        </form>
    </div>
</body>
</html>
6. 完成转账账户信息的校验

(1) 功能点需求:

用户在输入账户以及密码后,在密码失去焦点后,触发校验。如果正确则在密码框 后显示√,错误则显示X.

(2) 功能点分析:

通过需求我们发现,校验的结果是在当前页面中继续显示的。相当于我们在当前 页面中显示新的响应结果 ,确定该功能使用ajax技术来实现。

(3) 前台分析:

① ajax请求的触发时机:在密码框失去焦点时触发
② ajax请求的请求地址: Servlet的别名,checkAccount
③ ajax请求的请求数据:账户和密码
④ ajax请求的响应数据:true或者false的字符串

(4) 前台代码实现:

//给密码框添加焦点事件,完成校验
$(function () {
    $("#outdPwd").blur(function () {
        //发起ajax请求
        $.post("checkAccount",{outId:$("#outId").val(),outPwd:$("#outdPwd").val(),methodName=”checkOutInfo”},function (data) {
            if(eval(data)){
                $("#outSpan").html("√").css("color","green");
            }else{
                $("#outSpan").html("X").css("color","red");
            }
        })
    })
})

(5) 后台分析:

① 创建Servlet,处理转账账户信息校验。checkAccount 注意:有,响应”true”,没有,响应”false”
② 创建Service,处理账户信息校验。
③ 创建mapper,根据账户ID和密码获取账户信息。

(6) 后台代码实现:

CheckAccountServlet

    //声明方法:校验转账账户信息
    private void checkOutInfo(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //获取请求信息
        String outId=req.getParameter("outId");
        String outPwd=req.getParameter("outPwd");
        //处理请求
        //调用业务层方法
        Account account = checkAccountService.checkOutAccountInfoService(outId, outPwd);
        //响应结果
        resp.getWriter().write(account!=null?"true":"false");
    }

CheckAccountService

    //校验转账账户信息
    Account checkOutAccountInfoService(String outId,String outPwd);

CheckAccountServiceImpl

    //校验转账账户信息
    @Override
    public Account checkOutAccountInfoService(String outId, String outPwd) {
        return checkAccountMapper.checkAccountOutInfoMapper(outId,outPwd);
    }

CheckAccountMapper

    //校验转账账户信息:根据账户ID和密码获取账户信息
    @Select("select * from t_account where aid=#{outId} and apwd=#{outPwd}")
    Account checkAccountOutInfoMapper(@Param("outId") String outId, @Param("outPwd") String outPwd);

7. Servlet的优化

(1) 问题:

目前我们每实现一个功能点,就需要在后台声明一个对应的Servlet进行 请求的处理。这样造成Servlet声明过多,代码繁琐。

(2) 解决:

Servlet只声明一个,让所有的相关请求,都请求该Servlet。 在该Servlet中的service方法中,不做具体的请求处理。在Service中,根据请求,调用对应的逻辑代码来处理请求即可。 类似:main方法的机制。

(3) 实现:

在Servlet中将不同请求的处理逻辑代码封装成对应的逻辑功能方法 然后在service方法中,根据请求调用对应的逻辑方法处理请求。每次请求都需要在请求数据中携带要请求的方法的方法名。后台service中 根据请求数据中的方法名调用对应的逻辑方法即可。

package com.java.controller;
import com.java.pojo.Account;
import com.java.service.CheckAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
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;
@WebServlet(value = "/checkAccount",loadOnStartup = 2)
public class CheckAccountServlet extends HttpServlet {
    //声明业务层属性
    private CheckAccountService checkAccountService;
   //重写init方法
    @Override
    public void init() throws ServletException {
        //获取Spring容器对象
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
        //获取业务层对象
        checkAccountService= (CheckAccountService) ac.getBean("checkAccountService");
    }
    //重写service方法
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置请求编码格式
            req.setCharacterEncoding("utf-8");
        //设置响应编码格式
            resp.setCharacterEncoding("utf-8");
            resp.setContentType("text/html;charset=utf-8");
         //获取请求数据中的方法名
        String methodName=req.getParameter("methodName");
        //根据请求调用对应的逻辑代码
        if("checkOutInfo".equals(methodName)){
            checkOutInfo(req,resp);
        }else if("checkMoneyInfo".equals(methodName)){
            checkMoneyInfo(req,resp);
        }else if("checInInfo".equals(methodName)){
            checInInfo(req,resp);
        }else if("transferInfo".equals(methodName)){
            transferInfo(req,resp);
        }else{
            System.out.println("没有对应的逻辑方法:"+methodName);
        }
    }
    //转账
    private void transferInfo(HttpServletRequest req, HttpServletResponse resp) {
    }
    //校验收款人信息
    private void checInInfo(HttpServletRequest req, HttpServletResponse resp) {
    }
    //校验金额
    private void checkMoneyInfo(HttpServletRequest req, HttpServletResponse resp) {
    }

    //声明方法:校验转账账户信息
    private void checkOutInfo(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //获取请求信息
        String outId=req.getParameter("outId");
        String outPwd=req.getParameter("outPwd");
        //处理请求
        //调用业务层方法
        Account account = checkAccountService.checkOutAccountInfoService(outId, outPwd);
        //响应结果
        resp.getWriter().write(account!=null?"true":"false");
    }


}
8. 校验金额

(1) 功能点需求:

用户在金额框中输入要转账的金额信息后,失去焦点时,完成金额信息的校验。 余额足够则在金额框后显示√,否则显示X

(2) 功能分析:

使用ajax技术。

① 前台分析

i. 给金额框增加焦点事件
ii. 发起ajax请求
iii. 请求数据为金额,转账账户Id,后台逻辑方法名
iv. 响应数据为true或者false的字符串

示例代码:

/*********************转账金额校验**************************************/    
    $(function () {
        $("#money").blur(function () {
            //发起ajax请求
            $.post("checkAccount",{outId:$("#outId").val(),money:$("#money").val(),methodName:"checkMoneyInfo"},function (data) {
                if(eval(data)){
                    $("#moneySpan").html("√").css("color","green");
                }else{
                    $("#moneySpan").html("X").css("color","red");
                }
            })
        })
    })

② 后台分析:
i. 在CheckAccountServlet中声明金额校验逻辑方法,并在service方法完成调用

    //校验金额
    private void checkMoneyInfo(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //获取请求数据
            String outId=req.getParameter("outId");
            String money =req.getParameter("money");
        //处理请求
            Account account=checkAccountService.checkMoneyInfoService(outId,money);
        //响应结果
            resp.getWriter().write(account!=null?"true":"false");
    }

ii. 在CheckAccountService中新增金额校验的业务方法

    //校验金额
    Account checkMoneyInfoService(String outId, String money);

    //校验金额
    @Override
    public Account checkMoneyInfoService(String outId, String money) {
        return checkAccountMapper.checkMoneyInfoMapper(outId,money);
    }

iii. 在CheckAccountMapper中新增金额校验的数据库操作

//校验金额
@Select("select * from t_account where aid=#{outId} and money>=#{money}")
Account checkMoneyInfoMapper(@Param("outId") String outId, @Param("money") String money);
9. 收款人信息校验

(1) 功能点需求:

用户在收款人姓名失去焦点时,校验收款人信息。存在,则在收款人姓名框后显示 √,不存在则显示X

(2) 功能分析

  1. 前台分析

i. 给收款人姓名框增加焦点事件
ii. 发起ajax请求完成校验
iii. 请求数据为收款人账户ID,收款人姓名,后台逻辑方法名
iv. 响应数据 true或者false的字符串

代码示例:

/*********************收款人信息校验**************************************/
    $(function () {
        $("#inName").blur(function () {
            //发起ajax请求
            $.post("checkAccount",{inId:$("#inId").val(),inName:$("#inName").val(),methodName:"checInInfo"},function (data) {
                if(eval(data)){
                    $("#inNameSpan").html("√").css("color","green");
                }else{
                    $("#inNameSpan").html("X").css("color","red");
                }
            })
        })
    })
  1. 后台分析
    i. 在CheckAccountServlet中声明对应的逻辑方法完成校验
    //校验收款人信息
    private void checInInfo(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //获取请求数据
            String inId=req.getParameter("inId");
            String inName=req.getParameter("inName");
        //处理请求
            Account account=checkAccountService.checkInInfoService(inId,inName);
        //响应结果
            resp.getWriter().write(account!=null?"true":"false");
    }

ii. 在CheckAccountService中声明业务方法

    //校验收款人信息
    Account checkInInfoService(String inId, String inName);
    //校验收款人信息
    @Override
    public Account checkInInfoService(String inId, String inName) {
        return checkAccountMapper.checkInInfoMapper(inId,inName);
    }

iii. 在CheckAccountMapper中声明数据库操作

    //校验收款人信息
    @Select("select a.* from t_account a join t_user u on a.uid=u.uid where a.aid=#{inId} and u.uname=#{inName}")
    Account checkInInfoMapper(@Param("inId") String inId, @Param("inName") String inName);
10. 开始转账

(1) 功能点需求:

点击开始转账时,保证所有的转账信息是正确的,如果有错误的转账信息 提示用户,请填写正确的信息。如果全部都是正确的,则直接发起转账请求,完成转账。

(2) 功能分析:

① 前台分析

i. 给转账按钮增加单击事件
ii. 校验转账信息是否全部正确
iii. 提交转账请求

代码示例:

/*********************转账账户信息校验**************************************/
    //给密码框添加焦点事件,完成校验
    $(function () {
        $("#outdPwd").blur(function () {
            //发起ajax请求
            $.post("checkAccount",{outId:$("#outId").val(),outPwd:$("#outdPwd").val(),methodName:"checkOutInfo"},function (data) {
                if(eval(data)){
                    $("#outSpan").html("√").css("color","green").addClass("success").removeClass("error");
                }else{
                    $("#outSpan").html("X").css("color","red").addClass("error").removeClass("success");
                }
            })
        })
    })
/*********************转账金额校验**************************************/
    $(function () {
        $("#money").blur(function () {
            //发起ajax请求
            $.post("checkAccount",{outId:$("#outId").val(),money:$("#money").val(),methodName:"checkMoneyInfo"},function (data) {
                if(eval(data)){
                    $("#moneySpan").html("√").css("color","green").addClass("success").removeClass("error");
                }else{
                    $("#moneySpan").html("X").css("color","red").addClass("error").removeClass("success");
                }
            })
        })
    })
/*********************收款人信息校验**************************************/
    $(function () {
        $("#inName").blur(function () {
            //发起ajax请求
            $.post("checkAccount",{inId:$("#inId").val(),inName:$("#inName").val(),methodName:"checInInfo"},function (data) {
                if(eval(data)){
                    $("#inNameSpan").html("√").css("color","green").addClass("success").removeClass("error");
                }else{
                    $("#inNameSpan").html("X").css("color","red").addClass("error").removeClass("success");
                }
            })
        })
    })
/*********************转账功能**************************************/
    $(function () {
        $("#btn").click(function () {
            //校验转账信息是否正确
            if($(".success").length==3){
                //提及表单
                $("#fm").submit();
            }else{
                alert("请填写正确的账户信息")
            }
        })
    })

② 后台分析

i. 在CheckAccountServlet中声明转账的逻辑方法

    //转账
    private void transferInfo(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //获取请求数据
            String outId=req.getParameter("outId");
            String inId=req.getParameter("inId");
            String money=req.getParameter("money");
        //处理请求
            int i=checkAccountService.transferInfoService(outId,inId,money);
        //响应结果
            if(i>0){
                resp.sendRedirect(req.getContextPath()+"/success.jsp");
            }else{
                resp.sendRedirect(req.getContextPath()+"/error.jsp");
            }
    }

ii. 在CheckAccountService中声明转账的业务方法

    //转账功能
    int transferInfoService(String outId, String inId, String money);
    //转账功能
    @Override
    public int transferInfoService(String outId, String inId, String money) {
        //1.出账
        int i = checkAccountMapper.transferOut(outId, money);
        //2.入账
        i+=checkAccountMapper.transferIn(inId,money);
        //返回
        return i;
    }

iii. 在CheckAccountMapper中完成转账的数据库操作

    @Update("update t_account set money=money-#{money} where aid=#{outId}")
    int transferOut(@Param("outId") String outId,@Param("money") String money);
    //转入
    @Update("update t_account set money=money+#{money} where aid=#{inId}")
    int transferIn(@Param("inId") String inId,@Param("money") String money);
11. 登录日志

(1) 功能点需求:

我们的银行转账功能,在刚开始运营的时候,并没有用户登录的日志信息的记录。后来,某天某个客户他的账号被登录了,但是给该客户又不知道是什么时间进行的登录,造成调查有困扰,怎么办?在当前登录功能的基础上,增加登录日志,来记 录用户的登录信息。便于我们后期的排查。

(2) 功能分析:

在保留当前登录功能的基础上,完成对登录功能的扩展。但是又不希望改变原有的功能代码逻辑。考虑使用SpringAOP。
前置通知:在日志文件中输出XXX在XXX时间发起了登录请求
切点:登录的业务方法
后置通知:在日志文件中输出XXX在XXX时间登录成功
建议使用SchemaBased方式实现。

(3) 功能实现:

i. 在lib下导入AOP的jar包
ii. 在src下创建com.bjsxt.advice的包
iii. 在advice包中创建前置通知和后置通知

后置通知

package com.java.advice;

import org.apache.log4j.Logger;
import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;

public class MyAfter implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
        //获取Log4j的对象
        Logger logger = Logger.getLogger(MyAfter.class);
        //日志输出
        if(o!=null){
            logger.debug(objects[0]+"登录成功");
        }

    }
}

前置通知

package com.java.advice;

import org.apache.log4j.Logger;
import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class MyBefore implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        //获取Log4j的对象
        Logger logger = Logger.getLogger(MyBefore.class);
        //日志输出
        logger.debug(objects[0]+"发起了登录请求");
    }
}

iv. 在src下声明log4j.properties配置文件


log4j.rootCategory=info



log4j.logger.com.bjsxt.mapper=debug, CONSOLE,LOGFILE
log4j.logger.com.bjsxt.advice=debug, CONSOLE,LOGFILE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=- %c-%d-%m%n


log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=D:/axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=- %c-%d-%m%n

v. 在applicationcontext.xml文件中配置通知bean以及组装规则

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        ">
    <!--配置数据源bean-->
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
            <property name="url" value="jdbc:mysql://localhost:3306/502"></property>
            <property name="username" value="root"></property>
            <property name="password" value="1234"></property>
        </bean>
    <!--配置工厂bean-->
        <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
    <!--配置mapper扫描bean-->
        <bean id="mapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="sqlSessionFactory" ref="factory"></property>
            <property name="basePackage" value="com.bjsxt.mapper"></property>
        </bean>
    <!--配置业务层bean-->
        <!--用户登录-->
        <bean id="us" class="com.bjsxt.service.impl.UserServiceImpl">
            <property name="userMapper" ref="userMapper"></property>
        </bean>
        <!--配置信息校验-->
        <bean id="checkAccountService" class="com.bjsxt.service.impl.CheckAccountServiceImpl">
            <property name="checkAccountMapper" ref="checkAccountMapper"></property>
        </bean>
    <!--配置通知bean-->
        <bean id="before" class="com.bjsxt.advice.MyBefore"></bean>
        <bean id="after" class="com.bjsxt.advice.MyAfter"></bean>
    <!--配置AOP组装规则-->
        <aop:config>
            <aop:pointcut id="mp" expression="execution(* com.bjsxt.service.impl.UserServiceImpl.userLoginService(String,String))"/>
            <aop:advisor advice-ref="before" pointcut-ref="mp"></aop:advisor>
            <aop:advisor advice-ref="after" pointcut-ref="mp"></aop:advisor>
        </aop:config>
    <!--开启cglib代理模式-->
        <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
</beans>
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用Mybatis-Plus实现银行转账可以按照以下步骤进行: 第一步,创建一个实体类,表示银行账户: ```java public class Account { private Long id; private String accountNumber; private BigDecimal balance; // 其他属性和方法 } ``` 第二步,创建一个Mapper接口,用于定义数据库操作方法: ```java public interface AccountMapper extends BaseMapper<Account> { // 其他方法,如转账操作等 } ``` 第三步,创建一个Service类,用于编写转账业务逻辑: ```java @Service public class AccountService { @Autowired private AccountMapper accountMapper; public void transfer(Long fromAccountId, Long toAccountId, BigDecimal amount) { // 查询转出账户和转入账户 Account fromAccount = accountMapper.selectById(fromAccountId); Account toAccount = accountMapper.selectById(toAccountId); // 判断转出账户余额是否足够 if (fromAccount.getBalance().compareTo(amount) < 0) { throw new RuntimeException("转出账户余额不足"); } // 更新转出账户余额 fromAccount.setBalance(fromAccount.getBalance().subtract(amount)); accountMapper.updateById(fromAccount); // 更新转入账户余额 toAccount.setBalance(toAccount.getBalance().add(amount)); accountMapper.updateById(toAccount); } } ``` 第四步,配置Mybatis-Plus分页插件。在Mybatis-Plus的配置类中添加分页插件的Bean定义: ```java @Configuration @EnableTransactionManagement public class MybatisPlusConfig { @Bean public PaginationInterceptor paginationInterceptor() { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true)); return paginationInterceptor; } } ``` 以上是使用Mybatis-Plus实现银行转账的基本步骤。可以根据实际业务需求进行修改和扩展。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [springboot整合mybatis-plus看这篇文章就足够了](https://blog.csdn.net/qq_33220089/article/details/104752320)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [springboot封装统一查询对象进行条件查询案例(mybatis和mybatis-plus+反射两种版本)](https://blog.csdn.net/qq_41358574/article/details/120986617)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AloneDrifters

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值