自定义mvc实现增删改查

一、前言

我在之前的博客中已经向大家介绍了自定义mvc的基本知识。还不是很了解的可以看一下之前的博客。
传送门在此: https://blog.csdn.net/qq_45547474/article/details/106531932.

那么这次我就给大家讲解一下用自定义mvc来解决增删改查。
首先了解一下servlet是如何解决增删改查的。

二、用servlet解决增删改查

1、servlet解决代码方式简单了解

那我们先看到一个类列表,我们可以了解到为了完成一个增删改查,使用servlet会显得代码很多,极其繁琐。
在这里插入图片描述
我们调出一段servlet查询需求的代码看一下:

//zouyan
  public List<Book> getAll(Book b,PageBean pageBean) throws SQLException{
	List<Book> ls=new ArrayList<Book>();
	String sql="select * from t_mvc_book where true";
    String bname = b.getBname();
	if(StringUtils.isNotBlank(bname)) {
		sql+=" and bname like '%"+bname+"%'";
	}
	Connection  con=DBAccess.getConnection();
  PreparedStatement ps = con.prepareStatement(sql);
	ResultSet   rs=ps.executeQuery();
	while(rs.next()) {
		ls.add(new Book(rs.getInt("bid"),rs.getString("bname"),rs.getFloat("price")));
	}
	DBAccess.close(con, ps, rs);
	return ls;	
 }

可以看出代码的一个很明显的弊端 : if条件分支过多,代码过于臃肿。
包括还有界面和jar包,相对于自定义mvc解决增删改查来说servlet解决会简单很多。因为servlet存在很多的弊端。

2、弊端

1、if条件分支过多,代码过于臃肿
2、处理前端jsp传递到后端值得封装代码量过大
3、处理完业务逻辑应该跳转指定页面

但是自定义mvc却很好的可以解决 :
(自定mvc)
1、if条件分支过多,代码过于臃肿
分析:if代码块中就是调用了当前类的对应方法
处理:反射动态调用方法

2、处理前端jsp传递到后端值得封装代码量过大
分析:给指定的类属性赋值
处理:通过反射读写属性

3、处理完业务逻辑应该跳转指定页面
分析:不同的逻辑处理完要跳转的页面不同,代码的位置过于混乱,我们希望同一管理
处理:xml建模将结果页面统一配置

那么我们就通过代码来了解吧。

三、自定义mvc解决增删改查

1、步骤解读

使用到的工具:mysql+eclipse
利用mvc完成增删改
在这里插入图片描述
那我们就按照步骤来完成吧。

2、代码了解

首先来完成实体类的代码,你需要完成什么代码就写上什么属性就可以了。
我所操纵的是一个job表

那么实体类代码就是这样写的:

//zouyan
/**
 * 招聘信息的实体类
 * @author zouyan
 *
 * Orange_南橙
 */
public class Recruitment{

	private String id;
	private String job;
	private String company;
	private String address;
	private String salary;
	private String url;
	private String limit;
	private Date time;
	private String desc;
	private String jobHandle;
	private String addressHandle;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getJob() {
		return job;
	}
	public void setJob(String job) {
		this.job = job;
	}
	public String getCompany() {
		return company;
	}
	public void setCompany(String company) {
		this.company = company;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public String getSalary() {
		return salary;
	}
	public void setSalary(String salary) {
		this.salary = salary;
	}
	public String getLimit() {
		return limit;
	}
	public void setLimit(String limit) {
		this.limit = limit;
	}
	public Date getTime() {
		return time;
	}
	public void setTime(Date time) {
		this.time = time;
	}
	
	public String getUrl() {
		return url;
	}
	public void setUrl(String url) {
		this.url = url;
	}
	public String getDesc() {
		return desc;
	}
	public void setDesc(String desc) {
		this.desc = desc;
	}
	public String getJobHandle() {
		return jobHandle;
	}
	public void setJobHandle(String jobHandle) {
		this.jobHandle = jobHandle;
	}
	public String getAddressHandle() {
		return addressHandle;
	}
	public void setAddressHandle(String addressHandle) {
		this.addressHandle = addressHandle;
	}
	
	@Override
	public String toString() {
		return "Recruitment [id=" + id + ", job=" + job + ", company=" + company + ", address=" + address + ", salary="
				+ salary + ", url=" + url + ", limit=" + limit + ", time=" + time + ", desc=" + desc + ", jobHandle="
				+ jobHandle + ", addressHandle=" + addressHandle + "]";
	}
	
	public Recruitment(String id, String job, String company, String address, String salary, String url, String limit,
			Date time, String desc, String jobHandle, String addressHandle) {
		this.id = id;
		this.job = job;
		this.company = company;
		this.address = address;
		this.salary = salary;
		this.url = url;
		this.limit = limit;
		this.time = time;
		this.desc = desc;
		this.jobHandle = jobHandle;
		this.addressHandle = addressHandle;
	}
	public Recruitment() {}
}

然后实体类完成之后,就是dao层里面的代码了。

//zouyan
public class BaseDao<K> {

