自定义MVC架构【下】(一)

简介: 自定义MVC架构【下】

一、前言

在上篇中,我们已经优化了子控制器初始化、跳转页面的代码冗余以及请求参数进行实体封装的三大问题,目前我们的自定义MVC已经可以满足绝大部分需求了,下面我来带领大家使用我们的自定义MVC架包以及CRUD操作的优化。

(以下的所有代码我都会上传CSDN欢迎下载或者翻阅前两篇博客也可以)

二、导出自定义MVC架包

首先,使用之前,我们必须先将我们所写的自定义MVC导出jar文件才行。

第一步:找到有关自定义MVC的包

我们的framework与model包

第二步:右击Export导出

第三步:选择JAR file文件

第四步:选择自己需要存放的位置进行保存一键Finish即可

这样我们所写的自定义MVC架包就做好啦!!

三、使用自定义MVC架包

①建立一个web项目,将所需要的架包导入(特别是我们自己所写的架包)

②建立工具包(utils)将所需的文件导入

注意:这里最好测试一下我们的数据库帮助类(DBAccess),是否连接数据库成功

③导入我们的mvc.xml子控制配置文件

最好新建一个Source Folder资源包进行保存

<?xml version="1.0" encoding="UTF-8"?>
<config>
  <action path="/book" type="com.zking.web.BookAction">
    <forward name="list" path="/bookList.jsp" redirect="false" />
    <forward name="toList" path="/book.action?methodName=list"
      redirect="true" />
    <forward name="toEdit" path="/bookEdit.jsp" redirect="false" />
  </action>
</config>

这里的xml配置文件与自定义MVC架构【中】的有所不同,因为增删改查操作需要有三种情况,第一种查询界面、第二种修改初始化数据界面、第三种增删改操作执行过后调用list方法先同步数据再进行回显。

④web.xml文件手动配置中央控制器(DispatchServlet)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>xmymvc_crud</display-name>
  <servlet>
    <servlet-name>mvc</servlet-name>
    <servlet-class>com.zking.framework.DispatchServlet</servlet-class>
    <init-param>
      <param-name>configurationLocation</param-name>
      <param-value>/mvc.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>mvc</servlet-name>
    <url-pattern>*.action</url-pattern>
  </servlet-mapping>
</web-app>

温馨提示:

因为以前我们是在中央控制器(DispatchServlet)进行注解的方式进行拦截servlet请求的操作并完成初始化配置,但是现在中央控制器(DispatchServlet)是架包里面的东西了所以需要手动配置需要解析的xml文件(/mvc.xml)。

四、优化增删改查Dao层及Servlet

1.优化增删改查Dao层

创建数据库实体以及dao包

实体类

package com.zking.entity;
public class Book {
  private int bid;
  private String bname;
  private float price;
  public int getBid() {
    return bid;
  }
  public void setBid(int bid) {
    this.bid = bid;
  }
  public String getBname() {
    return bname;
  }
  public void setBname(String bname) {
    this.bname = bname;
  }
  public float getPrice() {
    return price;
  }
  public void setPrice(float price) {
    this.price = price;
  }
  @Override
  public String toString() {
    return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + "]";
  }
}

这里我们就可以优化我们的Dao层代码了,将增删改融为一个代码。

       增删改查的通用套路
       1.建立链接
       2.预定义对象PreparedStatement
       3.设置占位符的?的值
       4.pst.executeUpdate();

所以我们可以将重复的代码和思维进行优化

BaseDao(通用的增删改查)

package com.zking.util;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import com.zking.entity.Book;
import com.zking.util.DBAccess;
import com.zking.util.PageBean;
import com.zking.util.StringUtils;
/**
 * 所有Dao层的父类
 *  BookDao
 *  UserDao
 *  OrderDao
 *  ...
 * @author Administrator
 *
 * @param <T>
 */
public class BaseDao<T> {
  /**
   * 通用的增删改方法
   * @param book
   * @throws Exception
   */
  public void executeUpdate(String sql, T t, String[] attrs) throws Exception {
    Connection con = DBAccess.getConnection();
    PreparedStatement pst = con.prepareStatement(sql);
    /*
     * 思路:
     *  1.从传进来的t中读取属性值
     *  2.往预定义对象中设置了值
     */
    for (int i = 0; i < attrs.length; i++) {
      Field f = t.getClass().getDeclaredField(attrs[i]);
      f.setAccessible(true);
      pst.setObject(i+1, f.get(t));
    }
    pst.executeUpdate();
  }
  /**
   * 通用分页查询
   * @param sql
   * @param clz
   * @return
   * @throws Exception
   */
  public List<T> executeQuery(String sql,Class<T> clz,PageBean pageBean) throws Exception{
    List<T> list = new ArrayList<T>();
    Connection con = DBAccess.getConnection();;
    PreparedStatement pst = null;
    ResultSet rs = null;
    if(pageBean != null && pageBean.isPagination()) {
      String countSQL = getCountSQL(sql);
      pst = con.prepareStatement(countSQL);
      rs = pst.executeQuery();
      if(rs.next()) {
        pageBean.setTotal(String.valueOf(rs.getObject(1)));
      }
      String pageSQL = getPageSQL(sql,pageBean);
      pst = con.prepareStatement(pageSQL);
      rs = pst.executeQuery();
    }else {
      pst = con.prepareStatement(sql);
      rs = pst.executeQuery();
    }
    while (rs.next()) {
      T t = clz.newInstance();
      Field[] fields = clz.getDeclaredFields();
      for (Field f : fields) {
        f.setAccessible(true);
        f.set(t, rs.getObject(f.getName()));
      }
      list.add(t);
    }
    return list;
  }
  /**
   * 将原生SQL转换成符合条件的总记录数countSQL
   * @param sql
   * @return
   */
  private String getCountSQL(String sql) {
    return "select count(1) from ("+sql+") t";
  }
  /**
   * 将原生SQL转换成pageSQL
   * @param sql
   * @param pageBean
   * @return
   */
  private String getPageSQL(String sql,PageBean pageBean) {
    return sql + " limit "+ pageBean.getStartIndex() +","+pageBean.getRows();
  }
}

