1、BaseDao

持久层业务接口实现类的公共父类,定义了jdbc操作数据库的所有公共方法,方便子类继承;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

/**
 * 持久层业务接口实现类的公共父类,定义了jdbc操作数据库的所有公共方法,方便子类继承
 * @author zhukang
 *
 */
public class BaseDao {
	
	// 数据库操作对象
	protected Connection conn = null;
	protected PreparedStatement pstmt = null;
	protected ResultSet rs = null;
	
	/**
	 * 获取数据库连接,返回获取连接成功还是失败
	 */
	public boolean getConnection(){
		try {
			// 创建Properties属性对象
			Properties properties = new Properties();
			
			// 使用反射机制,读取外部配置文件
			InputStream inputStream = BaseDao.class.getClassLoader().getResourceAsStream("jdbc.properties");
			
			// 加载输入流对象,获取配置文件内容
			properties.load(inputStream);
			
			// 读取数据库连接信息
			String driverClass = properties.getProperty("driverClass");
			String jdbcUrl = properties.getProperty("jdbcUrl");
			String user = properties.getProperty("user");
			String password = properties.getProperty("password");
			
			// 加载驱动
			Class.forName(driverClass);
			
			// 获取数据库连接对象
			conn = DriverManager.getConnection(jdbcUrl, user, password);
		} catch (Exception e) {
			e.printStackTrace();
			// 获取连接失败
			return false;
		}
		
		// 获取连接成功
		return true;
	}
	
	/**
	 * 增删改的通用方法:只需要提供执行的SQL语句和SQL语句需要的参数,使用预处理对象
	 */
	public int executeUpdate(String executeSql, Object ... params){
		
		// 定义SQL语句执行的影响行数
		int row = 0;
		
		// 获取数据库连接,如果获取失败,不执行操作
		if(getConnection()){
			// 公共执行增删改的处理代码
			try {
				
				// 创建预处理操作对象
				pstmt = conn.prepareStatement(executeSql);
				
				// 实现动态传参,注意: 传入的预编译SQL的?和传入的参数个数和顺序要一致,即:要保证一一对应
				for (int i = 0; i < params.length; i++) {
					pstmt.setObject(i + 1, params[i]);
				}
				
				// 执行增删改操作,并获取影响行数
				row = pstmt.executeUpdate();
				
				System.out.println("BaseDao增删改的SQL=>"+pstmt);
				
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				releaseResource(conn, pstmt, null);
			}
		}
		
		// 返回影响行数
		return row;
		
	}
	
	/**
	 * 查询的通用方法:只需要提供执行的SQL语句和SQL语句需要的参数,使用预处理对象
	 */
	public void executeSelect(String executeSql, Object ... params){
		
		// 获取数据库连接,如果获取成功,执行查询,否则不执行
		if(getConnection()){
			// 公共执行查询的处理代码
			try {
				// 创建预处理操作对象
				pstmt = conn.prepareStatement(executeSql);
				
				// 实现动态传参,注意: 传入的预编译SQL的?和传入的参数个数和顺序要一致,即:要保证一一对应
				for (int i = 0; i < params.length; i++) {
					pstmt.setObject(i + 1, params[i]);
				}
				
				// 执行查询操作,并获取结果集
				rs = pstmt.executeQuery();
				
				System.out.println("BaseDao查询的SQL=>"+pstmt);
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				// 不释放资源,因为rs要返回,关闭后,直接外层不可以使用
			}
		}
	}
	
