主頁 > 後端開發 > Javaweb08-Ajax專案-分頁條件查詢 + 增刪改

Javaweb08-Ajax專案-分頁條件查詢 + 增刪改

2022-08-17 07:18:16 後端開發

1、登錄

1.1 登錄form表單

<form action="<%=request.getContextPath()%>/loginAnime" method="get">
    <table border="1px" align="center"  cellspacing="0">
        <tr style="hight:60px; font-size:16px;background-color:#B9DEE0">
            <th colspan="2"> 歡迎登錄課工場KH96動漫管理系統 </th>
        </tr>
        <tr>
            <td>用戶名:</td>
            <td>
                <input type="text" name="uname" id="uname" placeholder="請輸入"用戶名> </input> 
        <span id = "showMsg"   style="text-align:center;"></span>
        </td>
    </tr>
<tr>
    <td>用戶密碼:</td>
    <td>
        <input type="password" name="upwd" id="upwd" placeholder="請輸入用戶密碼"> </input> 
</td>
</tr>
<tr>
    <td colspan="2" align="center">
        <input type="submit" value="https://www.cnblogs.com/xiaoqigui/p/立即登錄" />
        <input type="reset" value="https://www.cnblogs.com/xiaoqigui/p/重新填寫" />
    </td>
</tr>
</table>
</form>
歡迎登錄課工場KH96動漫管理系統
用戶名:
用戶密碼:

1.2 非空判斷 和 Ajax 登錄

<script type="text/javascript">
	$(function(){
		//使用jQuery的Ajax實作異步登錄
		//監聽表單提交事件,數校驗
		$("form").submit(function(){
			//登錄名校驗
			var userName = $("#uname").val();
			if(userName == null || userName == ""){
				alert("用戶名不能為空");
				return false;
			}
			
			var userPwd = $("#upwd").val();
			if(userPwd == null || userPwd == ""){
				alert("密碼不能為空");
				return false;
			}
			
			//發送請求
			$.post("<%=request.getContextPath()%>/loginAnime",{"userName" : userName,"userPwd":userPwd},function(data){
				 //決議資料
				 //alert("登錄"+data);
				 if(data =https://www.cnblogs.com/xiaoqigui/p/="true"){
					 //alert("登錄成功");
					 location.href= "https://www.cnblogs.com/xiaoqigui/p/animeList.jsp";
					 
				 }else{
					 alert("登錄失敗");
				 }
			});
			
			//取消表單提交
			return false;
			
		});
		
	});
</script>

1.3 Ajax接收前端回傳boolean型別資料

1.3.1 一般AJax請求,$.get,$.post 請求 接收的是 String 型別

//判斷場景
$("form").submit(function(){
    //發送請求
    $.post("<%=request.getContextPath()%>/loginAnime",{"userName" : userName,"userPwd":userPwd},function(data){
        //1.直接使用字符型判斷
        if(data =https://www.cnblogs.com/xiaoqigui/p/="true"){
        //2.轉換成boolean型別判斷
        //if(JSON(data) == true)
            //alert("登錄成功");
            location.href= "https://www.cnblogs.com/xiaoqigui/p/animeList.jsp";

        }else{
            alert("登錄失敗");
        }
    })
    //取消表單提交
    return false;

});

1.3.2 $.getJSON 接收的是boolean型別

//場景
$("#codeLogin").click(function () {
    $.getJSON("userServlet?method=sendEmail",null ,function(data){
        //判斷添加回傳結果
        //alert(data)
        if(data =https://www.cnblogs.com/xiaoqigui/p/= true){
            alert("請注意接收驗證碼!!!");
            location.href = "https://www.cnblogs.com/xiaoqigui/p/emailLogin.jsp";
        }else{
            alert("驗證碼發送失敗!!!");
        }
    });
});

1、洗掉

1.1 洗掉的a標簽

a標簽是由第一次跳轉到animeList.jsp頁面時,Ajax動態加載的;

href='javascript:void(0);' 取消a標簽的href屬性;

/*
href='javascript:void;'  取消href跳轉,使用Ajax提交請求
animeId = '"+this.id+"'  添加一個animed引數,洗掉時方便獲取
class='delAnime'        添加類名,方便動態click系結事件
*/
+"<a href='javascript:void(0);' animeId = '"+this.id+"' class='delAnime' >洗掉</a></td>"

1.2 Ajax 洗掉對應的動漫

