自定义MVC(增删改查)

                                                                文章目录

1️⃣怎么将框架打成jar包,导入新工程

2️⃣编写实体类Dao层

BookDao层源码

使用JUnit测试一下

(JUnit测试结果)

1)通用增删改

 BookDao

 BaseDao源码

 测试通用增加

 2)BookAction(表单重复提交问题)

BookAction源码

配置xml

 3)新增&修改

 3️⃣总结

1)搭建环境  

2)dao的编写通过BaseDao的简化,减少代码量 

3)我们的web层相对以前的变化       4)       5)


1️⃣怎么将框架打成jar包,导入新工程

🤦‍♀️在打成jar包之前记得看看该框架Debug中是否还有断点

 1️⃣你得有一个该工程所需的框架

2️⃣

3️⃣ 

 基于自定义的框架开发,首先要配置框架环境 a.将所需的jar包依赖导入项目工程                                                                       

 b.构建框架配置环境     

 2️⃣编写实体类Dao层

以书籍表为例:

 BookDao层源码:

package com.hemingxiang.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.hemingxiang.entity.Book;
import com.hemingxiang.util.BaseDao;
import com.hemingxiang.util.DBAccess;
import com.hemingxiang.util.PageBean;
import com.hemingxiang.util.StringUtils;

public class BookDao extends BaseDao<Book>{

	//查询功能
	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+"%'";
		}
		int bid=book.getBid();
		//前台jsp传递到后台,只要传了就有值,没有传就是默认值,默认值为0
		if(bid != 0) {
			sql += " and bid = " + bid;
		}
		return super.executeQuery(sql, pageBean, rs -> {
			List<Book> list=new ArrayList<>();
			//处理rs中的结果集
			try {
				while(rs.next()) {
					list.add(new Book(rs.getInt("bid"), rs.getString("bname"), rs.getFloat("price")));
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			return list;
		});
	}
	
	//增加
	public int add(Book book) throws Exception {
		Connection con = DBAccess.getConnection();
		String sql="insert into t_mvc_book values(?,?,?)";
		PreparedStatement ps = con.prepareStatement(sql);
		ps.setObject(1, book.getBid());
		ps.setObject(2, book.getBname());
		ps.setObject(3, book.getPrice());
		return ps.executeUpdate();
	}
	
	//删除
	public int del(Book book) throws Exception {
		Connection con = DBAccess.getConnection();
		String sql="delete from t_mvc_book where bid = ?";
		PreparedStatement ps = con.prepareStatement(sql);
		ps.setObject(1, book.getBid());
		return ps.executeUpdate();
	}
	
	//修改
	public int edit(Book book) throws Exception {
		Connection con = DBAccess.getConnection();
		String sql="update t_mvc_book set bname=?,price=? where bid = ?";
		PreparedStatement ps = con.prepareStatement(sql);
		ps.setObject(1, book.getBname());
		ps.setObject(2, book.getPrice());
		ps.setObject(3, book.getBid());
		return ps.executeUpdate();
	}
}

使用JUnit测试一下:

(JUnit测试结果)

1)通用增删改

BookDao

 BaseDao源码:

package com.hemingxiang.util;

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

import com.hemingxiang.entity.Book;

/**
 * 将来我们不知道要具体查什么,就用泛型来代替
 * T代表的是实体类
 * @author Administrator
 *
 * @param <T>
 */
public class BaseDao<T> {

	//版本1
	/*public List<T> executeQuery(String sql,PageBean pageBean,CallBack<T> callback) throws Exception{
		*//**
		 * 1.拿到数据库连接
		 * 2.拿到Preparestatement
		 * 3.执行SQL语句
		 *//*
		//连接对象
		Connection con = DBAccess.getConnection();//重复代码1
		
		//拿到域定义对象
		PreparedStatement pst = con.prepareStatement(sql);//重复代码2
		ResultSet rs = pst.executeQuery();//重复代码3
		//将结果集进行遍历
//		while(rs.next()) {
//			list.add(new Book(rs.getInt("bid"), rs.getString("bname"), rs.getFloat("price")));
//		}
		*//**
		 * 查询不同的表,必然要处理不同的结果集
		 * 接口是调用方来实现
		 *//*
		return callback.foreach(rs);
		
	}*/
	
