自定义mvc

9 篇文章 0 订阅

自定义mvc

前言:当我们写一个项目时,最重要的就是思路清晰,逻辑清楚,只有当我们
很清楚的知道自己要做什么样的项目,要把项目做成什么,应该有什么功能时,
我们就算完成了一半,另一半就是写代码了,虽然写代码的过程中可能会出现bug
不要慌,仔细的去寻找问题的所在。最后一个小小的项目功能就实现了

1. 分析其他的增删改查与自定义mvc的增删查改
2. 自定义mvc增删改查的操作步骤

分析增删改查的方案

方案一
servlet方案,代码和类过多,重复性也很多,不易修改

在这里插入图片描述
方案二
1.把所有的增删改查归为一个类,看似减少了很多类和代码,但是它的判
断条件过多,代码过于繁杂
2.前端jsp传递给后端的代码量过大
3.每个方法都要的写跳转界面

@WebServlet(name="bookServlet",urlPatterns="/bookServlet")
public class BookServlet extends extends HttpServlet{

	private static final long serialVersionUID = -8000602503008331264L;
	private BookDao bookDao = new BookDao();
	private Book book = new Book();
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String methodName = req.getParameter("methodName");
		if("list".equals(methodName)) {
			list(req, resp);
		}else if("add".equals(methodName)) {
			add(req, resp);
		}else if("toEdit".equals(methodName)) {
			toEdit(req, resp);
		}else if("edit".equals(methodName)) {
			edit(req, resp);
		}else if("del".equals(methodName)) {
			del(req, resp);
		}
	}
	
	private String del(HttpServletRequest req, HttpServletResponse resp) {
		
	}

	private String edit(HttpServletRequest req, HttpServletResponse resp) {
		
	}

	private String toEdit(HttpServletRequest req, HttpServletResponse resp) {

	}
	
	private String toAdd(HttpServletRequest req, HttpServletResponse resp) {
		
	}

	private String add(HttpServletRequest req, HttpServletResponse resp) {
		
		Book book = new Book();
		book.setBid(Integer.valueOf(req.getParameter("bid")));
		book.setBname(req.getParameter("bname"));
		book.setPrice(Float.valueOf(req.getParameter("price")));
		bookDao.add(book);
		return "toList";
	}

	private String list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		Book book = new Book();
		book.setBname(req.getParameter("bname"));
		PageBean pageBean = new PageBean();
		pageBean.setRequest(req);
		try {
			List<Book> list = this.bookDao.list(book, pageBean);
			req.setAttribute("bookList", list);
			req.setAttribute("pageBean", pageBean);
			req.getRequestDispatcher("/bookList.jsp").forward(req, resp);
		} catch (InstantiationException | IllegalAccessException | SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "list";
	}

	@Override
	public Book getModel() {
		return book;
	}
}

方案三
用自定义mvc(用反射调用方法,用xml建模统一配置,用反射写属性)
1.通过字符串截取名字
2.通过xml建模拿到全路径名称
3.再实例化
4.动态封装参数
5.动态调用方法
6.处理结果码

@WebServlet(name="dispatcherServlet",urlPatterns="*.action")
public class DispatcherServlet extends HttpServlet{


	private static final long serialVersionUID = 1L;

	private ConfingModel confingModel;
	
	@Override
	public void init() throws ServletException {
		// TODO Auto-generated method stub
		try {
			confingModel=ConfigModelFactory.build();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String uri=req.getRequestURI();
		String path = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
		ActionModel actionModel=confingModel.pop(path);
		if(actionModel==null) {
			throw new RuntimeException(path+" action标签没有被配置");
		}
		//实例化处理网络URL的类
		try {
			//action相当于BokkAction
			Action action=(Action) Class.forName(actionModel.getType()).newInstance();
			//动态封装参数
			if(action instanceof ModelDriver) {
				ModelDriver md=(ModelDriver)action;
				//将前端jsp参数传递到后端的所有封装到业务模型类中
				BeanUtils.populate(md.getmodel(), req.getParameterMap());
			}
			
			//动态调用方法
			String code = action.execute(req, resp);
			 ForwardModel forwardModel = actionModel.pop(code);
			 String jsppath = forwardModel.getPath();
			 if(forwardModel.isRedirect()) {
				 resp.sendRedirect(req.getServletContext()+jsppath);
			 }else {
				 req.getRequestDispatcher(jsppath).forward(req, resp);
			 }
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		}
	}
	
}

自定义mvc增删改查的操作步骤

一、需要一个数据库

在这里插入图片描述

二、导入jar包

在这里插入图片描述

三、copy工具类

在这里插入图片描述
因为使用反射的原因,我写了一个通用的类BaseDao

public class BaseDao<T> {
	