$("table tbody").on("click",".delAnime",function(){ });給動態加載元素系結事件

獲取動漫id通過Ajax請求洗掉資料,并通過當前元素的父元素,洗掉該元素;(因為異步洗掉的資料,沒有再查詢一次,所以需要,手動洗掉動漫資料);

//點擊洗掉,洗掉對應的動漫
$("table tbody").on("click",".delAnime",function(){
    //alert($(this).attr("animeId"));

    //確定洗掉提示
    if(!confirm("確定要洗掉這條資料嗎?")){
        return false;
    }

    //確定要洗掉的超鏈接物件
    var $delAnime = $(this);

    //獲取洗掉動漫編號
    var animeId = $delAnime.attr("animeId");
    //alert("洗掉的編號:" + animeId);

    //使用Ajax,實作異步洗掉
    $.getJSON("animes?mothed=delAnime",{"id":animeId},function(data){
        //判斷洗掉成功
        if(data){
            //后臺洗掉成功后,當前頁面動漫元素資料頁洗掉
            $delAnime.parents("tr").remove();
            alert("洗掉成功");
        }else{
            alert("洗掉失敗");
        }
    })
});

1.3 onClick(), click(),on系結 click 三者區別

1.3.1 onClick()系結事件

onClick(函式名,或者是js代碼片段)用于系結事件,告訴瀏覽器在滑鼠點擊時候要做什么;

//場景1:
<button id="" onClick("functionName()")>點擊 </button>
點擊觸發函式
//場景2:直接再onClick="" 中寫函式內容
<a  href="https://www.cnblogs.com/userServlet?method=userDel&id=${user.id}"  onClick="return confirm('是否確認洗掉${user.userName}用戶')" >洗掉</a>

1.3.2 $("selected")click(function(){}); 方法

  • 注意:不可以給Ajax動態添加的元素,系結click()方法;
  • 一般click(function() {})就夠用了,注意Ajax加載的元素的時候就好;
//確認按鈕使用的場景
$("#save").click(function () {
    if(confirm("是否確認修改資訊?")){
        $("#userForm").submit();
    }
});

1.3.3 $("table tbody").on("click",".delAnime",function(){})

  • $("父級元素").on("事件","子級元素,一般寫類名",function( ){} );
//點擊洗掉,洗掉對應的動漫
$("table tbody").on("click",".delAnime",function(){
    //使用Ajax,實作異步洗掉
    $.getJSON("animes?mothed=delAnime",{"id":animeId},function(data){
        //判斷洗掉成功
        if(data){
            //后臺洗掉成功后,當前頁面動漫元素資料頁洗掉
            $delAnime.parents("tr").remove();
            alert("洗掉成功");
        }else{
            alert("洗掉失敗");
        }
    })
});

2、修改

2.1 修改a標簽

將要修改的資料的id,帶過去,方便修改頁面獲取,需要修改的資料

/*
href='https://www.cnblogs.com/xiaoqigui/p/modAnime.jsp?id="+this.id+"&cid="+this.cid+"'
跳轉到到修改頁面
引數id 是動漫的id,通過id查詢對應動漫的資料,并資料回顯,方便修改
cid 是動漫的的型別,方便選定動漫型別
*/

+ "<td><a href='https://www.cnblogs.com/xiaoqigui/p/modAnime.jsp?id="+this.id+"&cid="+this.cid+"' >修改</a>&nbsp;&nbsp;"

2.2 Ajax 動漫資料回顯

由于是使用Ajax直接跳轉到修改動漫的頁面,無法攜帶要修改的動漫id,于是就取巧的,將引數放在導航欄rul中,然后獲取url,使用字符操作,獲取到攜帶在rul中的引數(動漫id);

// 從url中獲取引數函式,使用正則運算式
function getUrlParam(name) {
    //構造一個含有目標引數的正則運算式物件
    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
    //匹配目標引數
    var r = window.location.search.substr(1).match(reg);
    //回傳引數
    if (r != null) {
        return unescape(r[2]);
    }
    return null;
}


//回傳按鈕
$("input[type=button]").click(function(){
    history.back();
});

//根據id查詢資料 資料回顯
$.getJSON("animes?mothed=animeById",{"id":getUrlParam("id")} ,function(data){
    $("input[name=id]").val(data.id);
    $("input[name=aname]").val(data.name);
    $("input[name=author]").val(data.author);
    $("input[name=actor]").val(data.actor);
    $("input[name=produce]").val(data.produce);
    $("input[name=createDate]").val(data.create_date);
});	

