Java初试MVC及三层架构学习笔记

最近又捡起了对Java的学习,通过对一个实例的介绍,总结下此次对Web开发中MVC三层架构的学习,以便用于日后的复习。

一、 MVC

简单的先介绍下MVC模式:

  • M(Model):JavaBean。用于完成具体的业务操作。

    JavaBeanJava中特殊的类.

    JavaBean满足条件:

    • public修饰的类,并提供public无参构造方法
    • 所有的属性都是private修饰
    • 提供gettersetter方法

    使用层面:

    • 封装业务逻辑:dao层封装对数据库的底层操作
    • 封装数据:domain层。对数据库中所要查询对象的封装
  • V(View):视图。用于数据的展示。

    • 页面的展示
    • 与用户的交互
  • C(Controller):控制器。由Servlet实现控制器。

    主要功能:

    • 获取用户的输入
    • 调用模型,将请求交给模型进行处理
    • 将数据交给视图进行展示
MVC模式

首先浏览器(通过View页面)向服务器端进行请求(可以是表单请求、超链接、AJAX请求等),Controller层获取浏览器请求的数据进行解析,调用模型;模型进行业务逻辑的操作,并将处理结果返回给Controller层;Controller层再将相应的数据交给View层,进行数据展示到客户端。

二、三层架构

三层架构:视图层View、服务层Service、与持久层Dao。

  • View:用于接收用户提交请求的代码。
  • Service:用于编写系统的业务逻辑。(最重要的一层)
  • Dao:对数据库进行最直接的操作。即:对数据库的增删改查。

三层架构

dao层中,定义了对数据库的增删改查的接口。而service层中即对数据的具体业务操作,用于组合dao层中的接口方法。web层中则用于对用户数据的接收和发送。上图很好的解释了MVC与三层架构之间的关系。

三、案例

通过servletjspMysqlJDBCTempleatDuirdBeanUtilsTomcat等技术完成用户信息列表展示的实例。此部分着重解释后端代码的实现。

1.查询所有用户信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2QtbEHOm-1600526471558)(https://s1.ax1x.com/2020/08/16/dEGRSJ.png)]

当点击前端页面查询按钮时,此时通过对服务器端的请求,到web层中的Controller层,触发FindUserServlet。由Controller调用Service层中的模型,继而Service层通过dao层获取全部的用户信息,封装到List<User>集合中。返回给Service层,再通过Service层将用户信息返回给Controller层。Web层中的Controller将数据进行存储转发给View,进行数据的解析展示,返回给客户端。

findAll方法:

dao层中findAll接口的实现
@Override
public List<User> findAll() {
   
    JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
    String sql = "select * from user";
    List<User> users = template.query(sql, new BeanPropertyRowMapper<User>(User.class));
    return users;
}
service层中findAll接口的实现
@Override
public List<User> findAll() {
   
    UserDao userDao = new UserDaoImpl();
    List<User> users = userDao.findAll();
    return users;
}
web层中UserListServlet
@WebServlet("/userListServlet")
public class UserListServlet extends HttpServlet {
   
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   
        UserService userService = new UserServiceImpl();
        List<User> users = userService.findAll();
        request.setAttribute("users", users);
        request.getRequestDispatcher("/list.jsp").forward(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   
        this.doPost(request,response);
    }
}
2.增加用户信息

在这里插入图片描述

当客户端点击提交按钮时,此次对服务器端的请求带着表单的数据。根据我们上面对三层架构以及Controller层的介绍可知,由其进行数据的接收。这里即为AddUserServlet对获取的数据进行处理、封装。将封装好的数据传给Service层(Model),即为UerService,进行业务逻辑的操作。再通过dao层对数据库进行相应的访问。

dao层中add接口的实现
@Override
public void addUser(User user) {
   
    JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
    String sql = "insert into user values(null,?,?,?,?,?,?,null,null)";
    template.update(sql, user.getName(), user.getGender(), user.getAge(), 									user.getAddress(), user.getQq(), user.getEmail());
}
Service层中add接口的实现
@Override
public void addUser(User user) {
   
    UserDao userDao = new UserDaoImpl();
    userDao.addUser(user);
    }
web层中addServlet的实现
@WebServlet("/addServlet")
public class AddServlet extends HttpServlet {
   
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   
        request.setCharacterEncoding("utf-8");
        User user = new User();
        Map<String, String[]> parameterMap = request.getParameterMap(); // 将请求参数进行Map集合的封装
        try {
   
            BeanUtils.populate(user, parameterMap);//将获取到的值封装到User对象中
        } catch (IllegalAccessException e) {
   
            e.printStackTrace();
        } catch (InvocationTargetException e) {
   
            e.printStackTrace();
        }
        UserService service = new UserServiceImpl();
        service.addUser(user);
        HttpSession session = request.getSession(); // 再进行重定向之前,将需要添加的User对象设置到session中,以便后续对其的获取使用
        session.setAttribute("addUser", user);
        response.sendRedirect(request.getContextPath() + "/findUserByPageServlet");//重定向至View层
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   
        this.doPost(request, response);
    }
}