	public List<K> executeQuery(String sql, Class clz,PageBean pagebean) throws Exception{
		List<K> ls=new ArrayList<K>();
		
		Connection con = DBAccess.getConnection();
		
		PreparedStatement ps = con.prepareStatement(sql);
		
		ResultSet rs=null;
		if(pagebean!=null && pagebean.isPagination()) {
		//想分页
			String countSql=getCountSql(sql);
			ps = con.prepareStatement(countSql);
			rs=ps.executeQuery();
			if(rs.next()) {
				pagebean.setTotal(rs.getObject(1).toString());
			}
			//展示想要看到的数据 比如说第三条的数据
			String pageSql=getPageSql(sql,pagebean);
			ps = con.prepareStatement(pageSql);
			rs=ps.executeQuery();
		}else {
		//不想分页
			ps = con.prepareStatement(sql);
			rs=ps.executeQuery();
		}
		
		while(rs.next()) {
			//ls.add(new Book(rs.getInt("bid"), rs.getString("bname"), rs.getString("price")));
			K k=(K)clz.newInstance();
			//Field[] fields = clz.getDeclaredFields();
			for (Field f : clz.getDeclaredFields()) {
				f.setAccessible(true);
				f.set(k, rs.getObject(f.getName()));
			}
			ls.add(k);
		}
		DBAccess.close(con, ps, rs);
		return ls;
	}
	
	public int executeUpdate(String sql,K k,String attrs[]) throws SQLException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		Connection con=DBAccess.getConnection();
		PreparedStatement ps = con.prepareStatement(sql);
		/*ps.setObject(1, book.getBid());
		ps.setObject(2, book.getBname());
		ps.setObject(3, book.getPrice());*/
		//以上三行代码的意思是,将参数t中的属性值,赋值给object对象
		int loop=1;
		Field f= null;
		//attrs 属性值
		for (String attr : attrs) {
			f=k.getClass().getDeclaredField(attr);
			f.setAccessible(true);
			ps.setObject(loop++, f.get(k));
		}
		int n=ps.executeUpdate();
		DBAccess.close(con, ps, null);
		return n;
	}

	private String getCountSql(String sql) {
		// TODO Auto-generated method stub
		return "select count(1) from ("+sql+") t";
	}

	private String getPageSql(String sql, PageBean pagebean) {
		// TODO Auto-generated method stub
		return sql+" limit "+pagebean.getStartIndex()+","+pagebean.getRows();
	}
}

然后dao层的好了之后,看到web层的代码。web层的就要考虑增删改查的查询了。

//zouyan
public class RecruitmentServlet extends ActionSupport implements ModelDriven<Recruitment>{

	private static final long serialVersionUID = 1L;
	private Recruitment r=new Recruitment();
	public RecruitmentDao rd=new RecruitmentDao();
	
