IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 自我解读MVC三层架构原理 -> 正文阅读

[开发测试]自我解读MVC三层架构原理

MVC简单原理

(1)在我们最开始学习编程,开始写代码的时候;往往写的代码较为的混乱,层次不清晰,从而造成了维护安全上的缺陷。这里就慢慢引出了框架的知识。能够是我们的代码变得层次清晰、分明,维护起来简单,使用安全。

(2)比较老的架构,适合新人学习的家口,便是我们的MVC三层架构。

(3)MVC(Model、View、Controller),

  • Model层:的包括范围比较广,包括了pojo(实体类层)和业务的处理层持久层(操作数据层);
  • View层:包括了类似于项目中的Jsp、Html页面进行数据展示层;
  • Controller层:接收用户的请求,交给业务层处理对应的代码,控制视图的跳转;

?例子解读:(登录校验例子)

?(1)前台页面(常见系统中的登录页面? 用户名,密码的输入,并校验)

<%@ page contentType="text/html;charset=UTF-8" pageEncoding="GBK" language="java" %>
<html>
<head>
    <title>超市订单系统</title>
    <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css">
</head>
<body class="login_bg">
<%--在body里面划分section(部分)--%>
<section class="loginBox">
    <%--头部标签--%>
    <header class="loginHeader">
        <h1>超市订单管理系统</h1>
    </header>
        <section class="loginCont">
            <%--form表单--%>
            <form class="loginForm" action="${pageContext.request.contextPath}/login.do"  name="actionForm" id="actionForm"  method="post" >
                <%--登录状态盒子--%>
                <div class="info">${error}</div>
                <%--输入用户名盒子--%>
                <div class="inputbox">
                    <label for="userCode">用户名:</label>
                    <input type="text" class="input-text" id="userCode" name="userCode" placeholder="请输入用户名" required/>
                </div>
                <%--输入密码盒子--%>
                <div class="inputbox">
                    <label for="userPassword">密码:</label>
                    <input type="password" id="userPassword" name="userPassword" placeholder="请输入密码" required/>
                </div>
                <%--登录重置盒子--%>
                <div class="subBtn">
                    <input type="submit" value="登录"/>
                    <input type="reset" value="重置"/>
                </div>
            </form>
        </section>
</section>

</body>
</html>

(2)控制层

当前台页面输入用户名和密码后,这时控制层开始工作,将获取过来的用户名和密码交个Servlet进行校验,校验就是Model层中的业务处理层和持久层进行工作了;

这里需要说明一下,控制层提交登录数据的具体过程:首先当我们按校验规则输入用户名和密码之后,点击提交按钮,通过form表单中的action中的路径,到了web.xml中,在web.xml中找到对应的过滤器,通过过滤器,执行对应的Servlet,在Servlet拿到输入的数据,并在数据库中进行查找,进行比对;

代码如下:

(1)首先是对应的web.xml中的login.do过滤器

<!--注册登陆请求的Servlet-->
    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>servlet.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/login.do</url-pattern>
    </servlet-mapping>

(2)到了对应的Servlet类:LoginServlet.class

/**
 * @author ZEShart
 * @create 2021-07-29-21:31
 */
/**
 * 处理登录的请求
 * 控制层去调业务层的代码
* */
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /**
         * 获取用户名和密码
         * */
        String userCode=req.getParameter("userCode");
        String userPassword=req.getParameter("userPassword");

        //resp.getWriter().println(userCode+"------------"+userPassword);

        //和数据库中的密码进对比,调用业务层
        UserService userService=new UserServiceImpl();


        //这里已经把登录的人给查出来了
        User user=userService.userLogin(userCode,userPassword);


        if (user!=null){//表示查有此人
            //将用户的信息放到Session中
            req.getSession().setAttribute(Constants.USER_SESSION,user);
            //重定向到主页
            resp.sendRedirect("jsp/frame.jsp");
        }else{//表示查无此人
            //转发回登录页面,并提示用户名或密码错误
            req.setAttribute("error","用户名或密码错误");
            req.getRequestDispatcher("login.jsp").forward(req, resp);
        }
    }
}

(3)在Servlet中获取数据并校验

在获取完数据之后,在校验时,Model层中业务处理层与持久层开始工作:

Dao层(数据持久层)

操作数据库的方法封装:BaseDao.class

/**
 * @author ZEShart
 * @create 2021-07-17-16:36
 */
