自定义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页面
七、最后呈现出来的结果
总结:当自己没有思路,或者思路不清晰的时候,就算你看着别人的代码敲,也一样会报错,但是如果你思路清晰,就算报错
你也会比别人更加容易找到错误的所在