	public String list(HttpServletRequest req, HttpServletResponse resp) throws Exception {
		Recruitment re=new Recruitment();
		req.setCharacterEncoding("utf-8");
		String name=req.getParameter("name");
		re.setCompany(name);
		
		PageBean pageBean=new PageBean();
		pageBean.setRequest(req);

		req.setAttribute("pageBean", pageBean);
		try {
			List<Recruitment> ls= rd.list(re, pageBean);
			req.setAttribute("recruitment", ls);
			req.setAttribute("name", name);
			req.getRequestDispatcher("/index.jsp").forward(req, resp);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "list";
	}

	//新增
	public String add(HttpServletRequest req, HttpServletResponse resp) throws Exception {
		rd.add(r);
		return "toList";
	}
	//删除
	public String del(HttpServletRequest req, HttpServletResponse resp) throws Exception {
		rd.del(r);
		return "toList";
	}
	//修改
	public String edit(HttpServletRequest req, HttpServletResponse resp) throws Exception {
		rd.edit(r);
		return "toList";
	}
	//跳转修改
	public String toEdit(HttpServletRequest req, HttpServletResponse resp) throws Exception {
		Recruitment re=this.rd.list(r, null).get(0);
		req.setAttribute("r", re);
		return "toEdit";
	}
	//查询单个
	public String one(HttpServletRequest req, HttpServletResponse resp) throws Exception {
		Recruitment re=this.rd.list(r, null).get(0);
		req.setAttribute("Recruitment", re);
		return "toOne";
	}
	
	@Override
	public Recruitment getModel() {
		// TODO Auto-generated method stub
		return r;
	}
}

ok之后,记得对xml进行修改,因为很多时候就会忘记修改xml里面的路径:
在这里插入图片描述
最后就是界面jsp的代码了。

//zouyan
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@taglib prefix="z" uri="/zouyan" %>
<!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 action="${pageContext.request.contextPath }/recruitment.action?methodName=list" method="post">
		<input name="name" type="text" value="${name }" />
		<input type="submit" value="查询" />
	</form>
	<table border="1px" width="100%" >
		<tr>
			<td align="center">职位</td>
			<td align="center">公司</td>
			<td align="center">工作地址</td>
			<td align="center">薪资</td>
			<td align="center">学历要求</td>
			<td align="center">爬取时间</td>
			<td align="center">查看详情</td>
		</tr>
		<c:forEach items="${recruitment}" var="r" >
			<tr>
			<td align="center">${r.job}</td>
			<td align="center">${r.company }</td>
			<td align="center">${r.address }</td>
			<td align="center">${r.salary }</td>
			<td align="center">${r.limit }</td>
			<td align="center">${r.time }</td>
			<td align="center">
				<a href="${pageContext.request.contextPath }/recruitment.action?methodName=one&id=${r.id}">查看详情</a>
			</td>
		</tr>
		</c:forEach>
	</table>
	 <z:page pageBean="${pageBean }"></z:page> 
	 <a href="add.jsp">增加</a>
</body>
</html>

然后,还会有增加界面和修改界面的一个界面显示。我就不在这里做详细讲解了。

1.分页工具包

分页工具包是可以用到分页代码里的,类似一个大工厂,拿过去就可以了。方便至极。

//zouyan
package com.zouyan.util;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

/**
 * 分页工具类
 *
 */
public class PageBean {

	private int page = 1;// 页码

	private int rows = 10;// 页大小

	private int total = 0;// 总记录数

	private boolean pagination = true;// 是否分页
	//上一次查询所携带的查询条件
	private Map<String, String[]> parameterMap=new HashMap<String, String[]>();
	//上一次查询的url
	private String url;
	
	public void setRequest(HttpServletRequest req) {
		//初始化jsp页面传递过来的当前页
		this.setPage(req.getParameter("page"));
		//初始化jsp页面传递过来的页大小
		this.setRows(req.getParameter("rows"));
		//初始化jsp页面传递过来的是否分页
		this.setPagination(req.getParameter("pagination"));
		//保留上一次的查询请求
		this.setUrl(req.getRequestURI().toString());
		//保留上一次的查询条件
		this.setParameterMap(req.getParameterMap());
	}
	
	private void setPagination(String parameter) {
		//只有填写了false才代表不分页
		this.setPagination(!"false".equals(parameter));
	
	}

	private void setRows(String parameter) {
		if(StringUtils.isNotBlank(parameter))
		this.rows=(Integer.valueOf(parameter));
	
	}

	private void setPage(String parameter) {
		if(StringUtils.isNotBlank(parameter))
		this.page=(Integer.valueOf(parameter));
	}

	public Map<String, String[]> getParameterMap() {
		return parameterMap;
	}

	public void setParameterMap(Map<String, String[]> parameterMap) {
		this.parameterMap = parameterMap;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public PageBean() {
		super();
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		this.page = page;
	}

	public int getRows() {
		return rows;
	}

	public void setRows(int rows) {
		this.rows = rows;
	}

	public int getTotal() {
		return total;
	}

	public void setTotal(int total) {
		this.total = total;
	}

	public void setTotal(String total) {
		this.total = Integer.parseInt(total);
	}

	public boolean isPagination() {
		return pagination;
	}

	public void setPagination(boolean pagination) {
		this.pagination = pagination;
	}

	/**
	 * 获得起始记录的下标
	 * 
	 * @return
	 */
	public int getStartIndex() {
		return (this.page - 1) * this.rows;
	}

	@Override
	public String toString() {
		return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination + "]";
	}

	//上一页
		public int getPrevPage() {
			return this.page>1?this.page-1:this.page;
		}
	//下一页
		public int getNextPage() {
			return this.page < this.getMaxPage()? this.page+1:this.page;
		}
	//最大页
		public int getMaxPage() {
			return this.total % this.rows == 0 ? this.total/this.rows : (this.total/this.rows)+1;
		}
}

3、界面展示

主界面展示如下:
在这里插入图片描述
注:界面可以自己通过样式去进行调整哦,包括字体颜色、表格宽度等。
下面是我的一个jar包展示和列表展示:
在这里插入图片描述
在这里插入图片描述

四、总结

然后自定义mvc的增删改查就可以实现了,此后可以更深入去了解这方面的学习。继续加油吧。
我是南橙,一个逐渐秃头的橙子Orange。
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页
评论

打赏作者

Orange_南橙

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值