	//版本2
	public List<T> executeQuery(String sql,PageBean pageBean,CallBack<T> callback) throws Exception{
		//BookDao的sql=select * from t_mvc_book where bname like '%圣墟%';
		//从这条sql语句中得到select count(1) as n from (select * from t_mvc_book where bname like '%圣墟%') t;
		//目的为了得到总记录数--》得到总分页
		//select * from t_mvc_book where bname like '%圣墟%' limit 10,10;
		/**
		 * 1.拿到数据库连接
		 * 2.拿到Preparestatement
		 * 3.执行SQL语句
		 */
		//连接对象
		Connection con = null;//重复代码1
		//拿到域定义对象
		PreparedStatement pst = null;//重复代码2
		ResultSet rs = null;//重复代码3
		//pageBean不等于空就分页
		if(pageBean!=null&&pageBean.isPagination()) {
			//拼接,拿到原始SQL
			String countSQL=getCountSQL(sql);
			con = DBAccess.getConnection();
			pst = con.prepareStatement(countSQL);
			rs = pst.executeQuery();
			if(rs.next()) {
				//把符合条件的总记录放进pageBean,当前实体类就包含了总记录数
				pageBean.setTotal(rs.getString("n"));
			}
			String pageSQL=getPageSQL(sql,pageBean);
			con = DBAccess.getConnection();
			pst = con.prepareStatement(pageSQL);
			rs = pst.executeQuery();
		}
		else {//不分页就sql
			con = DBAccess.getConnection();
			pst = con.prepareStatement(sql);
			rs = pst.executeQuery();
		}
		return callback.foreach(rs);
		
	}
	/**
	 * 拼装第N页的数据的SQL
	 * @param sql
	 * @param pageBean
	 * @return
	 */
	private String getPageSQL(String sql, PageBean pageBean) {
		return sql + " limit " + pageBean.getStartIndex() + "," + pageBean.getRows();
	}
	
	/**
	 * 拼装符合条件总记录数的SQL
	 * 拼接,拿到原始SQL
	 * @param sql
	 * @return
	 */
	private String getCountSQL(String sql) {
		return "select count(1) as n from ("+sql+") t";
	}
	
	//通用增删改
	public int executeUpdate(String sql, T t, String[] attrs) throws Exception {
		Connection con = DBAccess.getConnection();
		PreparedStatement ps = con.prepareStatement(sql);
		//将t中的某一个属性对应的值加到ps中
		//attrs遍历
		for (int i = 0; i < attrs.length; i++) {
			Field f = t.getClass().getDeclaredField(attrs[i]);
			f.setAccessible(true);
			ps.setObject(i+1, f.get(t));
		}
		return ps.executeUpdate();
	}	
}

测试通用增加

 2)BookAction(表单重复提交问题)

BookAction源码:

package com.hemingxiang.web;

import java.util.List;

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

import com.hemingxiang.dao.BookDao;
import com.hemingxiang.entity.Book;
import com.hemingxiang.framework.ActionSupport;
import com.hemingxiang.framework.ModelDriven;
import com.hemingxiang.util.PageBean;

public class BookAction extends ActionSupport implements ModelDriven<Book>{

	private Book book=new Book();
	private BookDao bookdao=new BookDao();
	
	@Override
	public Book getModel() {
		return book;
	}
	
	//增加
	public String add(HttpServletRequest req, HttpServletResponse resp) {
		try {
			bookdao.add(book);
		} catch (Exception e) {
			e.printStackTrace();
		}
		//"toList"代表跳到查询界面
		return "toList";
	}
	
	//删除
	public String del(HttpServletRequest req, HttpServletResponse resp) {
		try {
			bookdao.del(book);
		} catch (Exception e) {
			e.printStackTrace();
		}
		//删除成功 "toList"跳到查询界面
		return "toList";
	}
	
