JAVA中的MVC三层架构

JAVA中的MVC三层架构

MVC架构概述

MVC(Model-View-Controller)是一种软件设计模式,用于将应用程序分为主要的部分:模型(Model)、视图(View)和控制器(Controller)。这种架构有助于提高代码的可维护性和可扩展性。

模型(Model)
  • 定义:模型层负责数据的处理与存储,包括业务逻辑层的实现

  • 作用:处理数据,如数据库查询、数据验证等

  • 示例:在Java中,模型通常是由POJO(Plain Old Java Object)类和DAO(Data Access Object)类组成。

视图(View)
  • 定义:视图层负责展示数据给用户,是用户界面的部分。

  • 作用:接收用户的输入,并显示从模型层获取的数据。

  • 示例:在web应用中,视图可以是JSP页面、HTML页面或Thymeleaf模板。

控制器(Controller)
  • 定义:视图层负责展示数据给用户,是用户界面的部分。

  • 作用:接收用户的输入,并显示从模型层获取数据

  • 示例:在Spring框架中,控制器通常是带有@Controller注解的类。

MVC的优势:
  • 分离关注点:将业务逻辑、数据访问和用户界面分离,使得每个部分可以独立开发和测试。

  • 提高可维护性:代码结构清晰,易于理解和维护

  • 提高可扩展性:可以轻松地添加新的功能或修改现有功能,而不会影响其他部分。

MVC在Java Web应用中的实现
  • 常用框架:SpringMVC、Struts2

  • 工作流程:

    1. 用户通过浏览器发送请求到服务器。

    2. 前端控制器(DispatcherServlet)接收到请求,根据请求信息调用相应的处理器映射器(HandlerMapping)。

    3. 处理器映射器找到对应的处理器(Controller)。

    4. 控制器调用模型层进行业务处理。

    5. 模型层处理完业务后返回数据给控制器。

    6. 控制器选择合适的视图进行渲染,并将数据传递给视图。

    7. 视图生成最终的HTML页面,返回给前端控制器。

    8. 前端控制器将响应返回给用户。

Spring中的MVC三层架构