	/**
	 * 释放数据库操作对象资源
	 */
	public void releaseResource(Connection conn, Statement stmt, ResultSet rs){
		try {
			// 手动释放
			if (null != rs) {
				rs.close();
			}
			
			if (null != stmt) {
				stmt.close();
			}

			if (null != conn) {
				conn.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

2、一个 Servlet 多请求 参数 mothed

使用反射实现;

(全部查询当作条件查询的没有条件来查询会比较方便后面的操作);

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    //根据请求携带的方法参数名参数,调用不同业务的处理方法

    String mothedName = req.getParameter("mothed") == null ? "animes" : req.getParameter("mothed");

    //利用反射,根据方法名调用指定方法
    try {
        Method method = getClass().getDeclaredMethod(mothedName,HttpServletRequest.class,HttpServletResponse.class);
        method.setAccessible(true);
        method.invoke(this, req,resp);
    } catch (Exception e) {
        e.printStackTrace();
    }

}

//查询所有的动漫列表
protected void animes(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("======= AnimesServlet查询所有的动漫列表==========");
    String aname = req.getParameter("aname");
    String author = req.getParameter("author");
    String cid = req.getParameter("cid");

    List<Anime> animes = animeService.animeList(aname, author, cid);

    String animesJson = JSON.toJSONStringWithDateFormat(animes,"yyyy-MM-dd");

    System.out.println(animesJson);
    System.out.println("=============================================");
    resp.getWriter().print(animesJson);

}

//删除动漫
protected void delAnime(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("==============删除动漫=====================");

}

//添加动漫
protected void addAnime(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("==============添加动漫=====================");

}

//修改动漫
protected void modAnime(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("==============修改动漫=====================");

}

3、搜索 点击搜索按钮,$(“form”).serialize()获取参数,并条件查询

$(function(){
    
    //页面初始化加载,主动查询列表
    //查询所有的数据,就是条件查询的没有条件
	showAnimeList();
    
	//动态获取动漫数据,动态显示
    function showAnimeList(){
        $.getJSON("animes",$("form").serialize() ,function(data){
            // 确定数据要动态显示的位置
            var $tbody = $("tbody");

            //如果没有数据,不能显示分页和提示暂无数据
            if(data == null || data == ""){
                //先清空再,显示提示信息
                $tbody.empty().append("<tr align='center'><td colspan='8'>暂无数据</td></tr>");
                //隐藏 tfoot
                $("tfoot").hide();
                //直接返回,因为没有数据,不需要拼接页面
                return;
            }

            // 隔行变色
            var count = 1;

            //定义动态展示内容,如果不定义为空字符的话,一直拼接新数据
            var animeCountent = "";

            // 数据解析
            $(data).each(function(){
                // 定义颜色
                var bgColor = count % 2 == 0 ? "style='background-color:#ddd;'" : "";
                animeCountent +=
                    "<tr align='center' " + bgColor + ">"
                    + "<td>" + this.id + "</td>"
                    + "<td>" + this.cname + "</td>"
                    + "<td>" + this.name + "</td>"
                    + "<td>" + this.author + "</td>"
                    + "<td>" + this.actor + "</td>"
                    + "<td>" + this.produce + "</td>"
                    + "<td>" + this.create_date + "</td>"
                    + "<td><a href='#'>修改</a>&nbsp;&nbsp;<a href='#'>删除</a></td>"
                    + "</tr>";

                count++;
            });
            $tbody.empty().append(animeCountent);
            //有数据就要展示tfoot
            $("tfoot").show();
        });
    }

    //点击搜索按钮,根据条件筛选数据
    $("#searchAnimes").click(function(){
        showAnimeList();
    });
    
 });

4、分页查询sql 动态拼接(apramsList)

public class AnimeDaoImpl extends BaseDao implements AnimeDao{

	@Override
	public List<Anime> selectAnimeList(String aname, String author, String cid) {
		//查询动漫详情的SQL语句
		String executeSql = "select a.id, a.cid, a.name, a.author, a.actor, a.produce, a.create_date, c.name from animes a, category c where a.cid = c.id ";
		
		//执行查询的参数集合
		//此写法弊端,如果两个或者多个参数同时有,必须不停的增加判断,添加参数
		//Object[] params = new Object[]{};
		
		//动态参数,推荐使用
		List<Object> paramList = new ArrayList<Object>();
		
		//根据不同的查询条件,拼接SQL语句和参数
		//条件中有动漫名
		if(null != aname && !"".equals(aname)) {
			//模糊匹配
			executeSql += " and a.name like concat('%',?,'%')";
			
			paramList.add(aname);
		}
		
		//条件中有作者
		if(null != author && !"".equals(author)) {
			//模糊匹配
			executeSql += " and a.author like concat('%',?,'%')";
			
			paramList.add(author);
		}
		
		//条件中有类型
		if(null != cid && !"0".equals(cid)) {
			executeSql += " and a.cid = ?";
			paramList.add(cid);
		}
		
		//定义返回动漫列表的数据集合
		List<Anime> animes = new ArrayList<Anime>();
		
		try {
			// 执行查询
			this.executeSelect(executeSql, paramList.toArray());
			
			// 解析查询结果
			while(rs.next()){
				// 每条数据,创建一个动漫对象,存储数据
				Anime anime = new Anime();
				anime.setId(rs.getInt(1));
				anime.setCid(rs.getInt(2));
				
				//对动漫name结构处理
				if(null != aname && !"".equals(aname)) {
					//标记name
					String markname = rs.getString(3).replace(aname, "<span style='color:red'>"+aname+"</span>");
					anime.setName(markname);
				}else {
					anime.setName(rs.getString(3));
				}
				
				anime.setAuthor(rs.getString(4));
				anime.setActor(rs.getString(5));
				anime.setProduce(rs.getString(6));
				anime.setCreate_date(rs.getDate(7));
				anime.setCname(rs.getString(8));
				
				// 将每条动漫数据对象放入集合
				animes.add(anime);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			//关闭资源
			this.releaseResource(conn, pstmt, rs);
		}
		
		//返回动漫集合
		return animes;
	}

}

5、作业总结技巧(BaseDao 页面不跳转 Ajax)

5.1 Ajax动态拼接元素及数据

5.1.1 Ajax动态添加分类数据

//$(function() jQuery标志
$(function(){
    //定位z展示分类的下拉元素
    var $cidSelect = $("#cid");

    //获取动漫分类,动态展示
    $.getJSON("categories",function(data){
        //遍历返回的分类集合json集合数,动态加载分类选项
        $(data).each(function(){
            //alert(this.id+this.name);
            $cidSelect.append("<option value='"+this.id+"'>"+this.name+"</option>");
        });
    });
});

5.1.2Ajax动态添加动漫数据

加载动漫数据的时候,直接考虑到模糊匹配查询,全部查询就是不带条件查询;

(这里的代码又展示了一遍,主要是提示后面的操作是基于这些代码操作的);

//$(function() jQuery标志
$(function(){
	//页面初始化加载,主动查询列表
		showAnimeList();
				
		//动态获取动漫数据,动态显示
		function showAnimeList(){
			$.getJSON("animes",$("form").serialize() ,function(data){
				// 确定数据要动态显示的位置
				var $tbody = $("tbody");
				
				//如果没有数据,不能显示分页和提示暂无数据
				if(data == null || data == ""){
					//先清空再,显示提示信息
					$tbody.empty().append("<tr align='center'><td colspan='8'>暂无数据</td></tr>");
					//隐藏 tfoot
					$("tfoot").hide();
					//直接返回,因为没有数据,不需要拼接页面
					return;
				}
				
				// 隔行变色
				var count = 1;
				
				//定义动态展示内容,如果不定义为空字符的话,一直拼接新数据
				var animeCountent = "";
				
				// 数据解析
				$(data).each(function(){
					// 定义颜色
					var bgColor = count % 2 == 0 ? "style='background-color:#ddd;'" : "";
					animeCountent +=
						"<tr align='center' " + bgColor + ">"
						+ "<td>" + this.id + "</td>"
						+ "<td>" + this.cname + "</td>"
						+ "<td>" + this.name + "</td>"
						+ "<td>" + this.author + "</td>"
						+ "<td>" + this.actor + "</td>"
						+ "<td>" + this.produce + "</td>"
						+ "<td>" + this.create_date + "</td>"
						+ "<td><a href='modAnime.jsp?id="+this.id
												  +"&cid="+this.cid
												  +"&cname="+this.cname
												  +"&name="+this.name
												  +"&author="+this.author
												  +"&actor="+this.actor
												  +"&produce="+this.produce
												  +"&create_date="+this.create_date+"'>修改</a>&nbsp;&nbsp;"
						+ "<a class='delAnime' href='animes?mothed=delAnime&id="+this.id+"'>删除</a>"
						+"</td>"
						+ "</tr>";
						
					count++;
				});
				$tbody.empty().append(animeCountent);
				//有数据就要展示tfoot
				$("tfoot").show();
			});
		}
		
		//点击搜索按钮,根据条件筛选数据
		$("#searchAnimes").click(function(){
			showAnimeList();
		});
});

5.1 标记搜索词

5.1 .2 通过SQl 的 replace 标记

没有同名字段时可以使用;

//条件中有作者
if(null != author && !"".equals(author)) {
    //标记关键字 author
    String markAuthor = "replace(`author`,'"+author +"',\"<span style='color:red'>"+author+"</span>\") as 'a.author'";

    //标记
    executeSql  = executeSql.replace("a.author", markAuthor);

    //模糊匹配
    executeSql += " and a.author like concat('%',?,'%')";
    
    paramList.add(author); //添加参数
}

5.1.4 通过 replace 对结果进行 标记

//对动漫name结构处理
if(null != aname && !"".equals(aname)) {
    //如果有这个条件 标记name
    String markname = rs.getString(3).replace(aname, "<span style='color:red'>"+aname+"</span>");
    anime.setName(markname);
}else {
    //没有这个条件则不需要标记
    anime.setName(rs.getString(3));
}

5.2 修改 类型 选择 select

先将修改传过来的类型参数隐藏到一个input标签中,在动态获取类型的时候,JQuery获取原来的类型参数,并选择性的给option标签添加selected参数

<%
//获取前端参数,封装到实体类,并添加到request域中,方便获取
//注意日期不要放进实体类
//直接value="<%=request.getParameter("create_date") %>" 要不然会类型不匹配
request.setAttribute("upAnimes", anime);
%>
<!-- 隐藏动漫类型 cid -->
<input type="hidden" id="mycid" class="form-control" value="${upAnimes.cid }" required>


<script type="text/javascript">
 //异步获取并遍历动漫类型
$(function(){
	//获取动漫分类,动态展示
	$.getJSON("categories",function(data){
		//定位z展示分类的下拉元素
		var $cidSelect = $("#cid");
		
		//遍历返回的分类集合json集合数,动态加载分类选项
		var cid =  $("#mycid").val();
		$(data).each(function(){
			//alert(this.id+this.name);
			if(cid == this.id){
				$cidSelect.append("<option value='"+this.id+"' selected>"+this.name+"</option>");
			}else{
				$cidSelect.append("<option value='"+this.id+"'>"+this.name+"</option>");
			}
		});
	});	
});

5.3 Ajax 拼接确认删除(动态绑定事件)

5.3.1 给动态添加的元素,添加cilck事件(无法绑定事件)

cilck无法直接给动态的元素添加事件;

//确认删除提示  错误,click事件不能动态绑定事件
$(".delAnime").click(function(){
    if(!confirm("是否确认删除 ${anime.name } ")){
    	return false;
    }
});

5.3.2 添加动态元素时直接动态添加 onClick=”return confirm(\”确认删除\”)“

 "<a class='delAnime' href='animes?mothed=delAnime&id="+this.id+"' onClick='return confirm(\"确认删除《"+this.name+"》?\")'>删除</a></td>"

5.3.3 $(document).on 绑定动态加载元素的事件

//动态绑定事件(当前和以后添加的元素都可以绑定)
//$(document).on 绑定动态加载子元素的事件   document是父级元素即可
$(document).on('click', '.delAnime', function(){
    if(!confirm("是否确认删除 ${anime.name }")){
        return false;
    }
});

on 绑定动态加载元素的事件参考博客

5.6 分页条件查询 (不需要pageSupper类)

分页条件查询,包括了一般查询,所以一个分页条件查询就够了;

前端处理分页参数;

5.6.1 参数

参数 说明 提交
aname 条件查询参数 表单提交
author 条件查询参数 表单提交
cid 条件查询参数 表单提交
pageNo 当前页面页码 获取tfoot的pageNum,Ajax提交的时候拼接参数
pageSize 页面大小 获取tfoot的pageSize,Ajax提交的时候拼接参数
totalCount 数据总条数 Ajax获取,然后填入 totalCount 中,分页请求时直接获取
<!-- 条件查询参数 aname author cid -->
<form action="#">
    <p style="text-align: center">
        名称:<input type="text" name="aname" size="15"/>
        作者:<input type="text" name="author" size="15"/>
        分类:<select name="cid" id="cid">
        <option value="0">全部</option>
        </select>
        <input type="button" value = "搜索" id = "searchAnimes" />
    </p>
</form>

<!-- totalCount -->
共&nbsp;<span id="totalCount">5</span>&nbsp;条&nbsp;&nbsp;

<!-- pageSize 和 pageNum -->
每页&nbsp;
<!--  <span id = "pageSize">5</span>&nbsp;  -->
<select name="pageSize" id="pageSize">
    <option value="3" selected>3</option>
    <option value="5">5</option>
    <option value="10">10</option>
</select>
条&nbsp;
当前第&nbsp;<span id = "pageNum">1</span>&nbsp;页&nbsp;/&nbsp;

5.6.2 分页标签

<tfoot>
    <tr>
        <td colspan="8" style="height: 40px; text-align: center">
            <input type="button" value="添加" id="addAnime"/>&nbsp;&nbsp;
            <a href="#">首页</a>&nbsp;|&nbsp;
            <a href="#">&lt;&lt;上一页</a>&nbsp;|&nbsp;
            <a href="#">下一页&gt;&gt;</a>&nbsp;|&nbsp;
            <a href="#">尾页</a>&nbsp;|&nbsp;
            共&nbsp;<span id="totalCount">5</span>&nbsp;条&nbsp;&nbsp;
            每页&nbsp;
            <!--  <span id = "pageSize">5</span>&nbsp;  -->
            <select name="pageSize" id="pageSize">
                <option value="3" selected>3</option>
                <option value="5">5</option>
                <option value="10">10</option>
            </select>
            条&nbsp;
            当前第&nbsp;<span id = "pageNum">1</span>&nbsp;页&nbsp;/&nbsp;
            共&nbsp;<span id="totalPage">1</span>&nbsp;页
        </td>
    </tr>
</tfoot>

5.6.3 数据总量函数

Ajax请求 分页查询的数据总量,并填写到页面上,方便后面分页处理

//设置数据总量 函数
function totalCount(){
    //通过 不分页 的条件查询,查询出总数据量
    $.getJSON("animes?mothed=animesCount",$("form").serialize() ,function(data){
        //定义数据总量
        var totalCount = data;

        //alert(" totalCount 数据总量:"+totalCount);
        //获取数据总量元素
        var $totalCount = $("#totalCount");	
        //重置数据总量
        $totalCount.text(totalCount);	
    });
}

5.6.4 分页处理函数 (作用类似PageSupport)

包括 上一页,下一页的隐藏处理

//分页处理函数
function pageSearch(pageSize,pageNum,totalPage){
    //后去分页数据
    //页面容量 (页面容量可以不操作,我是为了可以手动改变页面容量)
    var $pageSize = $("#pageSize");
    //当前页码
    var $pageNum = $("#pageNum");
    //页面总数
    var $totalPage = $("#totalPage");


    //重置分页数据
    //页面容量 (页面容量可以不处理,因为Ajax异步的,页面不会刷新)
    //$pageSize.text(pageSize);
    $pageSize.val(pageSize);
    //当前页码
    $pageNum.text(pageNum);
    //页面总数
    $totalPage.text(totalPage);

    //处理上一页和下一页
    //上一页
    if(pageNum <= 1){
        $("tfoot a:eq(1)").hide();
    }else{
        $("tfoot a:eq(1)").show();
    }

    //下一页
    if(pageNum >= totalPage){
        $("tfoot a:eq(2)").hide();
    }else{
        $("tfoot a:eq(2)").show();
    }
}

5.6.5 分页条件查询 动态显示数据

  • 获取处理总页数
  • 分页参数获取 pageNum,pageSize
  • 动态拼接数据
  • 处理pageSize,pageNum,totalPage
//===页面初始化加载,主动分页条件查询处理===
//分页条件查询处理
pageAnimeList();

//动态 分页 条件 获取动漫数据,动态显示
function pageAnimeList(){
    //处理总页数
    totalCount();

    //获取分页查询的数据
    //页面容量
    var $pageSize = $("#pageSize");
    //pageSize 用 <span> 标签
    //var pageSize = $pageSize.text();
    //pageSize 用 <select> 标签
    var pageSize = $pageSize.val();
    //当前页码
    var $pageNum = $("#pageNum");
    var pageNum = $pageNum.text();

    //数据总数
    //$.getJSON("animes",$("form").serialize() ,function(data){
    //分页查询
    $.getJSON("animes?mothed=pageAnimes&pageNum="+pageNum+"&pageSize="+pageSize,$("form").serialize() ,function(data){
        // 确定数据要动态显示的位置
        var $tbody = $("tbody");

        //如果没有数据,不能显示分页和提示暂无数据
        if(data == null || data == ""){
            //先清空再,显示提示信息
            $tbody.empty().append("<tr align='center'><td colspan='8'>暂无数据</td></tr>");
            //隐藏 tfoot
            $("tfoot").hide();
            //直接返回,因为没有数据,不需要拼接页面
            return;
        }

        // 隔行变色
        var count = 0;

        //定义动态展示内容,如果不定义为空字符的话,一直拼接新数据
        var animeCountent = "";

        // 数据解析
        $(data).each(function(){
            // 定义颜色
            var bgColor = count % 2 == 1 ? "style='background-color:#ddd;'" : "";
            animeCountent +=
                "<tr align='center' " + bgColor + ">"
                + "<td>" + this.id + "</td>"
                + "<td>" + this.cname + "</td>"
                + "<td>" + this.name + "</td>"
                + "<td>" + this.author + "</td>"
                + "<td>" + this.actor + "</td>"
                + "<td>" + this.produce + "</td>"
                + "<td>" + this.create_date + "</td>"
                + "<td><a href='modAnime.jsp?id="+this.id
                +"&cid="+this.cid
                +"&cname="+this.cname
                +"&name="+this.name
                +"&author="+this.author
                +"&actor="+this.actor
                +"&produce="+this.produce
                +"&create_date="+this.create_date+"'>修改</a>&nbsp;&nbsp;"
                + "<a class='delAnime' href='animes?mothed=delAnime&id="+this.id+"'>删除</a>"
                +"</td>"
                + "</tr>";

            count++;
        });
        //清空原来的tbody,添加新的数据
        $tbody.empty().append(animeCountent);
        //有数据就要展示tfoot
        $("tfoot").show();

        //分页处理
        //获取总数据量  处理 页面数量
        //数据总量
        var $totalCount = $("#totalCount");	
        var totalCount = $totalCount.text();
        //处理总页数
        var totalPage = 1;

        if((totalCount%pageSize) == 0){
            //alert("totalCount="+totalCount+"pageSize"+pageSize);
            totalPage = totalCount/pageSize;
        }else{
            //alert("totalCount="+totalCount+"pageSize"+pageSize);
            totalPage = ((parseInt(totalCount/pageSize))+1);
        }

        //alert("处理总页数==>>totalPage==>"+totalPage);
        pageSearch(pageSize,pageNum,totalPage);

    });
}

//点击搜索按钮,根据条件筛选数据
$("#searchAnimes").click(function(){
    //分页条件查询
    pageAnimeList();
});

5.6.6 分页跳转处理

//分页跳转
//首页
$("tfoot a:eq(0)").click(function(){
    $("#pageNum").text(1);
    //分页条件查询
    pageAnimeList();
    return false;
});


// 上一页
$("tfoot a:eq(1)").click(function(){
    var pageNum = parseInt($("#pageNum").text()) - 1;
    $("#pageNum").text(pageNum);
    //分页条件查询
    pageAnimeList();
    return false;
});


// 下一页
$("tfoot a:eq(2)").click(function(){
    //alert("下一页");			
    //alert(parseInt($("#pageNum").text()) + 1);
    $("#pageNum").text(parseInt($("#pageNum").text()) + 1);
    //分页条件查询
    pageAnimeList();
    return false;
});

// 尾页
$("tfoot a:eq(3)").click(function(){
    $("#pageNum").text(parseInt($("#totalPage").text()));
    //分页条件查询
    pageAnimeList();
    return false;
});

5.6.7 修改pageSize

//修改pageSize
//select标签的change()事件, 切换选项时触发
$("#pageSize").change(function(){
    //获取修改后的 currentPageSize
    var pageSize = $(this).children('option:selected').val();
    //修改页面大小后,再主动查询一次动漫数据
    pageAnimeList();
});

5.6.8 数据总数 和 条件分页查询的 servlet

5.6.8.1 数据总数
//条件查询所有的动漫列表条数
protected void animesCount(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("======= AnimesServlet查询所有的动漫的总数量==========");
    String aname = req.getParameter("aname");
    String author = req.getParameter("author");
    String cid = req.getParameter("cid");

    int totalCount = animeService.animeListCount(aname, author, cid);

    String totalCountJson = JSON.toJSONString(totalCount);

    System.out.println("AnimesServlet == >animesCount=动漫总条数==>>"+totalCountJson);
    System.out.println("=============================================");
    resp.getWriter().print(totalCountJson);

}
5.6.8.2 分页条件查询
//分页条件查询所有的动漫
protected void pageAnimes(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("======= 分页条件查询  AnimesServlet查询所有的动漫列表==========");
    //条件查询参数
    String aname = req.getParameter("aname");
    String author = req.getParameter("author");
    String cid = req.getParameter("cid");

    //分页参数
    Integer pageNum = new Integer(req.getParameter("pageNum"));
    Integer pageSize = new Integer(req.getParameter("pageSize"));

    System.out.println("pageAnimes==> pageNum==>"+pageNum);
    System.out.println("pageAnimes==> pageSize==>"+pageSize);

    List<Anime> animes = animeService.PageSelectAnimeList(aname, author, cid, pageNum, pageSize);

    String animesJson = JSON.toJSONStringWithDateFormat(animes,"yyyy-MM-dd");

    System.out.println(animesJson);
    System.out.println("=============================================");
    resp.getWriter().print(animesJson);

}
5.6.8.3 多个Ajax请求注意点

多个Ajax请求,javaScript无法控制其执行顺序,有时候会出错;

一个请求拿到另外一个请求的rs中数据;(这里数据总条数取到了某条数据的id)

或第二个请求还没有从rs中取出数据rs就被关闭(No operations allowed after statement closed.);

(另外这里还有一个特殊点,我的setvlet请求是同一个类的多个方法通过反射执行的);

这里需要将用来反射调用方法的公共 **dopost方法上锁 synchronized **;

//doPost  方法上锁,保证一次只有一个请求,就保证 一次只有一个SQL执行,一次只有一个rs,就不会数据错乱;
@Override
protected synchronized void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    //根据请求携带的方法参数名参数,调用不同业务的处理方法

    String mothedName = req.getParameter("mothed") == null ? "animes" : req.getParameter("mothed");

    //利用反射,根据方法名调用指定方法
    try {
        Method method = getClass().getDeclaredMethod(mothedName,HttpServletRequest.class,HttpServletResponse.class);
        method.setAccessible(true);
        method.invoke(this, req,resp);
    } catch (Exception e) {
        e.printStackTrace();
    }

}

5.7 删除

5.7.1 动态添加的a标签 绑定事件

直接带着id到后台删除;

+ "<a class='delAnime' href='animes?mothed=delAnime&id="+this.id+"'>删除</a>"


//动态绑定事件(当前和以后添加的元素都可以绑定)
//$(document).on 绑定动态加载子元素的事件
$(document).on('click', '.delAnime', function(){
    if(!confirm("是否确认删除 ${anime.name }")){
        return false;
    }
});

5.7.2 删除成功后 提示

resp.getWriter().print("<script type='text/javascript'>alert('删除成功!!!'); location.href = 'animeList.jsp'</script>");

5.8 修改

这种方式比较的麻烦,携带的参数太多,不过也是一个方法,可以扩张一下思维;

+ "<td><a href='modAnime.jsp?id="+this.id
    +"&cid="+this.cid
    +"&cname="+this.cname
    +"&name="+this.name
    +"&author="+this.author
    +"&actor="+this.actor
    +"&produce="+this.produce				      		                                     +"&create_date="+this.create_date+"'>修改</a>&nbsp;&nbsp;"          

5.9 添加

<input type="button" value="添加" id="addAnime"/>&nbsp;&nbsp;


//添加按钮处理 跳转到添加页面
$("#addAnime").click(function(){
    location.href = "addAnime.jsp";
});