2.3 Ajax修改動漫資訊

$("form").serialize(),獲取提交表單中的引數

$("form").serialize():可直接獲取到表單中的引數,并不一定需要submit()事件;

$(selector).serialize():serialize()方法通過序列化表單值,創建標準的URL編碼文本字串,selector可以是input標簽,文本框,或者是form元素本身

$("form").submit(function(){ }); form表單提交事件,點擊submit 標簽時觸發;

$("form").submit(); 主動觸發表單提交事件;

//異步請求修改動漫,并跳轉會展示頁面
//修改動漫詳情
$("form").submit(function(){
    //發送Ajax異步請求,修改動漫
    $.getJSON("animes?mothed=modAnime",$("form").serialize() ,function(data){
        //判斷添加回傳結果
        if(data){
            alert("動漫修改成功");
            location.href="https://www.cnblogs.com/xiaoqigui/p/animeList.jsp";
        }else{
            alert("修改動漫失敗!!");
        }
    });

    //去除表單提交事件
    return false;
});

3、添加

3.1 跳轉到添加頁面

添加動漫,不需要攜帶引數,可直接跳轉;

<input type="button" value="https://www.cnblogs.com/xiaoqigui/p/添加" id="addAnime"/>&nbsp;&nbsp;

//點擊添加,跳轉到添加動漫頁面
$("#addAnime").click(function(){
	location.href = "https://www.cnblogs.com/xiaoqigui/p/addAnime.jsp";
})

3.2 Ajax 添加動漫詳情

$("form").serialize() 獲取表單的引數;

//$("form").serialize() 獲取表單的引數,作為異步請求的引數
//新增動漫詳情
$("form").submit(function(){
    //發送Ajax異步請求,新增動漫

    $.getJSON("animes?mothed=addAnime",$("form").serialize() ,function(data){
        //判斷添加回傳結果
        if(data){
            alert("添加動漫成功");
            location.href="https://www.cnblogs.com/xiaoqigui/p/animeList.jsp";

        }else{
            alert("添加動漫失敗!!");
        }
    });

    //去除表單提交事件
    return false;
});

4、分頁條件查詢

一般會先做分頁條件查詢再做增刪改;

步驟 : 查詢所有的資料 -> 條件查詢所有資料 ->分頁條件查詢所有資料;(慢慢遞進,不容易出錯);

4.1 引數

引數 說明 提交
aname 條件查詢引數 表單提交
author 條件查詢引數 表單提交
cid 條件查詢引數 表單提交
pageNo 當前頁面頁碼 獲取tfoot的currPageNo,填入form表單隱藏的pageNo中
pageSize 頁面大小 獲取tfoot的currentPageSize,填入form表單隱藏的pageSize中
totalCount 資料總條數 請求資料中,根據條件查詢引數先查詢資料總條數

條件查詢的引數一般都會在表單中,可以直接使用;(Ajax請求,不需要資料回顯,如果是請求跳轉,需要資料回顯);

分頁的引數我們為了提交表單請求的時候,可以獲取到分頁引數,就將其他需要的引數隱藏在表單中(只要是查詢需要的引數,都可以放這里,比較方便servlet的獲取);

<!--
條件查詢的引數:aname,author,cid
分頁的引數:pageNo,pageSize
(分頁必須引數,還有資料的總量 totalCount )
-->
<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="https://www.cnblogs.com/xiaoqigui/p/0">全部</option>
        </select>
        <input type="button" value = "https://www.cnblogs.com/xiaoqigui/p/搜索" id = "searchAnimes" />
    </p>
    <!-- 當前頁面引數 和 頁面容量-->
    <input type="hidden" name="pageNo" id="pageNo" value="https://www.cnblogs.com/xiaoqigui/p/1"/>
    <input type="hidden" name="pageSize" id="pageSize" value="https://www.cnblogs.com/xiaoqigui/p/3"/>
</form>

4.2 分頁標簽

分頁引數會顯示在非提交表單中,需要獲取放到表單中對應的隱藏標簽中