三层指的是Web层(界面层)、Service层(业务逻辑层)、Dao层(数据持久层)

  1. Web层,界面层(例如:餐厅中的服务员

    只负责与前端进行交互,处理用户的请求,并将结果返回给用户。至于业务逻辑如何处理,Web层不关心。Servlet/Controller可以充当。

  2. Service层,业务逻辑层 (例如:厨师)

    只负责处理核心的业务逻辑,至于是谁发的请求,Service层不关心。它与Web层和Dao层进行交互,但不直接与前端或数据库交互。是系统架构中最重要的一层,Service层的设计是否灵活,通用,就决定了整个系统将来的可扩展性和组件事务可替换性。

  3. Dao层(Data Access Object)层,数据持久层 (例如:采购员)

    负责和数据库进行交互,提供数据的增删改查操作,不关心具体的业务功能,专注于数据的存储和检索。

采用自顶而下,自低向上的层次关系

  1. Web层 接收来自前端的请求,调用 Service层 的方法来处理业务逻辑。

  2. Service层 根据业务需求调用 Dao层 的方法来操作数据库。

  3. Dao层 执行数据库操作,并将结果返回给 Service层

  4. Service层 将处理后的结果返回给 Web层,再由 Web层 将最终结果呈现给用户。

Spring框架广泛采用了MVC架构模式,通过注解来明确区分不同的层次,使得代码更加清晰和模块化。以下是Spring中MVC三层架构的具体实现:

JAVA中的MVC三层架构_第1张图片

1. 控制器层(Controller)
  • 注解@Controller

  • 作用:处理用户的请求,调用服务层进行业务处理,然后选择适当的视图进行响应。

  • 示例:

    @Controller
     public class UserController {
         @Autowired
         private UserService userService;
     ​
         @RequestMapping("/users")
         public String listUsers(Model model) {
             List users = userService.getAllUsers();
             model.addAttribute("users", users);
             return "userList"; // 返回视图名称
         }
     }
2. 服务层(Service)
  • 注解@Service

  • 作用:处理业务逻辑,调用数据访问层进行数据操作。

  • 示例:

    @Service
     public class UserService {
         @Autowired
         private UserRepository userRepository;
     ​
         public List getAllUsers() {
             return userRepository.findAll();
         }
     ​
         public User getUserById(Long id) {
             return userRepository.findById(id).orElse(null);
         }
     ​
         public void saveUser(User user) {
             userRepository.save(user);
         }
     ​
         public void deleteUser(Long id) {
             userRepository.deleteById(id);
         }
     }
3. 数据访问层(DAO)
  • 注解@Repository

  • 作用:负责与数据库交互,执行CRUD操作。

  • 示例:

    @Repository
     public interface UserRepository extends JpaRepository {
         // 可以添加自定义的查询方法
         List findByUsername(String username);
     }
工作流程
  1. 用户请求:用户通过浏览器发送HTTP请求到服务器。

  2. 前端控制器:Spring的前端控制器DispatcherServlet接收到请求。

  3. 处理器映射DispatcherServlet根据请求URL和配置的映射规则,找到对应的控制器方法。

  4. 控制器处理:控制器方法被调用,处理用户的请求。

  5. 调用服务层:控制器调用服务层的方法,进行业务逻辑处理。

  6. 调用数据访问层:服务层调用数据访问层的方法,进行数据操作。

  7. 返回数据:数据访问层返回数据给服务层,服务层处理完业务后返回数据给控制器。

  8. 选择视图:控制器选择合适的视图进行渲染,并将数据传递给视图。

  9. 视图渲染:视图生成最终的HTML页面。

  10. 响应用户DispatcherServlet将生成的HTML页面返回给用户。

优势
  • 分离关注点:每个层次都有明确的职责,使得代码更加清晰和模块化。

  • 提高可维护性:各层之间松耦合,便于维护和扩展。

  • 依赖注入:Spring的依赖注入机制使得对象的创建和管理更加方便,减少了硬编码。

总结

Spring框架通过@Controller@Service@Repository注解清晰地划分了MVC三层架构的各个层次,使得开发人员能够更高效地构建和维护复杂的Web应用。


POJO(Plain Old Java Object)类

  • 定义:POJO是指普通的Java对象,即没有继承任何特殊类或实现任何特殊接口的Java类。

  • 特点:

    • 纯粹的Java对象,不依赖于任何框架或库。

    • 通常用于表示业务实体或数据模型。

    • 包含属性和相关的getter/setter方法。

  • 示例:

public class User {
    private Long id;
    private String username;
    private String email;

    // Getter 和 Setter 方法
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}
DAO(Data Access Object)类
  • 定义:DAO是指数据访问对象,用于封装对数据库的操作。

  • 特点:

    • 提供一个抽象的接口,隐藏了具体的数据库访问细节。

    • 通常包含CRUD(创建、读取、更新、删除)操作方法。

    • 可以使用JDBC、ORM框架(如Hibernate、MyBatis)等技术实现。

  • 示例:

@Repository
public class UserDaoImpl implements UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public List findAll() {
        String sql = "SELECT * FROM users";
        return jdbcTemplate.query(sql, new UserRowMapper());
    }

    @Override
    public User findById(Long id) {
        String sql = "SELECT * FROM users WHERE id = ?";
        return jdbcTemplate.queryForObject(sql, new Object[]{id}, new UserRowMapper());
    }

    @Override
    public void save(User user) {
        String sql = "INSERT INTO users (username, email) VALUES (?, ?)";
        jdbcTemplate.update(sql, user.getUsername(), user.getEmail());
    }

    @Override
    public void update(User user) {
        String sql = "UPDATE users SET username = ?, email = ? WHERE id = ?";
        jdbcTemplate.update(sql, user.getUsername(), user.getEmail(), user.getId());
    }

    @Override
    public void delete(Long id) {
        String sql = "DELETE FROM users WHERE id = ?";
        jdbcTemplate.update(sql, id);
    }

    private static class UserRowMapper implements RowMapper {
        @Override
        public User mapRow(ResultSet rs, int rowNum) throws SQLException {
            User user = new User();
            user.setId(rs.getLong("id"));
            user.setUsername(rs.getString("username"));
            user.setEmail(rs.getString("email"));
            return user;
        }
    }
}
两者的关系
  • POJO类:表示业务实体,通常用于数据传输和存储。

  • DAO类:负责对POJO类进行数据库操作,提供数据访问的接口。

示例应用

假设有一个简单的用户管理系统,其中包含用户实体(User)和用户数据访问对象(UserDao):

  • User(POJO类)
public class User {
    private Long id;
    private String username;
    private String email;

    // Getter 和 Setter 方法
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}
  • UserDao(DAO类)
@Repository
public class UserDaoImpl implements UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public List findAll() {
        String sql = "SELECT * FROM users";
        return jdbcTemplate.query(sql, new UserRowMapper());
    }

    @Override
    public User findById(Long id) {
        String sql = "SELECT * FROM users WHERE id = ?";
        return jdbcTemplate.queryForObject(sql, new Object[]{id}, new UserRowMapper());
    }

    @Override
    public void save(User user) {
        String sql = "INSERT INTO users (username, email) VALUES (?, ?)";
        jdbcTemplate.update(sql, user.getUsername(), user.getEmail());
    }

    @Override
    public void update(User user) {
        String sql = "UPDATE users SET username = ?, email = ? WHERE id = ?";
        jdbcTemplate.update(sql, user.getUsername(), user.getEmail(), user.getId());
    }

    @Override
    public void delete(Long id) {
        String sql = "DELETE FROM users WHERE id = ?";
        jdbcTemplate.update(sql, id);
    }

    private static class UserRowMapper implements RowMapper {
        @Override
        public User mapRow(ResultSet rs, int rowNum) throws SQLException {
            User user = new User();
            user.setId(rs.getLong("id"));
            user.setUsername(rs.getString("username"));
            user.setEmail(rs.getString("email"));
            return user;
        }
    }
}
总结
  • POJO类:用于表示业务实体,通常包含属性和相关的getter/setter方法。

  • DAO类:用于封装对数据库的操作,提供数据访问的接口。

  • 两者结合:POJO类表示数据,DAO类负责数据的持久化操作,共同实现业务逻辑。

你可能感兴趣的:(Java笔记,java,mvc,架构)