	//修改
	public String edit(HttpServletRequest req, HttpServletResponse resp) {
		try {
			bookdao.edit(book);
		} catch (Exception e) {
			e.printStackTrace();
		}
		//修改成功 "toList"跳到查询界面
		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("list", list);
			req.setAttribute("pageBean", pageBean);
		} catch (Exception e) {
			e.printStackTrace();
		}
		//执行查询展示
		return "list";
	}
	
	//跳转到增加或修改界面
	public String preEdit(HttpServletRequest req, HttpServletResponse resp) {
		try {
			int bid = book.getBid();
			//点击修改按钮bid有值(id绑值),点击新增bid不要绑值,所有判断如果bid不等于0就跳修改界面
			if(bid != 0) {
				//传了bid到后台,有且只能查一条数据,那就意味着list集合中只有一条数据
				List<Book> list = bookdao.list(book, null);
				req.setAttribute("b", list.get(0));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "toRdit";
	}
}

配置xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- config标签:可以包含0~N个action标签 -->
<config>

	<action path="/book" type="com.hemingxiang.web.BookAction">
		<forward name="list" path="/bookList.jsp" redirect="false" />
		<forward name="toEdit" path="/bookEdit.jsp" redirect="false" />
		<forward name="tolist" path="/book.action?methodName=list" redirect="true" />
	</action>
	
</config>

表单重复提交?

在开发中,点击新增的时候,如果用的是转发,地址栏不会变,但是有的人手不听话就喜欢反复点击刷新按钮,反复刷新表单就会重复提交  ⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇

(转发会将我的参数值携带过来,假说删除时用id来删它会将这个id再带过来,使用这个id删除某一个数据,此时的list集合是空的,页面上也没有数据显示,所以增删改必须用重定向)

增加或修改没有建立唯一约束的话使用转发会添加重复数据

3)新增&修改

新建一个新增和修改的共同的页码bookEdit.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="${pageContext.request.contextPath }/book.action?methodName=${empty b ? 'add' : 'edit'}" method="post">
		bid:<input type="text" name="bid" value="${b.bid }">
		bname:<input type="text" name="bname" value="${b.bname }">
		price:<input type="text" name="price" value="${b.price }">
		<input type="submit">
	</form>
 
</body>
</html>

注意理解⬇

${pageContext.request.contextPath }/book.action?methodName=${empty b ? 'add' : 'edit'} 

测试增加修改都是ok,但可能会出现中文乱码问题,在EncodingFiter中解决(过滤以action结尾的并重新启动一下,就不会出现乱码问题了)

 3️⃣总结

总结转载自敢敢130,原文点这里https://blog.csdn.net/weixin_67465673/article/details/125508940

 利用自定义mvc框架去开发我们的增删改查,包括以后这个开源框架去做增删改查步骤如下:

1)搭建环境  


1.搭建这个框架的环境,包括框架的jar包依赖,然后以及我们的文件配置web.xml的配置,以及框架本身的配置文件的添加,比如说:我们的mvc.xml、xiaokun.xml等等这就是我们的框架的配置文件

2)我们原来的这个dao的编写通过我们这个BaseDao的简化,能够减少我们的代码量了 


2.我们的增删改查是从我们的实体类开始的,接下来我们就要去建实体类,建完实体类之后,我们的这个dao层是经过了我们之前的BaseDao的优化,所以说导致我们的代码量就会去减少,就是我们的增删改由原来的多行代码变成了两行代码,如果说我们的查询按照我们的第二版本它就会进一步减少,就没有拿过回调函数

3)我们的web层相对以前的变化 


3.web层编码通过我们的中央控制器以及模型驱动接口,它把我们原来的参数封装,以及我们的底层的反射动态调用方法,我们以前的doget,dopost方法是不用写的,因为我们继承了子控制器然后配置了web.xml里面的中央控制器,所以说,会发现我们的子控制器相当于我们之前的servlet它的代码量也减少了,总之一行代码就OK了,搞定的原因是框架帮你做了这个事情。

4) 

4.相对于以前我们的servlet需要在web.xml中去配置或者说在上面去添加servlet注解,现在的话不需要了,但是呢我们添加了这个配置文件里面的子控制器的一个配置wuyanzu.xml

5)


5.那么我们的分页由原来的这个大量jsp代码变成了我们自定义标签去实现了,就是在我们的界面端也做了优化,对应的是我们之前的jsp标签,自定义jsp标签的内容

本次文章所用到的类与包

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值