<tfoot>
    <tr>
        <td colspan="8" style="height: 40px; text-align: center">
            <input type="button" value="https://www.cnblogs.com/xiaoqigui/p/添加" id="addAnime"/>&nbsp;&nbsp;
            <a href="https://www.cnblogs.com/xiaoqigui/p/#">首頁</a>&nbsp;|&nbsp;
            <a href="https://www.cnblogs.com/xiaoqigui/p/#" id="lastPage">&lt;&lt;上一頁</a>&nbsp;|&nbsp;
            <a href="https://www.cnblogs.com/xiaoqigui/p/#" id="nextPage">下一頁&gt;&gt;</a>&nbsp;|&nbsp;
            <a href="https://www.cnblogs.com/xiaoqigui/p/#">尾頁</a>&nbsp;|&nbsp;
            共&nbsp;<span id="totalCount"></span>&nbsp;條&nbsp;&nbsp;
            每頁&nbsp;
            <!--   <span id = "currentPageSize"></span> -->
            <select name="currentPageSize" id="currentPageSize">
            </select>
            &nbsp;條&nbsp;
            當前第&nbsp;<span id="currPageNo"></span>&nbsp;頁&nbsp;/&nbsp;
            共&nbsp;<span id="totalPage"></span>&nbsp;頁
        </td>
    </tr>
</tfoot>

4.3 分頁Ajax

1、$("form").serialize() 獲取查詢條件和分頁引數

2、發起請求獲取回傳的data(pageSupport),判斷 動漫串列 (pageSupport.data)是否為null,如果為null就隱藏tfoot,且顯示暫無資料;

3、顯示回傳的分頁引數;

4、上一頁,下一頁的隱藏處理;
1). $("#lastPage").hide(); $("#lastPage") .show();

2). $("#lastPage").css("display","none"); $("#lastPage").css("display","inline");

5、動態拼接資料;

6、只要有資料展示,就說明需要展示tfoot;

//頁面初始化加載,主動查詢串列
showPageAnimeList();

