15.mvc和分页

文章目录

      • MVC和分页
        • 第一节 MVC模式简介
          • 1.1 MVC概念
          • 1.2 MVC模式详解
          • 1.3 MVC高级框架应用
        • 第二节 JSP开发模型
          • 2.1 JavaWeb经历两个时期
            • 2.1.1 JSP Model1
            • 2.1.2 JSP Model2
          • 2.2基于MVC的三层架构的实现
        • 第三节 MVC结合事务练习
          • 3.1 项目准备
          • 3.2 编写前端页面
          • 3.3 准备编写java代码
            • 3.3.1 项目分包
            • 3.3.2 编写DataSourceUtils工具类
            • 3.3.3 编写Dao层代码
            • 3.3.4 编写业务层代码
            • 3.3.5 编写servlet代码
          • 3.4防止表单重复提交
        • 第四节 分页概述
          • 4.1 分页实现思路
          • 4.2 分页代码实现
            • 4.2.1 数据库表语句如下
            • 4.4.2 创建工程和程序包
            • 4.4.3 数据库配置文件db.properties
            • 4.4.4 创建实体类和工具类
            • 4.4.5 创建Dao和实现类
            • 4.4.6 创建Servie和实现类
            • 4.4.7 listStudent.jsp页面
        • 总结

MVC和分页

第一节 MVC模式简介

1.1 MVC概念

​ 首先我们需要知道MVC模式并不是javaweb项目中独有的,MVC是一种软件工程中的一种设计模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller),即为MVC。它是一种软件设计的典范,最早为Trygve Reenskaug提出,为施乐帕罗奥多研究中心(Xerox PARC)的Smalltalk语言发明的一种软件设计模式。

1.2 MVC模式详解

虽然MVC并不是Java当中独有的,但是现在几乎所有的B/S的架构都采用了MVC框架模式。

  • 控制器Controller:控制器即是控制请求的处理逻辑,对请求进行处理,负责请 求转发和重定向;
  • 视图View:视图即是用户看到并与之交互的界面,比如HTML(静态资源),JSP(动态资源)等等。
  • 模型Model:模型代表着一种企业规范,就是业务流程/状态的处理以及业务规则的规定。业务流程的处理过程对其他层来说是不透明的,模型接受的请求,并返回最终的处理结果。业务模型的设计可以说是MVC的核心。
1.3 MVC高级框架应用

​ MVC模式被广泛用于Java的各种框架中,比如Struts2、spring MVC等等都用到了这种思想。

Struts2是基于MVC的轻量级的web应用框架。基于MVC,说明基于Struts2开发的Web应用自然就能实现MVC,也说明Struts2着力于在MVC的各个部分为我们的开发提供相应帮助。

第二节 JSP开发模型

2.1 JavaWeb经历两个时期
2.1.1 JSP Model1

JSP Model1是JavaWeb早期的模型,它适合小型Web项目,开发成本低!Model1第一代时期,服务器端只有JSP页面,所有的操作都在JSP页面中,连访问数据库的API也在JSP页面中完成。也就是说,所有的东西都耦合在一起,对后期的维护和扩展极为不利。

15.mvc和分页_第1张图片

JSP Model1的优化(Model1第二代)

JSP Model1优化后有所改进,把业务逻辑和数据访问的内容放到了JavaBean(狭义JavaBean:实体类,广义JavaBean:实体类,dao,service,工具类)中,而JSP页面负责显示以及请求调度的工作。虽然第二代比第一代好了些,但还让JSP做了过多的工作,JSP中把视图工作和请求调度(控制器)的工作耦合在一起了。

15.mvc和分页_第2张图片

2.1.2 JSP Model2

JSP Model2模式已经可以清晰的看到MVC完整的结构了。

JSP:视图层,用来与用户打交道。负责接收数据,以及显示数据给用户;

Servlet:控制层,负责找到合适的模型对象来处理业务逻辑,转发到合适的视图;

JavaBean:模型层,完成具体的业务工作,例如:开启事务、转账等。

15.mvc和分页_第3张图片

