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>
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> "
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"/>
//點擊添加,跳轉到添加動漫頁面
$("#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"/>
<a href="https://www.cnblogs.com/xiaoqigui/p/#">首頁</a> |
<a href="https://www.cnblogs.com/xiaoqigui/p/#" id="lastPage"><<上一頁</a> |
<a href="https://www.cnblogs.com/xiaoqigui/p/#" id="nextPage">下一頁>></a> |
<a href="https://www.cnblogs.com/xiaoqigui/p/#">尾頁</a> |
共 <span id="totalCount"></span> 條
每頁
<!-- <span id = "currentPageSize"></span> -->
<select name="currentPageSize" id="currentPageSize">
</select>
條
當前第 <span id="currPageNo"></span> 頁 /
共 <span id="totalPage"></span> 頁
</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> "
+"<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的值方法:
- 通過id選擇input標簽再賦值:$("#pageNo").val(1);
- 直接改表單指定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
-
資料量,當前頁,和總頁數
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;
每頁
<!-- <span id = "currentPageSize"></span> -->
<select name="currentPageSize" id="currentPageSize">
</select>
條
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注解最全詳解(超級詳細)
