前期准备 数据库准备
在ssm数据库下通过查询建立account表
导入jar包
准备全局配置文件mybatis.xml文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <setting name="logImpl" value="LOG4J"/> </settings> <typeAliases> <package name="com.bjsxt.pojo"/> <!-- 起别名 方便在配置的xml里面直接返回值就可以只写类名--> </typeAliases> <environments default="default"> <environment id="default"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/ssm"/> <property name="username" value="root"/> <property name="password" value="njdxrjgc7777777."/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/bjsxt/mapper/AccountMapper.xml"/> <!-- 直接调用配置文件 执行sql语句 --> </mappers> </configuration>
准备pojo包的实体类Account 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public class Account { private int id; private String accNo; private int password; private String name; private double balance; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAccNo() { return accNo; } public void setAccNo(String accNo) { this.accNo = accNo; } public int getPassword() { return password; } public void setPassword(int password) { this.password = password; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } }
准备mapper包下的AccountMapper.xml文件
通过分析我们要有三个任务:分别是写在三个select标签下完成对应任务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?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="com.bjsxt.mapper.AccountMapper"> <!-- 根据帐号和密码查询账户信息 --> <select id="selByAccnoPwd" resultType="account" parameterType="account"> //id就是此方法名称 resultType就是返回值类型 select * from account where accno=#{accNo} and password=#{password} </select> <!-- 根据帐号和姓名查询账户信息 --> <select id="selByAccnoName" resultType="account" parameterType="account"> select * from account where accno=#{accNo} and name=#{name} </select> <!-- 根据accNo修改账户余额 --> <update id="updBalanceByAccno" parameterType="account"> update account set balance=balance+#{balance} where accno=#{accNo} </update> </mapper>
准备serive包下的AccountService接口 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public interface AccountService { //帐号和密码不匹配状态码 int ACCOUNT_PASSWORD_NOT_MATCH=1; //余额不足 int ACCOUNT_BALANCE_NOT_ENOUGH=2; //账户姓名不匹配 int ACCOUNT_NAME_NOT_MATCH=3; //转账失败 int ERROR=4; //转账成功 int SUCCESS=5; //转账功能 int transfer(Account accIn,Account accOut) throws IOException; }
准备1.0版本的serviceimpl包 准备思路:
1. 先判断账号和密码是否匹配 (调用方法查sql语句)
2. 然后判断是否有足够转账金额 (判断账号密码查信息返回给account类 然后调用balance去判断是否足够)
3. 判断收款人账号和名字是否正确
4. 然后进行转账交易 (调用方法 一个减少一个增加)
5. 判断是不是成功
5.1 成功就session.commit()提交 -- session.close()关闭 -- 返回成功的结果值
5.2 失败就session.rollback()回滚 --session.close()关闭 -- 返回失败的结果值
实现类实现初级1.0事务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 public class AccountServiceImpl implements AccountService { @Override public int transfer(Account accIn, Account accOut) throws IOException { //固定的三行生产出session InputStream is = Resources.getResourceAsStream("mybatis.xml"); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); SqlSession session = factory.openSession(); //先判断帐号和密码是否匹配 Account accOutSelect = session.selectOne("com.bjsxt.mapper.AccountMapper.selByAccnoPwd",accOut); //根据账号和密码查询 if(accOutSelect!=null){ //账号和密码匹配 if(accOutSelect.getBalance()>=accOut.getBalance()) { //余额够 Account accInSelect = session.selectOne("com.bjsxt.mapper.AccountMapper.selByAccnoName",accIn); //根据账号和姓名查询 if(accInSelect!=null) { accOut.setBalance(-accOut.getBalance()); //set设置一下为负数 int index=session.update("com.bjsxt.mapper.AccountMapper.updBalanceByAccno",accOut); //如果传的是accOut 就需要的是扣除交易额 index += session.update("com.bjsxt.mapper.AccountMapper.updBalanceByAccno",accIn); //转账过去 if(index==2) { session.commit(); //成功就提交 session.close(); return SUCCESS; }else { session.rollback(); //失败就要回滚 session.close(); return ERROR; } }else { return ACCOUNT_NAME_NOT_MATCH; //账号和姓名不匹配 } }else { return ACCOUNT_BALANCE_NOT_ENOUGH; //余额不足 } }else{ return ACCOUNT_PASSWORD_NOT_MATCH; // 账号和密码 不匹配 } } }
准备servlet包下的TransferServlet类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 @WebServlet("/transfer") public class TransferServlet extends HttpServlet { //面向接口编程 private AccountService accService = new AccountServiceImpl(); @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //需要使用到中文 req.setCharacterEncoding("utf-8"); //获取转账人的信息 Account accOut = new Account(); accOut.setAccNo(req.getParameter("accOutAccNo")); accOut.setPassword(Integer.parseInt(req.getParameter("accOutPassword"))); accOut.setBalance(Double.parseDouble(req.getParameter("accOutBalance"))); //获取收款人信息 Account accIn =new Account(); accIn.setAccNo(req.getParameter("accInAccNo")); accIn.setName(req.getParameter("accInName")); //通过面向接口编程 调用转账功能 int index = accService.transfer(accIn, accOut); if(index==AccountService.SUCCESS) //转账成功的返回值和 service的静态success对比 { resp.sendRedirect("/bank/show"); //成功跳转到展示页面 } else { HttpSession session = req.getSession(); session.setAttribute("code", index); // 获得状态码 resp.sendRedirect("/bank/error/error.jsp"); //新建的error文件下的error.jsp页面 } } }
准备登陆/失败/转账查询的页面 log显示成功界面 1 2 3 <body> 成功的log.jsp </body>
index主页面界面 1 2 3 4 5 6 7 8 9 10 11 12 <body> <form action="transfer" method="post"> //写一个页表 -- servlet类 转账账户:<input type="text" name="accOutAccNo"/><br/> 密码:<input type="password" name="accOutPassword"/><br/> 金额:<input type="text" name="accOutBalance"/><br/> 收款帐号:<input type="text" name="accInAccNo"/><br/> 收款姓名:<input type="text" name="accInName"/><br/> <input type="submit" value="转账"/> </form> </body>
error错误界面 1 2 3 4 5 <body> 对不起操作失败:<br/> 错误原因: ${sessionScope.code} //通过jsp方式传出错误的原因对应的service的数字 </body>
准备log4j (查错) 带入jar包和配置文件log4j.properties 1 2 3 4 5 6 7 8 9 10 11 12 13 log4j.rootCategory=ERROR, CONSOLE ,LOGFILE //显示设置error去查找错误 log4j.logger.com.bjsxt.mapper=DEBUG //给这个包添加log4j文件 log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%C %d{YYYY-MM-dd hh:mm:ss} %m %n log4j.appender.LOGFILE=org.apache.log4j.FileAppender log4j.appender.LOGFILE.File=E:/my.log log4j.appender.LOGFILE.Append=true log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout log4j.appender.LOGFILE.layout.ConversionPattern=%m %n
全局配置文件中配置log4j 1 2 3 <settings> <setting name="logImpl" value="LOG4J"/> </settings>
执行结果
日志记录 创建表log 1 2 3 4 5 6 create table log( id int(10) primary key auto_increment, accout varchar(18), accin varchar(8), money double );
新增log实体类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public class Log { private int id; private String accIn; private String accOut; private double money; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAccIn() { return accIn; } public void setAccIn(String accIn) { this.accIn = accIn; } public String getAccOut() { return accOut; } public void setAccOut(String accOut) { this.accOut = accOut; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } }
新增关于log表的配置xml文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <?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="com.bjsxt.mapper.LogMapper"> <insert id="insLog" parameterType="log"> insert into log values(default,#{accOut},#{accIn},#{money}) //添加数据 </insert> <select id="selByPage" parameterType="map" resultType="log"> //分页 select * from log limit #{pageStart},#{pageSize} </select> <select id="selCount" resultType="long"> //查询所有 select count(*) from log </select> </mapper>
在serviceimpl实现类添加 1 2 3 4 5 6 7 8 //在已经转账成功 index==2之后添加 Log log=new Log(); log.setAccIn(accIn.getAccNo()); //取出来所有信息然后添加到log实体类对象 log.setAccOut(accOut.getAccNo()); log.setMoney(accIn.getBalance()); session.insert("com.bjsxt.mapper.LogMapper.insLog",log); //转账成功就添加到log表里面
日志文件显示转账信息(log4j) 1 2 3 4 5 6 //1. 要在log4j配置文件内更改: log4j.appender.LOGFILE.layout.ConversionPattern=%m %n //最后要是%m %n //2. 在刚才的实现类代码下添加日志文件记录(同时将log4j第一行的异常给一个info才可以显示) Logger logger=Logger.getLogger(AccountServiceImpl.class); logger.info(log.getAccOut()+"给"+log.getAccOut()+"在"+new Date().toLocaleString()+"转了"+log.getMoney()); //在log4j的五种异常中选info异常
分页展示功能 mapper包xml里面添加分页功能的sql语句 1 2 3 4 5 6 7 <select id="selByPage" parameterType="map" resultType="log"> //分页 select * from log limit #{pageStart},#{pageSize} </select> <select id="selCount" resultType="long"> //查询所有 select count(*) from log </select>
添加分页显示的实体类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public class PageInfo { private int pageSize; private int pageNumber; private long total; private List<?> list; public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public int getPageNumber() { return pageNumber; } public void setPageNumber(int pageNumber) { this.pageNumber = pageNumber; } public long getTotal() { return total; } public void setTotal(long total) { this.total = total; } public List<?> getList() { return list; } public void setList(List<?> list) { this.list = list; } }
service层接口实现方法 1 2 3 4 5 6 7 8 9 public interface LogService { /** * 分页显示 * @param pageSize * @param pageNumber * @return */ PageInfo showPage(int pageSize,int pageNumber) throws IOException; }
service实现类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public class LogServiceImpl implements LogService { @Override public PageInfo showPage(int pageSize, int pageNumber) throws IOException { //固定三行 InputStream is = Resources.getResourceAsStream("mybatis.xml"); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); SqlSession session = factory.openSession(); Map<String,Object> param = new HashMap<>(); param.put("pageStart",pageSize*(pageNumber-1)); //获取当前页要从第几个开始 param.put("pageSize", pageSize); //获取一页展示几个 List<Log> list = session.selectList("com.bjsxt.mapper.LogMapper.selByPage",param); //param是一个map 创建一个map 将最后的map集合的值给log实体类 long count = session.selectOne("com.bjsxt.mapper.LogMapper.selCount"); //查询总数 PageInfo pi = new PageInfo(); //分页类实现对象(四个属性) pi.setList(list); pi.setPageNumber(pageNumber); pi.setPageSize(pageSize); pi.setTotal(count%pageSize==0?count/pageSize:count/pageSize+1); //算出来总共几个几页 return pi; } }
准备servlet类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @WebServlet("/show") public class ShowServlet extends HttpServlet { private LogService logService = new LogServiceImpl(); @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { int pageSize = 2; String pageSizeStr = req.getParameter("pageSize"); //获取一页有几个 if(pageSizeStr!=null&&!pageSizeStr.equals("")){ pageSize = Integer.parseInt(pageSizeStr); //强转 } int pageNumber = 1; String pageNumberStr = req.getParameter("pageNumber"); //获取有几页 if(pageNumberStr!=null&&!pageNumberStr.equals("")){ pageNumber = Integer.parseInt(pageNumberStr); //强转 } //最后跳转 req.setAttribute("pageinfo", logService.showPage(pageSize, pageNumber)); req.getRequestDispatcher("/log.jsp").forward(req, resp); //跳转 } }
书写log.jsp页面 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <table border="1"> <tr> <th>转账帐号</th> <th>收款帐号</th> <th>转账金额</th> </tr> <c:forEach items="${pageinfo.list}" var="log"> <tr> <td>${log.accOut }</td> <td>${log.accIn }</td> <td>${log.money }</td> </tr> </c:forEach> </table> <a href="show?pageSize=${pageinfo.pageSize }&pageNumber=${pageinfo.pageNumber-1}" <c:if test="${pageinfo.pageNumber<=1 }"> onclick="javascript:return false;"</c:if>>上一页</a> <a href="show?pageSize=${pageinfo.pageSize }&pageNumber=${pageinfo.pageNumber+1}" <c:if test="${pageinfo.pageNumber>=pageinfo.total }"> onclick="javascript:return false;"</c:if>>下一页</a> </body> </html>
全局配置文件添加mappers 1 2 3 4 <mappers> <mapper resource="com/bjsxt/mapper/AccountMapper.xml"/> <!-- 直接调用配置文件 执行sql语句 --> <mapper resource="com/bjsxt/mapper/LogMapper.xml"/> <!-- 直接调用配置文件 执行sql语句 --> </mappers>
总结 最终代码结构:
最终结果:
<
getMapper接口绑定和多参数传递
Mybatis实现分页功能(完整流程)
>