小结:这就是javaweb经历的两个时期,JSP Model2适合多人合作开发大型的Web项目,各司其职,互不干涉,有利于开发中的分工,有利于组件的重用。但是,Web项目的开发难度加大,同时对开发人员的技术要求也提高了。

2.2基于MVC的三层架构的实现

虽然MVC把程序分成三部分,每个部分负责不同的功能,但是这只是逻辑的分离,实际代码并没有真正分离,特别是Model(包括业务、数据访问和实体类、工具类等)部分的代码,为了增强代码的维护性和降低代码耦合性,需要把代码分层管理,于是就有了三层架构:

分别是:web层(表示|界面层)、service层(业务逻辑层)、dao层(数据访问层、持久层)

15.mvc和分页_第4张图片

web层对应MVC中的Servlet和JSP

其他层都属于MVC中的Model

15.mvc和分页_第5张图片

第三节 MVC结合事务练习

通过结合事务和MVC知识,练习一个转账demo

ThreadLocal:线程局部变量:作用实现把数据绑定到线程中,从而实现线程安全。

3.1 项目准备
  • 创建web项目

  • 导入需要jar包

    mysql驱动

​ druid.jar

​ commons-beanutils-1.8.3.jar

​ commons-collections.jar

​ commons-dbutils-1.4.jar

​ commons-logging-1.1.1.jar

  • 添加数据库配置文件

    db.properties

#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/myschool
username=root
password=root
#
initialSize=10
#最大连接数量
maxActive=50
#
minIdle=5
#
maxWait=5000
3.2 编写前端页面
  • 转账页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>



  
    
    
    My JSP 'transfer.jsp' starting page
    
	
	
	    
	
	
	

  
  
  
      
      
转出方:
转入方:
金额

3.3 准备编写java代码

因为要使用到mvc模式,要对项目代码进行分包

3.3.1 项目分包

​ com.qf.dao

​ com.qf.dao.impl

​ com.qf.service

​ com.qf.service.impl

​ com.qf.web.servlet

​ com.qf.utils

​ com.qf.domain

3.3.2 编写DataSourceUtils工具类

DatasoutceUtils工具类,优化获取连接,优化事务操作

ThreadLocal的实例代表了一个线程局部的变量,每条线程都只能看到自己的值,并不会意识到其它的线程中也存在该变量。它采用采用空间来换取时间的方式,解决多线程中相同变量的访问冲突问题。

package com.itqf.utils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.DataSource;

import com.qf.utils.DruidUtils;

public class DataSourceUtils {
	private static DruidDataSource ds=null;
	