//動態獲取動漫資料,動態顯示 條件分頁查詢
function showPageAnimeList(){
    $.getJSON("animes?mothed=animesUsePage",$("form").serialize() ,function(data){
        //alert(data);
        // 確定資料要動態顯示的位置
        var $tbody = $("tbody");

        //如果沒有資料,不能顯示分頁和提示暫無資料
        if(data.data == null || data.data =https://www.cnblogs.com/xiaoqigui/p/=""){
            //先清空再,顯示提示資訊
            $tbody.empty().append("<tr align='center'><td colspan='8'>暫無資料</td></tr>");
            //隱藏 tfoot
            $("tfoot").hide();
            //直接回傳,因為沒有資料,不需要拼接頁面
            return;
        }

        // 顯示分頁資料
        $("#totalCount").text(data.titalCount);
        $("#currentPageSize").text(data.pageSize);
        $("#currPageNo").text(data.currPageNo);
        $("#totalPage").text(data.totalPage);

        //上一頁  和  下一頁處理
        if(data.currPageNo == 1){
            $("#lastPage").hide();
        }else{
            $("#lastPage").show();
        }

        if(data.currPageNo == data.totalPage){
            $("#nextPage").hide();
        }else{
            $("#nextPage").show();
        }

        // 隔行變色
        var count = 1;

        //定義動態展示內容,如果不定義為空字符的話,一直拼接新資料
        var animeCountent = "";

        // 資料決議
        $(data.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='https://www.cnblogs.com/xiaoqigui/p/modAnime.jsp?id="+this.id+"&cid="+this.cid+"' >修改</a>&nbsp;&nbsp;"
                +"<a href='javascript:void;' animeId = '"+this.id+"' class='delAnime' >洗掉</a></td>"
                + "</tr>";

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

//點擊搜索按鈕,根據條件篩選資料
$("#searchAnimes").click(function(){
    showPageAnimeList();
});

4.4 頁面跳轉Ajax

改變form表單中pageNo的值,并呼叫分頁條件查詢函式 showPageAnimeList();

改變form表單中pageNo的值方法:

  1. 通過id選擇input標簽再賦值:$("#pageNo").val(1);
  2. 直接改表單指定name屬性值的input標簽賦值:document.forms[0].pageNo.value = https://www.cnblogs.com/xiaoqigui/p/1;
//分頁跳轉
//首頁
$("tfoot a:eq(0)").click(function(){
    //通過id選擇input標簽再賦值
    //$("#pageNo").val(1);
    //直接改表單指定name屬性值的input標簽賦值
    document.forms[0].pageNo.value = https://www.cnblogs.com/xiaoqigui/p/1;
    showPageAnimeList();
    return false;
});

// 上一頁
$("tfoot a:eq(1)").click(function(){
    $("#pageNo").val(parseInt($("#currPageNo").text()) - 1);
    showPageAnimeList();
    return false;
});


// 下一頁
$("tfoot a:eq(2)").click(function(){
    $("#pageNo").val(parseInt($("#currPageNo").text()) + 1);
    showPageAnimeList();
    return false;
});

// 尾頁
$("tfoot a:eq(3)").click(function(){
    $("#pageNo").val(parseInt($("#totalPage").text()));
    showPageAnimeList();
    return false;
});

4.5 PageSupport

T 表示資料的型別,一般是資料串列List

我感覺比較好的設計話可以是條件分頁查詢所有引數全部放里面 (只是想法,這里沒有用):

  • T:為自定義泛型的資料(一般為List);

  • List :為條件查詢的引數,做回顯資料 (考慮到型別不確定和數量不確定,也可以是動態陣列,先用集合添加,然后toArray轉為陣列);

  • 資料量,當前頁,和總頁數

public class PageSupport<T> {
	//當前頁,顯示頁碼
	private int currPageNo = 1;
	
	//頁面容量
	private int pageSize = 3;

	//總條數(帶條件查詢的總條數)
	private int totalCount;
	
	//總頁數(根據總條數和頁面容量)
	private int totalPage;
    
	//分頁條件查詢的資料
	private T data;
    ......
    public void setTotalCount(int totalCount) {
		//當存在總條數,確定總頁數
		this.totalCount = totalCount;
		//計算總頁數
		this.totalPage = this.totalCount%this.pageSize == 0 ?
				this.totalCount/this.pageSize :
					this.totalCount/this.pageSize + 1;
	}
    ......
}    

4.6 Servlet 中的 方法

  • 通過條件,查詢資料總條數
  • 實體化pageSupport
  • 當前頁的特殊頁碼處理
  • 查詢出資料,放進pageSupport 的 data 中
  • 回傳pageSupport物件(包含分頁資訊,和 條件查詢后分頁的資料)
//查詢所有的動漫串列 帶分頁
protected void animesUsePage(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //獲取顯示的當前頁碼
    Integer pageNo = Integer.parseInt( req.getParameter("pageNo") == null ? "1" : req.getParameter("pageNo") );
    Integer pageSize = Integer.parseInt( req.getParameter("pageSize") == null ? "3" : req.getParameter("pageSize") );

    //獲取查詢條件
    String searchAname = req.getParameter("aname");
    String searauThor = req.getParameter("author");
    String searCid = req.getParameter("cid");

    //根據條件查詢總數
    int totalCount = animeService.animeCount(searchAname,searauThor,searCid);

    //創建分頁物件
    PageSupport<List<Anime>> pageSupport = new PageSupport<List<Anime>>();
    pageSupport.setPageSize(pageSize);
    pageSupport.setTitalCount(totalCount);

    System.out.println("pageNo==>"+pageNo);

    //頁碼特殊處理
    int currPageNo = pageNo;
    //如果當前頁碼小于1,或資料總量等于0
    if(currPageNo < 1 || pageSupport.getTitalCount() == 0) {
        currPageNo = 1;
    }else if(currPageNo > pageSupport.getTotalPage()){
        //如果當前頁碼大于總頁數
        currPageNo = pageSupport.getTotalPage();
    }


    System.out.println("pageNo======>"+pageNo);
    //設定當前頁碼
    pageSupport.setCurrPageNo(currPageNo);

    //設定分頁資料  分頁條件查詢的資料
    pageSupport.setData(animeService.animeListPage(searchAname, searauThor, searCid, pageNo, pageSize));

    //回應資料
    System.out.println("animesUsePage==》" + JSON.toJSONStringWithDateFormat(pageSupport,"yyyy-MM-dd"));
    resp.getWriter().write(JSON.toJSONStringWithDateFormat(pageSupport,"yyyy-MM-dd"));

}

阿里巴巴的資料轉為json的jar包: fastjson-1.2.13.jar

JSON.toJSONString(pageSupport):將資料轉為JSON型別

JSON.toJSONStringWithDateFormat(pageSupport,"yyyy-MM-dd"):將資料轉為JSON型別,并指定其中日期的格式;

4.7 Dao 方法

//條件查詢的資料總量
public int animeCount(String aname, String author, String cid);

//條件查詢后分頁 后的資料集合
public List<Anime> selectAnimeListPage(String aname, String author, String cid, Integer pageNo, Integer pageSize);

//增加分頁SQL陳述句
executeSql += " order by a.id desc limit ?,?";

paramList.add((pageNo - 1) * pageSize);
paramList.add(pageSize);

4.7.1 條件查詢資料總數

//根據條件查詢 資料總數
@Override
public int animeCount(String aname, String author, String cid) {
    //查詢動漫詳情的SQL陳述句
    String executeSql = "select count(1) from animes a where 1=1 ";

    //引數集合
    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)) {
        //標記關鍵字 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);
    }

    //條件中有型別
    if(null != cid && !"0".equals(cid)) {
        executeSql += " and a.cid = ?";
        paramList.add(cid);
    }

    //定義回傳動漫總數
    int totalCount = 0;

    try {
        // 執行查詢
        this.executeSelect(executeSql, paramList.toArray());

        // 決議查詢結果
        if(rs.next()) {
            totalCount = rs.getInt(1);
        }

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        //關閉資源
        this.releaseResource(conn, pstmt, rs);
    }

    //回傳動漫總數量
    return totalCount;
}

4.7.2 條件分頁查詢資料

//查詢  動態添加查詢條件,并分頁后  的資料集合
@Override
public List<Anime> selectAnimeListPage(String aname, String author, String cid, Integer pageNo, Integer pageSize) {
    //查詢動漫詳情的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 ";

    //動態引數,推薦使用
    List<Object> paramList = new ArrayList<Object>();

    //根據不同的查詢條件,拼接SQL陳述句和引數
    //條件中有動漫名
    if(null != aname && !"".equals(aname)) {
        //模糊匹配
        executeSql += " and a.name like concat('%',?,'%')";

        //System.out.println("模糊匹配且標記后的SQL=>"+executeSql);

        paramList.add(aname);
    }

    //條件中有作者
    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('%',?,'%')";

        System.out.println("模糊匹配且標記后的SQL=>"+executeSql);

        paramList.add(author);
    }

    //條件中有型別
    if(null != cid && !"0".equals(cid)) {
        executeSql += " and a.cid = ?";
        paramList.add(cid);
    }

    //增加分頁SQL陳述句
    executeSql += " order by a.id desc limit ?,?";

    paramList.add((pageNo - 1) * pageSize);
    paramList.add(pageSize);

    //定義回傳動漫串列的資料集合
    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、動態修改pageSize

5.1html

tfoot中可以選擇的pageSize,currentPageSize,動態改變后,需要填寫到form表單中的pageSize;

每頁&nbsp;
<!--   <span id = "currentPageSize"></span> -->
<select name="currentPageSize" id="currentPageSize">
</select>
&nbsp;條&nbsp;

5.2 動態加載pageSize

//pageSize 請求獲取一個JSONString型別的PageSize物件集合
//[{"size":3},{"size":5},{"size":10}]
//獲取PageSize,動態展示
$.getJSON("pageSize",function(data){
    //alert(data);
    //定位currentPageSize的下拉元素
    var $currentPageSize = $("#currentPageSize");

    //遍歷回傳的分類集合json集合數,動態加載分類選項
    $(data).each(function(){
        //alert(this.size);
        $currentPageSize.append("<option value='"+this.size+"' class='currentPageSize' >"+this.size+"</option>");
    });

});

5.3 改變psgeSize后觸發事件

  • 觸發事件:

select標簽的選項切換觸發事件change()

  • 獲取切換的值

$(this).children('option:selected').val(); 獲取被選中的選項的值;

修改表單隱藏的pageSize的value值;

  • 這一類修改下面的可選值時,需要將值設定到表單中

將值放到表單中兩種方式:(跟頁面跳轉一樣)

1、通過id選擇賦值:$("#pageSize").val(currentPageSize);

2、通過直接給表單指定name屬性值的input標簽賦值

document.forms[0].pageSize.value = https://www.cnblogs.com/xiaoqigui/p/currentPageSize;

pageSize 為 input標簽的name屬性值;

 //修改pageSize
//select標簽的change()事件, 切換選項時觸發
$("#currentPageSize").change(function(){
    //獲取修改后的 currentPageSize
    var currentPageSize = $(this).children('option:selected').val();
    //alert(currentPageSize);        	
    //修改提交表單的pageSize
    //$("#pageSize").val(currentPageSize);
    //通過document.forms[0].pageSize.value  pageSize 為 input標簽的name屬性值
    document.forms[0].pageSize.value =  https://www.cnblogs.com/xiaoqigui/p/currentPageSize;
    //修改頁面大小后,再主動查詢一次動漫資料
    showPageAnimeList();
});

6、單例模式

模式 特點
懶漢模式 類加載時,不會主動創建物件,而是當記憶體中需要且沒有該類的實體時,才會創建(存在執行緒不安全)雙重校驗
餓漢模式 類加載時,直接創建實體物件,放入記憶體中,需要使用的時候,直接回傳,不存在執行緒不安全

6.1 JdbcConfig

資料庫配置資訊讀取類(使用單例模式,保證資料讀取配置程式運行程序中,只會讀取一次 );

//資料庫配置資訊讀取類(使用單例模式,保證資料讀取配置程式運行程序中,只會讀取一次 jdbc.properties)
public class JdbcConfig {
	//創建 Properties 物件,必須全域,私有()只有內部才可以使用
	Properties properties;
	
	//懶漢:類加載時,不會主動創建物件,而是當記憶體中沒有該類的實體時,才會創建
	//靜態:下面要提供一個獲取實體的靜態方法,getInstance
	//private static JdbcConfig JdbcConfig;
	
	//餓漢:類加載時,直接創建實體物件,放入記憶體中,需要使用的時候,直接回傳,不存在執行緒不安全
	private static JdbcConfig JdbcConfig = new JdbcConfig();
	
	
	//私有構造方法,保證處理在當前類中,其他任何地方斗不可以創建實體
	private JdbcConfig() {
		try {
			//自動實體化  properties
			properties = new Properties();
			
			// 使用反射機制,讀取外部組態檔
			InputStream inputStream = JdbcConfig.class.getClassLoader().getResourceAsStream("jdbc.properties");
			
			// 加載輸入流物件,獲取組態檔內容
			properties.load(inputStream);
			
			System.out.println("------創建JdbcConfig實體成功-------");
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 創建Properties屬性物件
	}
	
	
	/*
	 * 單例模式 :在程式運行期間,保證當前類的實體只有一個,而且是唯一的一個
	 * 懶漢
	 */
//	public static JdbcConfig getInstance() {
//		
//		//判斷記憶體中是否存在JdbcConfig 物件實體,如果不存在就創建實體
//		if(null == JdbcConfig) {
//			//懶漢,不是執行緒安全的,可以使用雙重校驗檢查,實作多執行緒,確保單例
//			//加同步鎖,如果有一個執行緒獲取到同步鎖,其他執行緒等待
//			synchronized (JdbcConfig.class) {
//				//再判斷一次,記憶體是否存在JdbcConfig實體
//				if(null == JdbcConfig) {
//					//創建一個讀取資料庫配置實體物件,放入記憶體,創建物件時就自動讀取資料配置資訊
//					JdbcConfig = new JdbcConfig();
//				}
//			}
//		}
//		
//		return JdbcConfig;
//	}
	
	//餓漢
	public static JdbcConfig getInstance() {
		return JdbcConfig;
	}
	
	//提供一個公共的讀取組態檔的方法
	public String getPropertyByKey(String key) {
		return properties.getProperty(key);
	}

}

6.2 改進后的Basedao

其他不變,只是獲取配置資訊的方式改變了;

直接使用JdbcConfig獲取配置資訊

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");
			
			String driverClass = JdbcConfig.getInstance().getPropertyByKey("driverClass");
			String jdbcUrl =  JdbcConfig.getInstance().getPropertyByKey("jdbcUrl");
			String user =  JdbcConfig.getInstance().getPropertyByKey("user");
			String password =  JdbcConfig.getInstance().getPropertyByKey("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();
		}
	}

}

7、注意點

7.1當一個頁面多個Ajax請求,可能會資料錯亂

需要對 dopost方法進行加鎖(synchronized)操作,讓這個方法,一次只能有一個請求;

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

    //根據請求攜帶的方法引數名引數,呼叫不同業務的處理方法

    String mothedName = req.getParameter("method") == null ? "test" : req.getParameter("method");

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

}

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/501973.html

標籤:Java

上一篇:JAVA的環境搭建

下一篇:Java注解最全詳解(超級詳細)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more