Customize the MVC framework to achieve addition, deletion, modification and query

Table of contents

1. Environment construction

2. Import configuration folder

1. Central controller xml

2. Add, delete and modify configuration files

3. Import tool class

 3. Write the back-end code

1. General CRUD

2. BookDao class

 3. Book implements adding, deleting, modifying and querying classes

4. Paging helper class

4. Write front-end code

1. Data display main interface

         2. Run the display all data servlet by default

3. Add and modify shared pages


1. Environment construction

Optimize the content of the previous article, and import the previously written frmework package into a jar package

 

Then import the relevant jar package

 

2. Import configuration folder

1. Central controller xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>mymvc_crud</display-name>
  <servlet>
    <servlet-name>mvc</servlet-name>
    <servlet-class>com.zking.framework.DispatchServlet</servlet-class>
    <init-param>
      <param-name>configurationLocation</param-name>
      <param-value>/mvc.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>mvc</servlet-name>
    <url-pattern>*.action</url-pattern>
  </servlet-mapping>
</web-app>

2. Add, delete and modify configuration files

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<action path="/book" type="com.zking.web.BookAction">
<!-- 	 查询:BookList.jsp		返回值:list -->
<!-- 	 * 增删改确定:book.action?methodName=list		返回值:toList -->
<!-- 	 * 增加修改跳转对应界面:bookEdit.jsp			返回值:toEdit -->
		<forward name="list" path="/bookList.jsp" redirect="false" />
		<forward name="toList" path="/book.action?methodName=list" redirect="true" />
		<forward name="toEdit" path="/bookEdit.jsp" redirect="false" />
	</action>
	
</config>

 

3. Import tool class

 Enter this JSP custom general pagination link to view the subpackage tool class directory

 

 

 3. Write the back-end code

1. General CRUD

package com.zking.util;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import com.zking.util.DBAccess;
import com.zking.util.PageBean;

/**
 * 所有Dao层的父类
 * 
 * @author 云村小威
 *
 * @2023年7月3日 下午10:52:21
 */
public class BaseDao<T> {
	/**
	 * 通用的增删改方法
	 * 
	 * @param book
	 * @throws Exception
	 */
	public void executeUpdate(String sql, T t, String[] attrs) throws Exception {
		Connection con = DBAccess.getConnection();
		PreparedStatement pst = con.prepareStatement(sql);
		/*
		 * 思路: 1.从传进来的t中读取属性值 2.往预定义对象中设置了值
		 * 
		 * t->book f->bid
		 */
		for (int i = 0; i < attrs.length; i++) {
			Field f = t.getClass().getDeclaredField(attrs[i]);
			f.setAccessible(true);
			pst.setObject(i + 1, f.get(t));
		}
		pst.executeUpdate();
	}

	/**
	 * 通用分页查询
	 * 
	 * @param sql
	 * @param clz
	 * @return
	 * @throws Exception
	 */
	public List<T> executeQuery(String sql, Class<T> clz, PageBean pageBean) throws Exception {
		List<T> list = new ArrayList<T>();
		Connection con = DBAccess.getConnection();
		PreparedStatement pst = null;
		ResultSet rs = null;

		/*
		 * 是否需要分页? 无需分页(项目中的下拉框,查询条件教员下拉框,无须分页) 必须分页(项目中列表类需求、订单列表、商品列表、学生列表...)
		 */
		if (pageBean != null && pageBean.isPagination()) {
			// 必须分页(列表需求)
			String countSQL = getCountSQL(sql);
			pst = con.prepareStatement(countSQL);
			rs = pst.executeQuery();
			if (rs.next()) {
				pageBean.setTotal(String.valueOf(rs.getObject(1)));
			}

			// 挪动到下面,是因为最后才处理返回的结果集
			String pageSQL = getPageSQL(sql, pageBean);// 符合条件的某一页数据
			pst = con.prepareStatement(pageSQL);
			rs = pst.executeQuery();
		} else {
			// 不分页(select需求)
			pst = con.prepareStatement(sql);// 符合条件的所有数据
			rs = pst.executeQuery();
		}

		while (rs.next()) {
			T t = clz.newInstance();
			Field[] fields = clz.getDeclaredFields();
			for (Field f : fields) {
				f.setAccessible(true);
				f.set(t, rs.getObject(f.getName()));
			}
			list.add(t);
		}
		return list;
	}