	private static ThreadLocal<Connection> tl=new ThreadLocal<Connection>();
   //静态代码块
    static {
        InputStream is = DruidUtils.class.getClassLoader().getResourceAsStream("db.properties");
        Properties properties=new Properties();
        try {
            properties.load(is);
            dataSource= (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
	/**
	 * 获取数据源
	 * @return 连接池
	 */
	public static DataSource getDataSource(){
		return ds;
	}
	
	/**
	 * 从当前线程上获取连接
	 * @return 连接
	 * @throws SQLException
	 */
	public static Connection getConnection() throws SQLException{
		//-- 从线程获取链接
		Connection conn = tl.get();
		if(conn==null){
			//第一次获取 创建一个连接 和当前的线程绑定
			 conn=ds.getConnection();
			 
			 //----绑定
			 tl.set(conn);
		}
		return conn;
	}
	
	/**
	 * ---释放资源
	 * 
	 * @param conn
	 *            连接
	 * @param st
	 *            语句执行者
	 * @param rs
	 *            结果集
	 */
	public static void closeResource(Connection conn, Statement st, ResultSet rs) {
		closeResource(st, rs);
		closeConn(conn);
	}
	
	 
	public static void closeResource(Statement st, ResultSet rs) {
			closeResultSet(rs);
			closeStatement(st);
	}

	/**
	 * 释放连接
	 * 
	 * @param conn
	 *            连接
	 */
	public static void closeConn(Connection conn) {
		if (conn != null) {
			try {
              	//----和当前的线程解绑
				tl.remove();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			conn = null;
		}

	}

	/**
	 * 释放语句执行者
	 * 
	 * @param st
	 *            语句执行者
	 */
	public static void closeStatement(Statement st) {
		if (st != null) {
			try {
				st.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			st = null;
		}

	}

	/**
	 * 释放结果集
	 * 
	 * @param rs
	 *            结果集
	 */
	public static void closeResultSet(ResultSet rs) {
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			rs = null;
		}

	}
	
	/**
	 *---- 开启事务
	 * @throws SQLException
	 */
	public static void startTransaction() throws SQLException{
		//获取连接//开启事务
		getConnection().setAutoCommit(false);;
	}
	
	/**
	 *--- 事务提交
	 */
	public static void commitAndClose(){
		try {
			//获取连接
			Connection conn = getConnection();
			//提交事务
			conn.commit();
			//释放资源
			conn.close();
			//解除绑定
			tl.remove();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * ----事务回滚
	 */
	public static void rollbackAndClose(){
		try {
			//获取连接
			Connection conn = getConnection();
			//事务回滚
			conn.rollback();
			//释放资源
			conn.close();
			//解除绑定
			tl.remove();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}
3.3.3 编写Dao层代码

dao层进行具体数据库操作

package com.itqf.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;

import com.itqf.utils.DataSourceUtils;
import com.itqf.utils.JdbcUtils;

public class AccountDaoImpl{

	
	/**
	 * 转出钱
	 * @param from
	 * @param money
	 * @throws SQLException 
	 */
	public void out(String from, String money) throws SQLException {
		// TODO Auto-generated method stub
		//创建 queryrunner
		QueryRunner queryRunner = new QueryRunner();
		//编写sql
		String sql ="update account set money = money - ? where name = ?";
		
		//执行sql
		//手动传入
		queryRunner.update(DataSourceUtils.getConnection(),sql,money,from);
		//不要调DButils操作
		//DbUtils.close(conn);
	}
    
	/*
	 * 转入操作
	 */
	public void in(String to, String money) throws SQLException {
		// TODO Auto-generated method stub
		QueryRunner queryRunner = new QueryRunner();
		//编写sql
		String sql ="update account set money = money + ? where name = ?";
		
		//执行sql
		//手动传入
		queryRunner.update(DataSourceUtils.getConnection(),sql,money,to);
		//不要调DButils操作
	}

}

3.3.4 编写业务层代码
package com.itqf.service;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Savepoint;

import com.itqf.dao.AccountDao;
import com.itqf.dao.AccountDaoDButis;
import com.itqf.dao.AccountDaoLocal;
import com.itqf.utils.DataSourceUtils;
import com.itqf.utils.JdbcUtils;
/**
 * jdbc+threadlocal
 * 
 * @author Administrator
 *
 */
public class AccountServiceImpl {
    
	/**
	 * 转账业务逻辑
	 * @param from
	 * @param to
	 * @param money
	 * @throws Exception 
	 */
	public  void transfer(String from, String to,String money) throws Exception {
		// TODO Auto-generated method stub
		AccountDaoDButis accountDao = new AccountDaoDButis();
		
		
		try {
			//开启事务
			DataSourceUtils.startTransaction();
			//1.转出
			accountDao.out(from,money);
			int z = 1/0;
			//2.转入
			accountDao.in(to,money);
			DataSourceUtils.commitAndClose();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			
			DataSourceUtils.rollbackAndClose();
			throw e; //接着向外抛
		}
	}

}

3.3.5 编写servlet代码
package com.itqf.web.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.itqf.service.AccountService;
import com.itqf.service.AccountServiceDButil;
import com.itqf.service.AccountServiceLocal;

public class AccountServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		 //设置编码格式
		  request.setCharacterEncoding("UTF-8");
		  response.setContentType("text/html;charset=UTF-8");	
		  PrintWriter writer = response.getWriter();
		 //获取表单数据
		 String from = request.getParameter("outaccount");
		 String  to   = request.getParameter("intaccount");
		 String money = request.getParameter("money");
		//调用业务逻辑
		 AccountServiceDButil accountService = new AccountServiceDButil();
		 try {
			 accountService.transfer(from,to,money);
			//分发转向
			writer.print("转账成功!");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			writer.print("转账失败!");
		};
		 
		
	}

	/**
		 * The doPost method of the servlet. 
* * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
3.4防止表单重复提交

常见用两种方式

1 通过JavaScript屏蔽提交按钮(不推荐)

通过js代码,当用户点击提交按钮后,屏蔽提交按钮使用户无法点击提交按钮或点击无效,从而实现防止表单重复提交。
缺点:js代码很容易被绕过。比如用户通过刷新页面方式,或使用postman等工具绕过前段页面仍能重复提交表单。因此不推荐此方法。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
        
        <html>
        <head>
         <title>表单title>
            <script type="text/javascript">
            //默认提交状态为false
            var commitStatus = false;
            function dosubmit(){
                  if(commitStatus==false){
                //提交表单后,将提交状态改为true
                  commitStatus = true;  
                  return true;
                 }else{
                  return false;
              }
             }
      script>
     head>
   
        <body>
            <form action="/path/post" onsubmit="return dosubmit()" method="post" target="_blank">
             用户名:<input type="text" name="username">
            <input type="submit" value="提交" id="submit">
            form>
        body>
    html>

2 利用Session防止表单重复提交(推荐)

实现原理:
服务器返回表单页面时,会先生成一个subToken保存于session,并把该subToken传给表单页面。当表单提交时会带上subToken,服务器判断session中的subToken和表单提交subToken是否一致。若不一致或session的subToken为空或表单未携带subToken则不通过。

首次提交表单时session的subToken与表单携带的subToken一致走正常流程,然后服务器会删除session保存的subToken。当再次提交表单时由于session的subToken为空则不通过。从而实现了防止表单重复提交。

代码如下:

TokenProccessor.java

package com.qf.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

/**
 * wgy 2019/4/23 11:47
 */
public class TokenProccessor {
    private TokenProccessor(){}
    private static  final  TokenProccessor instance=new TokenProccessor();
    public static TokenProccessor getInstance(){
        return instance;
    }
    public String makeToken(){
        String str=System.currentTimeMillis()+new Random().nextInt(999999999)+"";

        try {
            //1使用md5加密
            MessageDigest digest=MessageDigest.getInstance("md5");
            digest.update(str.getBytes());
            byte[] digest1 = digest.digest();
            //2使用base64
            return Base64.getEncoder().encodeToString(digest);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

TokenTools.java

package com.qf.utils;

import javax.servlet.http.HttpServletRequest;

/**
 * wgy 2019/4/23 11:54
 */
public class TokenTools {

    //把token放入session
    public static void createToken(HttpServletRequest request,String tokenkey){
        String token=TokenProccessor.getInstance().makeToken();
        request.getSession().setAttribute(tokenkey, token);
    }
    //把token从session删除
    public static void removeToken(HttpServletRequest request,String tokenkey){
        request.getSession().removeAttribute(tokenkey);
    }
}

tranview.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>转账title>

    <script type="text/javascript">
        //默认提交状态为false
        var commitStatus = false;
        function dosubmit(){
            if(commitStatus==false){
                //提交表单后,将提交状态改为true
                commitStatus = true;
                document.getElementById("btnsubmit").disabled=true;
                return true;
            }else{
                return false;
            }
        }
     script>
head>
<body>
   <%
      //向session中添加令牌
      TokenTools.createToken(request, "mytoken");
    %>
<h2>转账h2>
    <form action="${pageContext.request.contextPath}/trans" onsubmit="return dosubmit()" method="post" target="_blank">
        <input type="text" name="from" placeholder="请输入转出账号"><br/>
        <input type="text" name="to" placeholder="请输入转入账号"><br/>
        <input type="text" name="money" placeholder="请输入金额"><br/>
        <input type="hidden" name="mytoken" value="${mytoken}">
        <input id="btnsubmit" type="submit" value="转账">
    form>
body>
html>

TransServlet.java

package com.qf.web.servlet;

import com.qf.domain.Account;
import com.qf.service.AccountService;
import com.qf.service.impl.AccountServiceImpl;
import com.qf.utils.TokenTools;

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;
import java.math.BigDecimal;

/**
 * wgy 2019/4/23 11:05
 */
@WebServlet(name = "TransServlet",urlPatterns = "/trans")
public class TransServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        //判断是否是重复提交
        boolean b=isRepeatSubmit(request, "mytoken");
        if(b){
            response.getWriter().write("不好意思,重复提交了...");
            return;
        }
        //通过验证
        TokenTools.createToken(request, "mytoken");

        //接受数据
        String from = request.getParameter("from");
        String to = request.getParameter("to");
        String money = request.getParameter("money");
        //验证金额
        BigDecimal m=new BigDecimal(money);
        if(m.doubleValue()<=0){
            response.getWriter().write("转账金额不能小于0");
            return;
        }
        //转账
        AccountService accountService=new AccountServiceImpl();
        Account accfrom=new Account(Integer.parseInt(from),"宁宁",new BigDecimal(0));
        Account accto=new Account(Integer.parseInt(to),"春春",new BigDecimal(0));
        try {
            accountService.transMoney(accfrom, accto, m);
            response.getWriter().write("转账成功");
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().write("转账失败");
        }


    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    public boolean isRepeatSubmit(HttpServletRequest request,String clientTokeyKey){
        //1 判断session有没有
        String serverToken = (String) request.getSession().getAttribute(clientTokeyKey);
        if(serverToken==null){
            return true;
        }

        //2 判断客户端有没有token
        String clientToken=request.getParameter(clientTokeyKey);
        if(clientToken==null){
            return true;
        }


        //3 两个是否相同
        if(!serverToken.equals(clientToken)){
            return  true;
        }

        return  false;

    }
}

第四节 分页概述

​ 分页是web应用程序非常重要的一个技术。数据库中的数据可能是成千上万的,不可能把这么多的数据一次显示在浏览器上面。一般根据每行数据在页面上所占的空间每页显示若干行,比如一般20行是一个比较理想的显示状态。

4.1 分页实现思路

分页的思路

对于海量的数据查询,需要多少就取多少,显然是最佳的解决方法,假如某个表中有200万条记录,第一页取前20条,第二页取21~40条记录。

select * from 表名 order by id limit 0,20 ;

select * from 表名 order by id limit 20,20;

select * from 表名 order by id limit 40,20;

4.2 分页代码实现

步骤:

1.确定每页显示的数据数量

2.确定分页显示所需的总页数

3.编写SQL查询语句,实现数据查询

4.在JSP页面中进行分页显示设置

代码实现如下:

4.2.1 数据库表语句如下

create database day16;

   use day16;
   create table student(
	 studentNo int(4) NOT NULL,
	 loginPwd varchar(20) NOT NULL,
	 studentName varchar(50) NOT NULL,
	 sex char(2) NOT NULL,
	 bornDate datetime
   );
   -- 向数据库中添加100条添加记录

4.4.2 创建工程和程序包

[外链图片转存失败(img-TJvxEqZf-1567856749561)(pic/01.jpg)]

4.4.3 数据库配置文件db.properties
#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/myschool
username=root
password=root
#
initialSize=10
#最大连接数量
maxActive=50
#
minIdle=5
#
maxWait=5000

4.4.4 创建实体类和工具类

Student类

package com.qf.myschool.domain;

import java.util.Date;

/**
 * 学生类
 * @author wgy
 */
public class Student {
		private int studentNo;
		private String loginPwd;
		private String studentName;
		private String sex;
		private Date bornDate;
		public Student() {
			// TODO Auto-generated constructor stub
		}
		public Student(int studentNo, String loginPwd, String studentName, String sex, Date bornDate) {
			super();
			this.studentNo = studentNo;
			this.loginPwd = loginPwd;
			this.studentName = studentName;
			this.sex = sex;
			this.bornDate = bornDate;
		}
		public int getStudentNo() {
			return studentNo;
		}
		public void setStudentNo(int studentNo) {
			this.studentNo = studentNo;
		}
		public String getLoginPwd() {
			return loginPwd;
		}
		public void setLoginPwd(String loginPwd) {
			this.loginPwd = loginPwd;
		}
		public String getStudentName() {
			return studentName;
		}
		public void setStudentName(String studentName) {
			this.studentName = studentName;
		}
		public String getSex() {
			return sex;
		}
		public void setSex(String sex) {
			this.sex = sex;
		}
		public Date getBornDate() {
			return bornDate;
		}
		public void setBornDate(Date bornDate) {
			this.bornDate = bornDate;
		}
		@Override
		public String toString() {
			return "Student [studentNo=" + studentNo + ", loginPwd=" + loginPwd + ", studentName=" + studentName
					+ ", sex=" + sex + ", bornDate=" + bornDate + "]";
		}
		
}

PageBean类

package com.qf.myschool.domain;

import java.util.List;

/**
 * 页面数据类
 * @author wgy
 *
 */
public class PageBean<T> {
	//页码
	private int pageIndex;
	//页大小
	private int pageSize;
	//总数据据个数
	private int totalSize;
	//总页数
	private int pageCount;
	//页面数据
	private List<T> data;

	public PageBean(){
	}

	public PageBean(int pageIndex,int pageSize,int totalSize,List<T> data){
		this.pageIndex=pageIndex;
		this.totalSize=totalSize;
      	this.pageSize=pageSize;
      	this.data=data;
		//计算总页数
		pageCount=totalCount%pageSize==0?totalCount/pageSize:totalCount/pageSize+1;
		
	}

	public int getPageIndex() {
		return pageIndex;
	}

	public void setPageIndex(int pageIndex) {
		this.pageIndex = pageIndex;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getTotalSize() {
		return totalCount;
	}

	public void setTotalSize(int totalSize) {
		this.totalSize = totalSize;
	}

	public int getPageCount() {
		return pageCount;
	}

	public void setPageCount(int pageCount) {
		this.pageCount = pageCount;
	}

	public List<T> getData() {
		return data;
	}

	public void setData(List<T> data) {
		this.data = data;
	}
}

DruidUtils类

package com.qf.myschool.utils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.alibaba.druid.pool.DruidDataSource;
import com.mysql.jdbc.SQLError;

/**
 * 1加载驱动
 * 2建立连接
 * 3释放资源
 * 4更新操作
 * @author wgy
 *
 */
public class DruidUtils {
	private static DruidDataSource dataSource=null;
	 
    static {
        InputStream is = DruidUtils.class.getClassLoader().getResourceAsStream("db.properties");
        Properties properties=new Properties();
        try {
            properties.load(is);
            dataSource= (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
	
	public static DataSource getDataSource(){
        return  dataSource;
    }
	
	

4.4.5 创建Dao和实现类

StudentDao接口

package com.qf.myschool.dao;

import java.util.List;

import com.qf.myschool.domain.Student;

public interface StudentDao {
	/**
	 * 
	 * @param pageIndex 当前页码  1 
	 * @param pagesize  页大小  10
	 * @return
	 * 
	 */
	public List<Student> findByPage(int pageIndex,int pagesize);
	
	//获取总的数据个数
	public int getTotalCount();
	
}	

StudentDaoImpl类

package com.qf.myschool.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.qf.myschool.dao.StudentDao;
import com.qf.myschool.domain.Student;
import com.qf.myschool.utils.DbUtils;

public class StudentDaoImpl implements StudentDao {
	@Override
	public List<Student> findByPage(int pageIndex, int pagesize) {
		// TODO Auto-generated method stub
		Connection conn=null;
		PreparedStatement pstat=null;
		ResultSet rs=null;
		List<Student> students=new ArrayList<Student>();
		try {
			conn=DbUtils.getConnection();
			pstat=conn.prepareStatement("select * from student limit ?,?");
			pstat.setInt(1, (pageIndex-1)*pagesize);
			pstat.setInt(2, pagesize);
			rs=pstat.executeQuery();
			while(rs.next()){
				int studentNo=rs.getInt("studentNo");
				String loginPwd=rs.getString("loginPwd");
				String studentName=rs.getString("studentName");
				String sex=rs.getString("sex");
				Date bornDate=rs.getDate("bornDate");
				students.add(new Student(studentNo, loginPwd, studentName, sex, bornDate));
			}
			return students;
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}finally {
			DbUtils.release(rs, pstat, conn);
		}
	
	}

	@Override
	public int getTotalCount() {
		Connection conn=null;
		PreparedStatement pstat=null;
		ResultSet rs=null;
		List<Student> students=new ArrayList<Student>();
		try {
			conn=DbUtils.getConnection();
			pstat=conn.prepareStatement("select count(*) from student");
			rs=pstat.executeQuery();
			int count=0;
			if(rs.next()){
				count=rs.getInt(1);
			}
			return count; 
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}finally {
			DbUtils.release(rs, pstat, conn);
		}
	}

}

4.4.6 创建Servie和实现类

StudentService接口

package com.qf.myschool.service;

import java.util.List;

import com.qf.myschool.domain.PageBean;
import com.qf.myschool.domain.Student;

public interface StudentService {	
	public PageBean getPage(int pageIndex);
}

StudentServiceImpl实现类

package com.qf.myschool.service.impl;

import java.util.List;

import com.qf.myschool.dao.StudentDao;
import com.qf.myschool.dao.impl.StudentDaoImpl;
import com.qf.myschool.domain.PageBean;
import com.qf.myschool.domain.Student;
import com.qf.myschool.service.StudentService;

public class StudentServiceImpl implements StudentService {

	private StudentDao studentDao=new StudentDaoImpl();
	
	@Override
	public PageBean getPage(int pageIndex,int pageSize) {
		//查询数据库一共多少条数据
		int totalCount=studentDao.getTotalCount();
		List<Student> data=studentDao.findByPage(pageIndex, pageSize);
		PageBean<Student> page=new PageBean<Student>(pageIndex,pageSize,totalCount,data);
		return page;
	}

}

StudentListServlet.java类

@WebServlet(name = "StudentListServlet",value = "/stulist")
public class StudentListServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1获取参数  pageIndex  pageSize   1   10
        String _pageIndex = request.getParameter("pageIndex"); // ""  null  "abc"
        String _pageSize = request.getParameter("pageSize");
        int pageIndex=1;
        int pageSize=10;
        if(_pageIndex!=null&&_pageIndex.trim().length()!=0){
            pageIndex=Integer.parseInt(_pageIndex);
            if(pageIndex<=0){
                pageIndex=1;
            }
        }
        if(_pageSize!=null&&_pageSize.trim().length()!=0){
            pageSize=Integer.parseInt(_pageSize);
        }

        //2调用业务
        StudentService studentService=new StudentServiceImpl();
        PageBean pageBean = studentService.findByPage(pageIndex, pageSize);
        //3把pageBean放入域中
        request.setAttribute("pageBean", pageBean);
        //4转发到jsp
        request.getRequestDispatcher("listStudent.jsp").forward(request, response);


    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

4.4.7 listStudent.jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>



  
    
    
    学生列表
    
  
  
  
  
学号 密码 姓名 性别 出生日期 操作
${stu.studentNo} ${stu.loginPwd} ${stu.studentName} ${stu.sex}
首页 上一页 下一页 尾页

总结

1 MVC Model模型 View 视图 Controller 控制:是一种设计模式,属于架构模式,把程序逻辑上分成三部分

Model: 负责获取、处理数据

View: 负责展示数据

Controller:负责接受请求,调用Model, 转发或重定向

2 Jsp开发模式

​ Model1 Jsp+Javaban

​ Model2 Servlet+JSP+JavaBean

3 基于MVC三层的实现

​ web 层 :servlet+jsp

​ 业务层:负责业务处理 service

​ 持久层 :负责数据库的访问 dao

​ utils:工具类

​ domain:实体类

4 使用javaweb实现事务转账

​ TheadLocal:线程局部变量 key线程 value:数据

5 防止重复提交

​ session token(令牌)

​ TokenProccessor

​ TokenTools

6 分页查询

​ PageBean

​ pageIndex;

​ pageSize;

​ totalSize;

​ pageCount;

​ data;

你可能感兴趣的:(javaweb)