思考:

在上一个方法查找所有的用户时,在最后,我们将获取到的数据传给view层,采用的是存储转发,而在这里,对用户的添加,我们却采用的是重定向(实际上,增、删、改都是采用的重定向)。这是为什么呢?

这里先对重定向和存储转发的几个特点进行简单的比较:

  • 存储转发:一种在服务器内部的资源跳转方式。

    特点:

    1. 浏览器地址栏不会发生变化
    2. 只能转发到当前服务器内部资源中
    3. 转发是一次请求

    最重要的一点便是转发只在当前服务器内部进行,请求也只有一次。这样做带来的一点用处便是,request域中带有的请求是可以在多次资源跳转中进行共享的。在使用时,只需要添加资源路径即可。

  • 重定向:具有多次的请求。其跳转在于客户端与服务器端之间,每次请求都是独立的,存在新的requestresponse

    特点:

    1. 重定向之后地址栏会发生变化
    2. 重定向可以访问其他站点(服务器)的资源
    3. 重定向是两次请求。故不能使用request域共享数据。

其中,重定向可避免在用户重新加载页面时,两次调用相同的动作。即,访问数据库时,增删改使用重定向。当前我的理解是:转发只有一次请求,故当重新加载页面时,会沿着之前的请求再请求一次(这句话可能比较绕),在页面进行展示全部用户数据之前,又会将数据库添加用户的操作进行一遍,所以会造成表单的重复提交;而重定向中是多次(两次)请求,所以只复用”最近一次“请求(因为每次请求是独立的,之前的请求都不在了),这里只是对页面进行全部用户的展示。

重定向:

存储转发:

存储转发

3.用户信息更改

在这里插入图片描述

思路:用户信息的更改相对前面的用户显示的展示和增加要多了一些步骤。首先,在我们需要对信息进行更改时,需要将原信息展示给我们,在原信息的基础上进行修改,即:是查询到所要修改的用户,将其信息进行回显。其次,当我们对用户信息更改完毕以后,通过对数据库的访问,将对应的数据库信息进行Update操作。最后,通过view层,对列表信息进行展示传送给客户端。这里,每个用户都有一个唯一标识符–id主键,所以当我们拿到主键id时,其实也就获得了对应的数据库中的User对象,后面的操作也就顺理成章了。

  1. FindUserServlet – 查询需要修改的用户,用于信息的回显
web层中FindUserServlet的实现
@WebServlet("/findUserServlet")
public class FindUserServlet extends HttpServlet {
   
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   
        request.setCharacterEncoding("utf-8");
        String id = request.getParameter("id"); // 获取id
        UserService service = new UserServiceImpl();
        User user = service.findUser(Integer.parseInt(id));// 通过id返回User对象
        request.setAttribute("user", user);// 查找操作所以存储-转发,将用户信息封装传至view层
        request.getRequestDispatcher("/update.jsp").forward(request,response);// 即传至update.jsp页面进行解析
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   
        this.doPost(request,response);
    }
}
service层中findUser的实现
@Override
public User findUser(int id) {
   
    UserDao userDao = new UserDaoImpl();
    User user = userDao.findUser(id);
    return user;
}
dao层中findUser接口的实现
@Override
public User findUser(int id) {
   
    JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
    String sql = "select * from user where id = ?";
    User user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), id);
    return user;
}

以上是获取到需要修改的对象,然后对用户信息进行一个回显操作。

下面,便是对用户信息进行修改。

  1. UpdateUserServlet – 修改用户信息,对数据库数据进行修改
web层中UpdateUserServlet的实现
@WebServlet("/updateUserServlet")
public class UpdateUserServlet extends HttpServlet {
   
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   
        request.setCharacterEncoding("utf-8");
        Map<String, String[]> parameterMap = request.getParameterMap();
        User user = new User();
        try {
   
            BeanUtils.populate(user, parameterMap);
        } catch (IllegalAccessException e) {
   
            e.printStackTrace(<
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值