🔍 Java 层级调用关系详解(附代码示例)
在 Java 开发中,层级调用是指不同职责的模块 / 类之间的协作调用,最典型的就是 MVC 架构中的「Controller → Service → Dao」分层调用。这种模式能让代码解耦、职责清晰,便于维护和扩展~下面用 Spring Boot 项目为例,带你一步步实现!

📦 一、经典分层架构

通常分为 4 层,每层职责明确:

  1. Controller 层:接收前端请求,调用 Service 处理,返回响应
  2. Service 层:处理业务逻辑,调用 Dao 层操作数据
  3. Dao 层(Mapper):直接操作数据库(增删改查)
  4. Entity 层:实体类,对应数据库表结构

🛠️ 二、代码实现完整示例

以「用户管理系统」为例,实现用户的查询、新增功能。

1. Entity 层(实体类)

java

// User.java
@Data // Lombok注解,自动生成getter/setter/toString等
public class User {
    private Long id;
    private String username;
    private String password;
    private Integer age;
}

👉 依赖:需要在pom.xml中引入 Lombok 依赖简化代码。

2. Dao 层(数据访问层)

java

// UserMapper.java
@Mapper // MyBatis注解,标识这是数据访问接口
public interface UserMapper {
    // 根据ID查询用户
    @Select("SELECT * FROM user WHERE id = #{id}")
    User getUserById(@Param("id") Long id);

    // 新增用户
    @Insert("INSERT INTO user(username, password, age) VALUES(#{username}, #{password}, #{age})")
    @Options(useGeneratedKeys = true, keyProperty = "id") // 自动返回主键ID
    int insertUser(User user);
}

👉 这里用 MyBatis 注解实现 SQL,也可以用 XML 映射文件。

3. Service 层(业务逻辑层)

java

// UserService.java
public interface UserService {
    User getUserById(Long id);
    boolean addUser(User user);
}

// UserServiceImpl.java
@Service // Spring注解,标识这是业务服务类
public class UserServiceImpl implements UserService {

    @Autowired // 自动注入UserMapper
    private UserMapper userMapper;

    @Override
    public User getUserById(Long id) {
        // 可以在这里添加业务逻辑,比如参数校验、权限判断
        if (id == null || id <= 0) {
            throw new IllegalArgumentException("用户ID非法");
        }
        return userMapper.getUserById(id);
    }

    @Override
    @Transactional // 事务注解,确保数据一致性
    public boolean addUser(User user) {
        // 业务逻辑:校验用户名是否已存在
        if (StringUtils.isEmpty(user.getUsername())) {
            throw new RuntimeException("用户名不能为空");
        }
        int result = userMapper.insertUser(user);
        return result > 0;
    }
}

👉 Service 层负责封装业务逻辑,调用 Dao 层完成数据操作,同时处理事务和异常。

4. Controller 层(请求处理层)

java

// UserController.java
@RestController // Spring注解,标识这是REST接口控制器
@RequestMapping("/api/users") // 基础路由
public class UserController {

    @Autowired // 自动注入UserService
    private UserService userService;

    // 根据ID查询用户
    @GetMapping("/{id}") // GET请求,路由:/api/users/1
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        try {
            User user = userService.getUserById(id);
            return ResponseEntity.ok(user); // 返回200和用户数据
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(null); // 返回400错误
        }
    }

    // 新增用户
    @PostMapping // POST请求,路由:/api/users
    public ResponseEntity<String> addUser(@RequestBody User user) {
        try {
            boolean success = userService.addUser(user);
            return success ? ResponseEntity.ok("新增成功") : ResponseEntity.status(500).body("新增失败");
        } catch (RuntimeException e) {
            return ResponseEntity.badRequest().body(e.getMessage());
        }
    }
}

👉 Controller 层接收前端请求,调用 Service 层处理,最后返回 JSON 响应。

🔄 三、层级调用流程

plaintext

前端请求 → Controller层 → Service层 → Dao层 → 数据库
         ←          ←          ←          ←
  1. 前端发送 HTTP 请求到 Controller
  2. Controller 解析请求参数,调用 Service 的方法
  3. Service 处理业务逻辑,调用 Dao 的方法操作数据库
  4. Dao 执行 SQL 语句,返回结果给 Service
  5. Service 处理结果后返回给 Controller
  6. Controller 封装响应数据,返回给前端

🎯 四、关键注意事项

  1. 依赖注入:使用@Autowired或构造注入,避免手动 new 对象,由 Spring 管理 Bean 生命周期
  2. 事务管理:在 Service 层添加@Transactional注解,确保业务操作的原子性
  3. 异常处理:Service 层抛出业务异常,Controller 层统一捕获并返回友好提示
  4. 职责单一:每层只做自己的事,比如 Controller 不处理业务,Service 不直接操作数据库

更多推荐