Thymeleaf二:增删改查扩展
一、分页显示
-
在全查询的基础上,增加了一个参数。
重点是控制首页、上一页、下一页、尾页的可点击情况
-
DAO的实现类
public class ListIpm extends BaseDAO<Customers> implements ListDAO{ // 分页显示 @Override public List<Customers> getList(Connection conn ,int pageOn) { String sql = "select cust_name name,cust_email email,cust_birth birth,cust_id id from customers limit ? , 2"; return super.CommonRetrieve(conn, sql,(pageOn-1)*2); } // 统计客户数量 @Override public Long getCount(Connection conn) { String sql = "select count(*) from customers"; return super.getValue(conn, sql); } }
-
Servlet组件
@WebServlet("/index") public class IndexServlet extends ViewBaseServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) { Connection conn = null; try { // 1.声明并初始化pageOn,是为了在js文件中page参数为空时,确保heml页面有具体的分页显示 int pageOn = 2; // 2.count变量的类型必须是Long,应为SQL语言中的count()函数返回值类型是Bigint long count = 0; // 3.连接数据库,获取数据库中的数据,返回一个集合 conn = JdbcUtils.getConnection(); ListIpm ipm = new ListIpm(); // 4.获取按钮被触发后,从html文件中传送到js文件内的页面值 String pageStr = req.getParameter("page"); if (StringUtil.isNotEmpty(pageStr)) { pageOn = Integer.parseInt(pageStr); } // 5.获取该分页面上的客户信息列表 List<Customers> custList = ipm.getList(conn,pageOn); // 6.获取客户个数,用于计算尾页的页号 count = ipm.getCount(conn); int max = (int) (count+2-1)/2; // 7.将需要在html文件内调用的变量(数据)以键值对的形式保存到session作用域中, HttpSession session = req.getSession(); session.setAttribute("cl",custList); session.setAttribute("page",pageOn); session.setAttribute("max",max); // 8.调用父类的模板处理方法,组装对应的html文件 super.processTemplate("index",req,resp); } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtils.closeResource(conn,null); } } }
-
html文件
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <html> <head> <meta charset="UTF-8"> <base href="http://localhost:8080/page/" > <link rel="stylesheet" href="CSS/index.css" > <script language="JavaScript" th:src="@{js/index.js}" ></script> </head> <body> <div id="div_contain"> <div id="div_fruit_list"> <p class="center f32">欢迎使用客户后台管理系统</p> <table id="tbl_fruit"> <tr> <th>cust_id</th> <th>cust_name</th> <th>cust_email</th> <th>cust_birth</th> </tr> <tr th:if="${#lists.isEmpty(session.cl)}"> <td colspan="4">无客户名单!</td> </tr> <tr th:unless="${#lists.isEmpty(session.cl)}" th:each="cust : ${session.cl}"> <td th:text="${cust.id}">1</td> <td th:text="${cust.name}">太白金星</td> <td th:text="${cust.email}" >tbstart@163.com</td> <td th:text="${cust.birth}">1000-1-1</td> </tr> </table> <div style="width:60% ; margin-left: 20%"> <!-- 1.button 是普通按钮,点击后需要触发一个js事件才能实现对应的功能 2.th:disable=${}” 当大括号内的条件判断成立时,button按钮失效 当session.page为1时,首页和上一页都不能被触发 当session.page为max时,尾页和下一页都不能被触发 --> <input th:type="button" th:value="首页" th:onclick="|pageControl(1)|" th:disabled="${session.page==1}"/> <input th:type="button" th:value="上一页" th:onclick="|pageControl(${session.page-1})|" th:disabled="${session.page==1}"/> <input th:type="button" th:value="下一页" th:onclick="|pageControl(${session.page+1})|" th:disabled="${session.page==session.max}"/> <input th:type="button" th:value="尾页" th:onclick="|pageControl(${session.max})|" th:disabled="${session.page==session.max}"/> </div> </div> </div> </body> </html>
-
js文件
function pageControl(page) { if (confirm("确认")) { window.location.href = 'index?page=' + page; } }
二、增加关键字查询功能
-
关键字查询,就是SQL中的模糊查询
-
DAO内的实现类
public class ListIpm extends BaseDAO<Customers> implements ListDAO{ @Override public List<Customers> getList(Connection conn ,String str,int pageOn) { String sql = "select cust_name name,cust_email email,cust_birth birth,cust_id id from customers where cust_email like ? limit ? , 2"; return super.CommonRetrieve(conn, sql,str,(pageOn-1)*2); } @Override public Long getCount(Connection conn,String str) { String sql = "select count(*) from customers where cust_email like ?"; return super.getValue(conn, sql,str); } }
-
Servlet组件
@WebServlet("/index") public class IndexServlet extends ViewBaseServlet { // 一、在html文件内点击查询按钮,提交表单后,其实现的主功能与doGet方法内的一致,故可如下直接挑战 @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } /* 二、将doPost方法中的功能合并到了doGet方法内,故难点在于将get响应和post响应用条件 1.用if语句加以区分,判断条件: 借助html的查询表单中设置的隐藏域,如果查询按钮被触发,则隐藏域内的value一同被发送过 来了。通过req.getParameter获取到的值与隐藏域中value值比较,相同则转入post请求的功 能设置中 2.两个响应的异同: 2.1 post: 2.1.1 首先,点击查询肯定是首次响应,故应将分页变量归1,让关键字查询后的结果从第一页 开始显示。 2.1.2 其次,通过getParameter获取关键字变量,赋值给模糊查询的传参变量key, 如果关键字变量为空,则需要将key的值设置为""或"_",千万不可设置成为空格" " 2.1.3 最后将从关键字查询变量获取的值保存到作用域中,因为再查询提交后,再去点下一页或尾页 按钮时,仍需模糊查询的传参变量保持为该关键字变量 2.2 get: 包含了普通查询和关键字查询提交后触发分页按钮两种请求情况 2.2.1 首先,确定页面。先提起js文件中的参数值page,如果不为空,才赋值给分页控制变量 pageOn,否则判定为第一次普通查询,pageOn仍然是初始化值1 2.2.2 其次,提取保存在作用域中的关键字查询变量,若为null,则与普通查询一致,设模糊查询 的传参变量key为"",否则,该get请求就是来自于关键字查询后的分页按钮请求,那么 key值必须保持为保存在作用域内的关键字查询变量 */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) { Connection conn = null; try { req.setCharacterEncoding("UTF-8"); // 1.连接数据库,实例化DAO中的实现类,得到session对象 conn = JdbcUtils.getConnection(); ListIpm ipm = new ListIpm(); HttpSession session = req.getSession(); // 2.给分页变量pageOn赋初始值,用于在js无返回页面值时,可以明确显示html的首次查询的 分页 int pageOn = 1; // 3.声明并初始化模糊查询的传参变量key String key = null; // 4 用if分支结构来区分是来自post请求还是get请求 // 4.1 post请求,则可捕获到隐藏域传参 String oper = req.getParameter("oper"); if (StringUtil.isNotEmpty(oper) && "search".equals(oper)) { // 关键字查询,要从第一个分页开始,但不确定现在的pageOn的值的情况,所以要重置为1 pageOn = 1; // 获取查询关键字的值 key = req.getParameter("keyword"); // 如果没有关键字,必须将模糊查询的传参变量key的值设为"",因为null不能传入SQL中 if (StringUtil.isEmpty(key)) { key = ""; } // 将查询关键字的值保存在作用域中,为接下来调用做准备 session.setAttribute("k",key); }else { // 4.2 get请求 /* 明确分页变量pageOn的值,如果能从js文件中取到值,那么就不是第一次查询了, 否则pageOn仍是初始值1 */ String pageStr = req.getParameter("page"); if (StringUtil.isNotEmpty(pageStr)) { pageOn = Integer.parseInt(pageStr); } /* 明确是否为关键字查询后的分页按钮请求,通过首先将保存在作用域中的关键字查询变量 赋值给key,可以确保关键字查询后,按了下一页,显示出来的是仍然是关键字查询结果中 第二页 */ Object keyObj = session.getAttribute("k"); if (keyObj == null) { key = ""; }else { key = (String) keyObj; } } // 5.进行模糊查询 List<Customers> custList = ipm.getList(conn,"%"+ key +"%",pageOn); // 6.获取客户个数,确定最大分页数 long count = 0L; count = ipm.getCount(conn,"%"+key+"%"); int max = (int) (count+2-1)/2; // 7.将下面变量保存到作用域中,用于在html中被调用 session.setAttribute("pageOn",pageOn); session.setAttribute("cl",custList); session.setAttribute("max",max); // 8.调用父类的模板处理方法 super.processTemplate("index",req,resp); } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtils.closeResource(conn,null); } } }
-
html文件
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" th:href="@{CSS/index.css}"> <script language="JavaScript" th:src="@{js/index.js}" ></script> </head> <body> <div id="div_contain"> <div id="div_fruit_list"> <p class="center f32">欢迎使用客户后台管理系统</p> <div style="float: left; margin-left: 20%;width: 60%"> <form th:action="@{index}" method="post"> <!-- 因为该html页面上还有其它按钮,为了避免在组件中其它按钮提交的数据混淆,故设置该隐藏域 --> <input type="hidden" name="oper" value="search"> 请输入查询关键字<input type="text" name="keyword"/> <input type="submit" value="查询" /> </form> </div> <table id="tbl_fruit"> <tr> <th>cust_id</th> <th>cust_name</th> <th>cust_email</th> <th>cust_birth</th> </tr> <tr th:if="${#lists.isEmpty(session.cl)}"> <td colspan="4">无客户名单!</td> </tr> <tr th:unless="${#lists.isEmpty(session.cl)}" th:each="cust : ${session.cl}"> <td th:text="${cust.id}">1</td> <td th:text="${cust.name}">太白金星</td> <td th:text="${cust.email}" >tbstart@163.com</td> <td th:text="${cust.birth}">1000-1-1</td> </tr> </table> <div style="width:60% ; margin-left: 20%"> <input th:type="button" th:value="首页" th:onclick="|pageControl(1)|" th:disabled="${session.pageOn==1}"/> <input th:type="button" th:value="上一页" th:onclick="|pageControl(${session.pageOn-1})|" th:disabled="${session.pageOn==1}"/> <input th:type="button" th:value="下一页" th:onclick="|pageControl(${session.pageOn+1})|" th:disabled="${session.pageOn==session.max}"/> <input th:type="button" th:value="尾页" th:onclick="|pageControl(${session.max})|" th:disabled="${session.pageOn==session.max}"/> </div> </div> </div> </body> </html>
-
js文件
function pageControl(page) { if (confirm("确认")) { window.location.href = 'index?page=' + page; } }
注:
- like模糊查询中,如果要全部查询,like = “” 或 like= “__” ,绝对不能是like = " "