	/**
	 * 将原生SQL转换成符合条件的总记录数countSQL
	 * 
	 * @param sql
	 * @return
	 */
	private String getCountSQL(String sql) {
		return "select count(1) from (" + sql + ") t";
	}

	/**
	 * 将原生SQL转换成pageSQL
	 * 
	 * @param sql
	 * @param pageBean
	 * @return
	 */
	private String getPageSQL(String sql, PageBean pageBean) {
		return sql + " limit " + pageBean.getStartIndex() + "," + pageBean.getRows();
	}
}

2. BookDao class

package com.zking.dao;

import java.util.List;

import com.zking.entity.Book;
import com.zking.util.BaseDao;
import com.zking.util.PageBean;
import com.zking.util.StringUtils;

/**
 * bookdao类
 * @author 云村小威
 *
 * @2023年7月3日 下午10:51:39
 */
public class BookDao extends BaseDao<Book>{
	/*
	 * public void add(Book book) throws Exception {
		String sql = "insert into t_mvc_book values(?,?,?)";
		Connection con = DBAccess.getConnection();
		PreparedStatement pst = con.prepareStatement(sql);
		pst.setObject(1, book.getBid());
		pst.setObject(2, book.getBname());
		pst.setObject(3, book.getPrice());
		pst.executeUpdate();
		}
		增删改查的通用套路
		1.建立链接
		2.预定义对象PreparedStatement
		3.设置占位符的?的值
		4.pst.executeUpdate();
		1.
	 */
	public void add(Book book) throws Exception {
		String sql = "insert into t_mvc_book values(?,?,?)";
		super.executeUpdate(sql, book, new String[] {"bid","bname","price"});
	}
	
	public void edit(Book book) throws Exception {
		String sql = "update t_mvc_book set bname = ?, price = ? where bid = ?";
		super.executeUpdate(sql, book, new String[] {"bname","price","bid"});
	}
	
	public void delete(Book book) throws Exception {
		String sql = "delete from t_mvc_book where bid = ?";
		super.executeUpdate(sql, book, new String[] {"bid"});
	}
	
	public List<Book> list(Book book,PageBean pageBean) throws Exception {
		String sql = "select * from t_mvc_book where 1=1 ";
		String bname = book.getBname();
		if(StringUtils.isNotBlank(bname)) {
			sql += " and bname like '%"+bname+"%'";
		}
		return super.executeQuery(sql, Book.class, pageBean);
	}
	
}

 

 3. Book implements adding, deleting, modifying and querying classes

package com.zking.web;

import java.util.List;

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

import com.zking.dao.BookDao;
import com.zking.entity.Book;
import com.zking.framework.ActionSupport;
import com.zking.framework.ModelDriver;
import com.zking.util.PageBean;

/**
 * book工作类
 * @author 云村小威
 *
 * @2023年7月3日 下午10:53:52
 */
public class BookAction extends ActionSupport implements ModelDriver<Book>{
	private Book book = new Book();
	private BookDao bookDao = new BookDao();
	@Override
	public Book getModel() {
		return book;
	}
	
