文章目录
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标签的内容
本次文章所用到的类与包