	public List<T> executeQuery(String sql,Class cls,PageBean pageBean)throws SQLException, InstantiationException, IllegalAccessException{
		List<T> list =new ArrayList<>();
		Connection con=DBAccess.getConnection();
		PreparedStatement ps=null;
		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()) {
			//实例化一个对象
			//给一个空对象的每一个属性赋值
			//将赋值完的对象添加到list集合中返回
			T t=(T) cls.newInstance();
			for (Field f : cls.getDeclaredFields()) {
				f.setAccessible(true);
				f.set(t, rs.getObject(f.getName()));
			}
			list.add(t);
		}
		DBAccess.close(con, ps, rs);
		return list;
	}

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

	private String getCountSql(String sql) {
		// TODO Auto-generated method stub
		return "select count(1) form ("+sql+") t";
	}
	
	public int executeUpdate(String sql,T t,String[] attrs)throws SQLException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		Connection con=DBAccess.getConnection();
		PreparedStatement ps=con.prepareStatement(sql);
		int loop=1;
		Field f=null;
		for (String attr : attrs) {
			f=t.getClass().getDeclaredField(attr);
			f.setAccessible(true);
			ps.setObject(loop++, f.get(t));			
		}
		int code=ps.executeUpdate();
		DBAccess.close(con, ps, null);
		return code;
	}
	

}
四、写实体类和dao类

因为写了一个BaseD到的通用,所以dao类中只需要写sql语句

public class SolrDao extends BaseDao<Solr>{

	/**
	 * 查询
	 */
	public List<Solr> list(Solr solr,PageBean pageBean) throws InstantiationException, IllegalAccessException, SQLException{
		String sql="select *from t_solr_job where true";
		String company=solr.getCompany();
		if(StringUtils.isNotBlank(company)) {
			sql+=" and company like '%"+company+"%'";
		}
		String sid=solr.getSid();
		if(StringUtils.isNotBlank(sid)) {
			sql+=" and sid='"+sid+"'";
		}
		return super.executeQuery(sql, Solr.class, pageBean);
	}
	/**
	 * 增加
	 */
	public int Add(Solr solr) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, SQLException {
		//如果后台没有传递的id
		solr.setSid(UUID.randomUUID().toString());
		String sql="insert into t_solr_job values(?,?,?,?,?,?,?)";
		return super.executeUpdate(sql, solr, new String[] {"sid","job","company","address","salary","limitd","time"});
	}
	/**
	 * 修改
	 */
	public int Edit(Solr solr) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, SQLException {
		String sql="update t_solr_job set job=? company=?,address=?,salary=?,limitd=?,time=? where sid=?";
		return super.executeUpdate(sql, solr, new String[] {"job","company","address","salary","limitd","time","sid"});
	}
	/**
	 * 删除
	 */
	public int Del(Solr solr) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, SQLException {
		String sql="delete from t_solr_job where sid=?";
		return super.executeUpdate(sql, solr, new String[] {"sid"});
	}
}
五、framework包

在framework包中的类只要写个一次,下次依然可以使用,基本不需要变动什么

六、前端代码和web包中SolrAction

这个类是用来跳转界面和调用增删改查的方法的,这是一个代码最少的类,一行代码就可以解决,然后直接抛异常就好

public class SolrAction extends ActionSupport implements ModelDriven<Solr> {

	private SolrDao sd = new SolrDao();
	private Solr s = new Solr();

	@Override
	public Solr getModel() {
		// TODO Auto-generated method stub
		return s;
	}

	// 查询
	public String list(HttpServletRequest req, HttpServletResponse resp) {
		PageBean pageBean=new PageBean();
		pageBean.setRequest(req);
		try {
			//默认查出第一页
			List<Solr> list = sd.list(s, pageBean);
			req.setAttribute("s", list);
			//分页中使用
			req.setAttribute("pageBean", pageBean);
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "list";

	}

	// 跳转增加
	public String toAdd(HttpServletRequest req, HttpServletResponse resp) {
		return "toAdd";

	}

	// 增加
	public String Add(HttpServletRequest req, HttpServletResponse resp) {
		try {
			this.sd.Add(s);
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "toList";

	}

	// 跳转修改
	public String toEdit(HttpServletRequest req, HttpServletResponse resp) {
		try {
			Solr solr = this.sd.list(s, null).get(0);
			req.setAttribute("solr", solr);
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "toEdit";

	}

	// 修改
	public String Edit(HttpServletRequest req, HttpServletResponse resp) {
		try {
			this.sd.Edit(s);
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "toList";

	}

	// 删除
	public String Del(HttpServletRequest req, HttpServletResponse resp) {
		try {
			this.sd.Del(s);
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "toList";

	}
}

注:跳转路径

href="/solr.jsp"相对路径,相对的是tomcat工作根目录 
href="solr.jsp"	相对于请求
href="${pageContext.request.contextPath }/solr.jsp 带上项目名的绝对路径
href="${pageContext.request.contextPath }/solr.action?methodName=toAdd" 通过后台转发到前台的jsp页面

七、最后呈现出来的结果

在这里插入图片描述
总结:当自己没有思路,或者思路不清晰的时候,就算你看着别人的代码敲,也一样会报错,但是如果你思路清晰,就算报错
你也会比别人更加容易找到错误的所在

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值