	/*
	 * 增删改最终都要跳回查询界面
	 * 分析增删改查一共有多少结果集的配置
	 * 查询:BookList.jsp		返回值:list
	 * 增删改确定:book.action?methodName=list		返回值:toList
	 * 增加修改跳转对应界面:bookEdit.jsp			返回值:toEdit
	 */
	public String add(HttpServletRequest req, HttpServletResponse resp) {
		try {
			bookDao.add(book);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "toList";
	}
	
	public String list(HttpServletRequest req, HttpServletResponse resp) {
		try {
			PageBean pageBean = new PageBean();
			pageBean.setRequest(req);
			List<Book> list = bookDao.list(book,pageBean);
			req.setAttribute("books", list);
			req.setAttribute("pageBean", pageBean);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "list";
	}
	
	public String delete(HttpServletRequest req, HttpServletResponse resp) {
		try {
			bookDao.delete(book);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "toList";
	}
	
	public String edit(HttpServletRequest req, HttpServletResponse resp) {
		try {
			bookDao.edit(book);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "toList";
	}
	/**
	 * 跳转到新增修改页面
	 * @param req
	 * @param resp
	 * @return
	 */
	public String toEdit(HttpServletRequest req, HttpServletResponse resp) {
		try {
			/*
			 * 如果是跳转修改页面,那么需要做bid条件的精准查询
			 */
			if(book.getBid() != 0) {
				List<Book> list = bookDao.list(book, null);
				req.setAttribute("b", list.get(0));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "toEdit";
	}
}

4. Paging helper class

package com.zking.tag;

import com.zking.util.PageBean;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
import java.io.IOException;
import java.util.Map;
import java.util.Set;

/**
 * Page助手类
 * 
 * @author 云村小威
 *
 */
public class PageTag extends BodyTagSupport {
	private static final long serialVersionUID = 1L;

	private PageBean pageBean;

	public PageBean getPageBean() {
		return pageBean;
	}

	public void setPageBean(PageBean pageBean) {
		this.pageBean = pageBean;
	}

	@Override
	public int doStartTag() throws JspException {
		// 获取流
		JspWriter out = pageContext.getOut();
		try {
			out.print(toHTML());
		} catch (IOException e) {
			e.printStackTrace();
		}
		return SKIP_BODY;
	}

	/**
	 * JSP自定义页面内容展示
	 * 
	 * @return
	 */
	private String toHTML() {
		StringBuilder sb = new StringBuilder();

		// 这里拼接的是一个上一次发送的请求以及携带的参数,唯一改变的就是页码
		sb.append("<form id='pageBeanForm' action='" + pageBean.getUrl() + "' method='post'>");
		sb.append("<input type='hidden' name='page'>");
		// 重要设置拼接操作,将上一次请求参数携带到下一次
		Map<String, String[]> paMap = pageBean.getParameterMap();
		if (paMap != null && paMap.size() > 0) {
			Set<Map.Entry<String, String[]>> entrySet = paMap.entrySet();
			for (Map.Entry<String, String[]> entry : entrySet) {
				for (String val : entry.getValue()) {
					if (!"page".equals(entry.getKey())) {
						sb.append("<input type='hidden' name='" + entry.getKey() + "' value='" + val + "'>");
					}
				}
			}
		}
		sb.append("</form>");
		
		/**
		 * 页码数据配置
		 */
		int page = pageBean.getPage(); //当前页码
		int max = pageBean.getMaxPage();//最大页码
		int before = page > 4 ? 4 : page - 1;//当前页码前面的页码
		int after = 10 - 1 - before;//当前页码后面的页码
		
		//如果最大页码没有10页,就显示当前页面后面的所有页码 max - page
		after = page + after > max ? max - page : after;
		// 初始页码和结束页码值判断 disabled
		boolean startFlag = page == 1;
		boolean endFlag = max == page;

		// 拼接分页条
		sb.append("<ul class='pagination'>");
		sb.append("<li class='page-item " + (startFlag ? "disabled" : "")
				+ "'><a class='page-link' href='javascript:gotoPage(1)'>首页</a></li>");
		sb.append("<li class='page-item " + (startFlag ? "disabled" : "")
				+ "'><a class='page-link' href='javascript:gotoPage(" + pageBean.getPrevPage() + ")'>&lt;</a></li>");

		// 代表了当前页的前4页
		for (int i = before; i > 0; i--) {
			sb.append("<li class='page-item'><a class='page-link' href='javascript:gotoPage(" + (page - i) + ")'>"
					+ (page - i) + "</a></li>");
		}

		sb.append("<li class='page-item active'><a class='page-link' href='javascript:gotoPage(" + pageBean.getPage()
				+ ")'>" + pageBean.getPage() + "</a></li>");

		// 代表了当前页的后5页
		for (int i = 1; i <= after; i++) {
			sb.append("<li class='page-item'><a class='page-link' href='javascript:gotoPage(" + (page + i) + ")'>"
					+ (page + i) + "</a></li>");
		}

		sb.append("<li class='page-item " + (endFlag ? "disabled" : "")
				+ "'><a class='page-link' href='javascript:gotoPage(" + pageBean.getNextPage() + ")'>&gt;</a></li>");
		sb.append("<li class='page-item " + (endFlag ? "disabled" : "")
				+ "'><a class='page-link' href='javascript:gotoPage(" + pageBean.getMaxPage() + ")'>尾页</a></li>");
		sb.append(
				"<li class='page-item go-input'><b>到第</b><input class='page-link' type='text' id='skipPage' name='' /><b>页</b></li>");
		sb.append("<li class='page-item go'><a class='page-link' href='javascript:skipPage()'>确定</a></li>");
		sb.append("<li class='page-item'><b>共" + pageBean.getTotal() + "条</b></li>");
		sb.append("</ul>");

		// 拼接分页的js代码
		sb.append("<script type='text/javascript'>");
		sb.append("function gotoPage(page) {");
		sb.append("document.getElementById('pageBeanForm').page.value = page;");
		sb.append("document.getElementById('pageBeanForm').submit();");
		sb.append("}");
		sb.append("function skipPage() {");
		sb.append("var page = document.getElementById('skipPage').value;");
		sb.append("if (!page || isNaN(page) || parseInt(page) < 1 || parseInt(page) > " + max + ") {");
		sb.append("alert('请输入1~N的数字');");
		sb.append("return;");
		sb.append("}");
		sb.append("gotoPage(page);");
		sb.append("}");
		sb.append("</script>");

		return sb.toString();
	}
}

 

4. Write front-end code

1. Data display main interface

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>	
<%@taglib uri="http://jsp.ycxw.cn" prefix="w" %>	
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link
	href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"
	rel="stylesheet">
<script
	src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js"></script>
<title>书籍列表</title>
<style type="text/css">
.page-item input {
	padding: 0;
	width: 40px;
	height: 100%;
	text-align: center;
	margin: 0 6px;
}

.page-item input, .page-item b {
	line-height: 38px;
	float: left;
	font-weight: 400;
}

.page-item.go-input {
	margin: 0 10px;
}
</style>
</head>
<body>
<c:if test="${empty books }">
<jsp:forward page="/BookServlet"></jsp:forward>
</c:if>
	<form class="form-inline"
		action="${pageContext.request.contextPath }/book.action?methodName=list" method="post">
		<div class="form-group mb-2">
			<input type="text" class="form-control-plaintext" name="bname" placeholder="请输入书籍名称">
				<input name="pagination" value="false" type="hidden">
		</div>
		<button type="submit" class="btn btn-primary mb-2">查询</button>
		<a class="btn btn-primary mb-2" href="${pageContext.request.contextPath }/book.action?methodName=toEdit">新增</a>
	</form>

	<table class="table table-striped">
		<thead>
			<tr>
				<th scope="col">书籍ID</th>
				<th scope="col">书籍名</th>
				<th scope="col">价格</th>
				<th scope="col">操作</th>
			</tr>
		</thead>
		<tbody>
			<c:forEach  var="b" items="${books }">
			<tr>
				<td>${b.bid }</td>
				<td>${b.bname }</td>
				<td>${b.price }</td>
				<td>
					<a href="${pageContext.request.contextPath }/book.action?methodName=toEdit&bid=${b.bid}">修改</a>
					<a href="${pageContext.request.contextPath }/book.action?methodName=delete&bid=${b.bid}">删除</a>
				</td>
			</tr>
			</c:forEach>
		</tbody>
	</table>
	<!-- 这一行代码就相当于前面分页需求前端的几十行了 -->
	<w:page pageBean="${pageBean }"></w:page>
</body>
</html>

2. Run the display all data servlet by default

package com.zking.web;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/BookServlet")
public class BookServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.sendRedirect(request.getContextPath()+"/book.action?methodName=list");
	}

}

3. Add and modify shared pages

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://jsp.ycxw.cn" prefix="z"%>	
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>	
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link
	href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"
	rel="stylesheet">
<script
	src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js"></script>
<title>书籍新增/修改</title>
</head>
<body>
	<form class="form-inline"
		action="${pageContext.request.contextPath }/book.action?methodName=${empty b ? 'add' : 'edit'}" method="post">
		书籍ID:<input type="text" name="bid" value="${b.bid }"><br>
		书籍名称:<input type="text" name="bname" value="${b.bname }"><br>
		书籍价格:<input type="text" name="price" value="${b.price }"><br>
		<input type="submit">
	</form>


</body>
</html>

Guess you like

Origin blog.csdn.net/Justw320/article/details/131526586