BookDao继承BaseDao

package com.zking.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import com.zking.entity.Book;
import com.zking.util.BaseDao;
import com.zking.util.DBAccess;
import com.zking.util.PageBean;
import com.zking.util.StringUtils;
public class BookDao extends BaseDao<Book>{
  public void add(Book book) throws Exception {
    String sql = "insert into t_mvc_book values(?,?,?)";
    super.executeUpdate(sql, book, new String[] {"bid","bname","price"});
  }
  public void edit(Book book) throws Exception {
    String sql = "update t_mvc_book set bname = ?, price = ? where bid = ?";
    super.executeUpdate(sql, book, new String[] {"bname","price","bid"});
  }
  public void delete(Book book) throws Exception {
    String sql = "delete from t_mvc_book where bid = ?";
    super.executeUpdate(sql, book, new String[] {"bid"});
  }
  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+"%'";
    }
    return super.executeQuery(sql, Book.class, pageBean);
  }
}


相关文章
|
1月前
|
存储 前端开发 调度
Flux 与传统的 MVC 架构模式区别
Flux是一种用于构建用户界面的架构模式,与传统的MVC架构不同,它采用单向数据流,通过Dispatcher统一管理数据的分发,Store负责存储数据和业务逻辑,View只负责展示数据,使得应用状态更加可预测和易于维护。
|
4月前
|
设计模式 前端开发 数据库
哇塞!Rails 的 MVC 架构也太牛了吧!快来看看这令人惊叹的编程魔法,开启新世界大门!
【8月更文挑战第31天】《Rails中的MVC架构解析》介绍了Ruby on Rails框架核心的MVC设计模式,通过模型(Model)、视图(View)和控制器(Controller)三部分分离应用逻辑,利用Active Record进行数据库操作,ERB模板渲染视图,以及控制器处理用户请求与业务逻辑,使代码更易维护和扩展,提升团队开发效率。
81 0
|
1月前
|
存储 前端开发 数据可视化
在实际项目中,如何选择使用 Flux 架构或传统的 MVC 架构
在实际项目中选择使用Flux架构或传统MVC架构时,需考虑项目复杂度、团队熟悉度和性能需求。Flux适合大型、高并发应用,MVC则适用于中小型、逻辑简单的项目。
|
2月前
|
前端开发 Java 数据库
springBoot:template engine&自定义一个mvc&后端给前端传数据&增删改查 (三)
本文介绍了如何自定义一个 MVC 框架,包括后端向前端传递数据、前后端代理配置、实现增删改查功能以及分页查询。详细展示了代码示例,从配置文件到控制器、服务层和数据访问层的实现,帮助开发者快速理解和应用。
|
3月前
|
设计模式 前端开发 数据库
理解mvc架构
mvc架构
33 4
|
4月前
|
设计模式 存储 前端开发
MVC革命:如何用一个设计模式重塑你的应用架构,让代码重构变得戏剧性地简单!
【8月更文挑战第22天】自定义MVC(Model-View-Controller)设计模式将应用分为模型、视图和控制器三个核心组件,实现关注点分离,提升代码可维护性和扩展性。模型管理数据和业务逻辑,视图负责数据显示与用户交互,控制器处理用户输入并协调模型与视图。通过示例代码展示了基本的MVC框架实现,可根据需求扩展定制。MVC模式灵活性强,支持单元测试与多人协作,但需注意避免控制器过度复杂化。
47 1
|
4月前
|
开发者 前端开发 Java
架构模式的诗与远方:如何在MVC的田野上,用Struts 2编织Web开发的新篇章
【8月更文挑战第31天】架构模式是软件开发的核心概念,MVC(Model-View-Controller)通过清晰的分层和职责分离,成为广泛采用的模式。随着业务需求的复杂化,Struts 2框架应运而生,继承MVC优点并引入更多功能。本文探讨从MVC到Struts 2的演进,强调架构模式的重要性。MVC将应用程序分为模型、视图和控制器三部分,提高模块化和可维护性。
49 0
|
4月前
|
存储 前端开发 数据库
神秘编程世界惊现强大架构!Web2py 的 MVC 究竟隐藏着怎样的神奇魔力?带你探索实际应用之谜!
【8月更文挑战第31天】在现代 Web 开发中,MVC(Model-View-Controller)架构被广泛应用,将应用程序分为模型、视图和控制器三个部分,有助于提高代码的可维护性、可扩展性和可测试性。Web2py 是一个采用 MVC 架构的 Python Web 框架,其中模型处理数据和业务逻辑,视图负责呈现数据给用户,控制器则协调模型和视图之间的交互。
41 0
|
5月前
|
存储 前端开发 算法
MVC(Model-View-Controller)架构
MVC架构帮助开发者构建清晰、可维护和可扩展的Web应用程序。
42 2
|
4月前
|
中间件 API 网络架构
Django后端架构开发:从匿名用户API节流到REST自定义认证
Django后端架构开发:从匿名用户API节流到REST自定义认证
46 0