/*
* 操作数据库的公共类
* 读取数据库配置文件,获取数据库基本信息
* */
public class BaseDao {
    private static String user;
    private static String password;
    private static String url;
    private static String driver;
    /*
    * 静态代码块,类加载的时候就初始化了
    * */
    static{
        Properties properties=new Properties();
        /*
        * 通过类加载器读取对应的资源,把一个资源变成流
        * */
        InputStream is=BaseDao.class.getClassLoader().getResourceAsStream("db.properties");
        try {
            properties.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        user=properties.getProperty("user");
        password=properties.getProperty("password");
        url=properties.getProperty("url");
        driver=properties.getProperty("driver");
    }

    /**
    * 获取数据库连接
    * */
    public static Connection getConnection(){
        Connection connection=null;
        try {
            Class.forName(driver);
            connection=DriverManager.getConnection(url,user,password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }
    /*
    * 编写公共查询类
    * */
    public static ResultSet execute(Connection connection, PreparedStatement pstm,ResultSet resultSet, String sql,Object[] params){
        //通过上面的连接数据库方法,连接数据库后得到statement对象
        try {
            //预编译的sql,在后面直接执行就可以了
            pstm=connection.prepareStatement(sql);
            //执行sql语句
            for (int i = 0; i < params.length; i++) {
                //setObject,占位符从1开始,但我们的数组是从0开始
                pstm.setObject(i+1,params[i]);
            }
            resultSet=pstm.executeQuery();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return  resultSet;
    }
    /*
    * 编写公共增删改公共类
    * */
    public static Integer execute(Connection connection, String sql,Object[] params, PreparedStatement pstm){
        //通过上面的连接数据库方法,连接数据库后得到statement对象
        int rows=0;
        try {
            pstm=connection.prepareStatement(sql);
            //执行sql语句
            for (int i = 0; i < params.length; i++) {
                //setObject,占位符从1开始,但我们的数组是从0开始
                pstm.setObject(i+1,params[i]);
            }
            rows=pstm.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  rows;
    }
    /*
    * 关闭资源
    * */
    public static boolean closeResource(Connection connection,PreparedStatement pstm,ResultSet resultSet){
        boolean flag=true;
        if (connection!=null){
            try {
                connection.close();
                //GC回收
                connection=null;
            } catch (SQLException e) {
                e.printStackTrace();
                flag=false;
            }
        }
        if (pstm!=null){
            try {
                pstm.close();
                //GC回收
                pstm=null;
            } catch (SQLException e) {
                e.printStackTrace();
                flag=false;
            }
        }
        if (resultSet!=null){
            try {
                resultSet.close();
                //GC回收
                connection=null;
            } catch (SQLException e) {
                e.printStackTrace();
                flag=false;
            }
        }
        return flag;
    }
}

Dao层中的接口(规定使用到的方法)

/**
* 接口就是一个规范
* */
public interface UserDao {
    //得到登录的用户,(通过用户名)
    public User getLoginUser(Connection connection, String userCode) throws SQLException;
}

实现接口中的方法:

public class UserDaoImpl implements UserDao {

    public User getLoginUser(Connection conn, String userCode) throws SQLException {
        PreparedStatement pstm=null;
        ResultSet rs=null;
        User user=null;
        /**
         * 调用BaseDao类里面的公共查询方法
        * */
        if(conn!=null){
            String sql="select * from smbms_user where userCode=?";
            Object[] params={userCode};
                rs=BaseDao.execute(conn,pstm,rs,sql,params);
                if (rs.next()){
                    user=new User();
                    user.setId(rs.getInt("id"));
                    user.setUserCode(rs.getString("userCode"));
                    user.setUserName(rs.getString("userName"));
                    user.setUserPassword(rs.getString("userPassword"));
                    user.setUserSex(rs.getInt("userSex"));
                    user.setUserBirth(rs.getDate("userBirth"));
                    user.setUserPhone(rs.getString("userPhone"));
                    user.setUserAddress(rs.getString("userAddress"));
                    user.setUserRole(rs.getInt("userRole"));
                    user.setCreateBy(rs.getInt("createBy"));
                    user.setCreateDate(rs.getTimestamp("createDate"));
                    user.setModifyBy(rs.getInt("modifyBy"));
                    user.setModifyDate(rs.getTimestamp("modifyDate"));
                }
                /**
                 * 遍历完成之后,要进行资源的关闭,这里我们一般不关闭connection,因为里面还有业务
                * */
                BaseDao.closeResource(null,pstm,rs);
        }
        return user;
    }
}

(4)为了项目的安全性

一般我们不直接通过前端直接连接dao层,让dao层来处理前端的数据,这样会造成系统的不安全,所以我们在前端和dao层之间家里了一层Service层。

service层接口:

/**
 * 业务层
* */
public interface UserService {

    /**
     * 作者:李东升
     * 功能:用户登录
    * */
    public User userLogin(String userCode, String password);

}

实现service接口:

**
 * @author ZEShart
 * @create 2021-07-29-21:00
 */
public class UserServiceImpl implements UserService {
    /**
     * 业务层都会调用dao层,所以我们要引入Dao层
     * 在学习微服务的时候,我们可以直接通过注解实现引入,这里得通过构造方法引入
    * */
    private UserDao userDao;
    public UserServiceImpl(){
        userDao= new UserDaoImpl();
    }
    public User userLogin(String userCode, String password) {
        Connection connection;
        User user=null;
        connection= BaseDao.getConnection();
        //通过业务层调用对应的具体的数据库操作
        try {
            user=userDao.getLoginUser(connection,userCode);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            BaseDao.closeResource(connection,null,null);
        }
        return user;
    }
}

综上,就是我自己简单理解的MVC三层架构(随笔记)

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-08-17 15:41:40  更:2021-08-17 15:43:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/28 0:05:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码