结合spring IOC AOP Mybatis写一个简易的银行转账案例

1.在mysql数据库引入如下sql文件

-- ----------------------------
-- 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的配置文件

applicationcontext.xml
<?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>

(5) 在web.xml文件中配置Spring文件路径和监听器

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
           version="3.0">
    <!--声明全局变量-->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationcontext.xml</param-value>
        </context-param>
    <!--配置监听器-->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>

</web-app>

3.创建一个登录页面login.jsp

在这里插入图片描述

<%--
  Created by IntelliJ IDEA.
  User: zyp
  Date: 2020/3/5
  Time: 16:45
  To change this template use File | Settings | File Templates.
--%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ 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">
        <c:if test="${sessionScope.flag=='userFail'}">
            <font color="red" size="20px;">用户名或密码错误</font>
        </c:if>
        <c:remove var="flag" scope="session"></c:remove>
        <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.完成登录功能 UserServlet

package com.bjsxt.controller;

import com.bjsxt.pojo.User;
import com.bjsxt.service.UserService;
import com.bjsxt.service.impl.UserServiceImpl;
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 UserServiceImpl us;
    @Override
    public void init() throws ServletException {
        //获取Spring容器对象
        ApplicationContext ac= WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
        //获取业务层对象
         us= (UserServiceImpl) 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");
            }
    }
}
UserService
package com.bjsxt.service;

import com.bjsxt.pojo.User;

public interface UserService {
    //用户登录
    User userLoginService(String uname, String pwd);
}

UserServiceImpl

package com.bjsxt.service.impl;

import com.bjsxt.mapper.UserMapper;
import com.bjsxt.pojo.User;
import com.bjsxt.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);
    }
}
UserMapper
package com.bjsxt.mapper;

import com.bjsxt.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);
}

5.创建main.jsp的页面

<%--
  Created by IntelliJ IDEA.
  User: zyp
  Date: 2020/3/5
  Time: 17:31
  To change this template use File | Settings | File Templates.
--%>
<%
    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)
        })
    /*********************转账账户信息校验**************************************/
        //给密码框添加焦点事件,完成校验
        $(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("请填写正确的账户信息")
                }
            })
        })
    </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="checkAccount" method="post" id="fm">
            <input type="hidden" name="methodName" value="transferInfo">
            <table style="margin: auto;margin-top: 30px;" cellpadding="10px">
                <tr>
                    <td>转账账户:</td>
                    <td>
                        <input type="text" id="outId" name="outId" value="">
                    </td>
                </tr>
                <tr>
                    <td>转账账户密码:</td>
                    <td>
                        <input type="password" id="outdPwd"  value="">
                        <span id="outSpan"></span>
                    </td>
                </tr>
                <tr>
                    <td>金额:</td>
                    <td>
                        <input type="text" name="money" id="money" value="">
                        <span id="moneySpan"></span>
                    </td>
                </tr>
                <tr>
                    <td>收款账号:</td>
                    <td>
                        <input type="text" id="inId" name="inId" value="">
                    </td>
                </tr>
                <tr>
                    <td>收款人姓名:</td>
                    <td>
                        <input type="text" id="inName"  value="">
                        <span id="inNameSpan"></span>
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                        <input type="button" id="btn" value="开始转账">
                    </td>
                </tr>
            </table>
        </form>
    </div>
</body>
</html>

在这里插入图片描述

6.CheckAccountServlet

package com.bjsxt.controller;

import com.bjsxt.pojo.Account;
import com.bjsxt.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) 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");
            }
    }
    //校验收款人信息
    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");
    }
    //校验金额
    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");
    }

    //声明方法:校验转账账户信息
    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");
    }


}

7.CheckAccountService

package com.bjsxt.service;

import com.bjsxt.pojo.Account;

public interface CheckAccountService {
    //校验转账账户信息
    Account checkOutAccountInfoService(String outId,String outPwd);
    //校验金额
    Account checkMoneyInfoService(String outId, String money);
    //校验收款人信息
    Account checkInInfoService(String inId, String inName);
    //转账功能
    int transferInfoService(String outId, String inId, String money);
}

8.CheckAccountServiceImpl

package com.bjsxt.service.impl;

import com.bjsxt.mapper.CheckAccountMapper;
import com.bjsxt.pojo.Account;
import com.bjsxt.service.CheckAccountService;

public class CheckAccountServiceImpl implements CheckAccountService {
    //声明mapper层属性
    private CheckAccountMapper checkAccountMapper;

    public CheckAccountMapper getCheckAccountMapper() {
        return checkAccountMapper;
    }

    public void setCheckAccountMapper(CheckAccountMapper checkAccountMapper) {
        this.checkAccountMapper = checkAccountMapper;
    }
    //转账功能
    @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;
    }
    //校验收款人信息
    @Override
    public Account checkInInfoService(String inId, String inName) {
        return checkAccountMapper.checkInInfoMapper(inId,inName);
    }

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

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

9.CheckAccountMapper

package com.bjsxt.mapper;

import com.bjsxt.pojo.Account;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

public interface CheckAccountMapper {
    //校验转账账户信息:根据账户ID和密码获取账户信息
    @Select("select * from t_account where aid=#{outId} and apwd=#{outPwd}")
    Account checkAccountOutInfoMapper(@Param("outId") String outId, @Param("outPwd") String outPwd);
    //校验金额
    @Select("select * from t_account where aid=#{outId} and money>=#{money}")
    Account checkMoneyInfoMapper(@Param("outId") String outId, @Param("money") String money);
    //校验收款人信息
    @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);
    //转出
    @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);
}

10.登录日志

(1) 功能点需求:

我们的银行转账功能,在刚开始运营的时候,并没有用户登录的日志信息的记录。

后来,某天某个客户他的账号被登录了,但是给该客户又不知道是什么时间进行的

登录,造成调查有困扰,怎么办?在当前登录功能的基础上,增加登录日志,来记 录用户的登录信息。便于我们后期的排查。

(2) 功能分析:

在保留当前登录功能的基础上,完成对登录功能的扩展。但是又不希望改变原有的

功能代码逻辑。考虑使用SpringAOP。

前置通知:在日志文件中输出XXX在XXX时间发起了登录请求

切点:登录的业务方法

后置通知:在日志文件中输出XXX在XXX时间登录成功

建议使用SchemaBased方式实现。

(3) 功能实现:

i. 在lib下导入AOP的jar包

ii. 在src下创建com.bjsxt.advice的包

iii. 在advice包中创建前置通知和后置通知

package com.bjsxt.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]+"发起了登录请求");
    }
}
package com.bjsxt.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]+"登录成功");
        }

    }
}

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以及组装规则

测试:ok!

在这里插入图片描述

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值