本文目录导读:

我来为你详细介绍Java分层规范的搭建方法,以一个实际案例来说明。
项目结构搭建
以一个简单的电商系统为例,展示Java分层架构:
ecommerce-app
├── src/main/java
│ └── com/ecommerce
│ ├── controller # 控制器层
│ │ ├── UserController.java
│ │ └── OrderController.java
│ ├── service # 服务层
│ │ ├── UserService.java
│ │ └── OrderService.java
│ ├── service/impl # 服务实现
│ │ ├── UserServiceImpl.java
│ │ └── OrderServiceImpl.java
│ ├── repository # 数据访问层
│ │ ├── UserRepository.java
│ │ └── OrderRepository.java
│ ├── entity # 实体类
│ │ ├── User.java
│ │ └── Order.java
│ ├── dto # 数据传输对象
│ │ ├── UserDTO.java
│ │ └── OrderDTO.java
│ ├── vo # 视图对象
│ │ ├── UserVO.java
│ │ └── OrderVO.java
│ └── common # 公共模块
│ ├── result # 统一返回结果
│ │ └── Result.java
│ ├── exception # 异常处理
│ │ └── GlobalExceptionHandler.java
│ └── config # 配置类
│ └── WebConfig.java
各层代码实现
1 实体层(Entity)
// entity/User.java
@Data
@TableName("user") // MyBatis-Plus注解
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String username;
private String password;
private String email;
private String phone;
private Integer status;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}
2 数据访问层(Repository)
// repository/UserRepository.java
@Repository
public interface UserRepository extends BaseMapper<User> {
@Select("SELECT * FROM user WHERE username = #{username}")
User findByUsername(String username);
@Select("SELECT * FROM user WHERE email = #{email}")
User findByEmail(String email);
}
3 DTO层(数据传输对象)
// dto/LoginDTO.java
@Data
public class LoginDTO {
@NotBlank(message = "用户名不能为空")
private String username;
@NotBlank(message = "密码不能为空")
private String password;
}
// dto/UserCreateDTO.java
@Data
public class UserCreateDTO {
@NotBlank(message = "用户名不能为空")
@Size(min = 3, max = 20, message = "用户名长度3-20个字符")
private String username;
@NotBlank(message = "密码不能为空")
@Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{6,20}$",
message = "密码必须包含大小写字母和数字")
private String password;
@Email(message = "邮箱格式不正确")
private String email;
private String phone;
}
4 服务层(Service)
// service/impl/UserServiceImpl.java
@Service
@Slf4j
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public UserVO login(LoginDTO loginDTO) {
// 业务逻辑处理
User user = userRepository.findByUsername(loginDTO.getUsername());
if (user == null) {
throw new BusinessException("用户不存在");
}
// 密码校验
if (!passwordEncoder.matches(loginDTO.getPassword(), user.getPassword())) {
throw new BusinessException("密码错误");
}
// 转换为VO返回
UserVO userVO = new UserVO();
BeanUtils.copyProperties(user, userVO);
return userVO;
}
@Override
@Transactional
public UserVO createUser(UserCreateDTO userCreateDTO) {
// 检查用户名是否已存在
User existUser = userRepository.findByUsername(userCreateDTO.getUsername());
if (existUser != null) {
throw new BusinessException("用户名已存在");
}
// DTO转Entity
User user = new User();
BeanUtils.copyProperties(userCreateDTO, user);
user.setPassword(passwordEncoder.encode(user.getPassword()));
user.setStatus(1);
// 保存
userRepository.insert(user);
// Entity转VO
UserVO userVO = new UserVO();
BeanUtils.copyProperties(user, userVO);
return userVO;
}
@Override
public PageResult<UserVO> getUserList(int page, int size) {
Page<User> pageInfo = new Page<>(page, size);
Page<User> userPage = userRepository.selectPage(pageInfo, null);
List<UserVO> userVOs = userPage.getRecords().stream()
.map(user -> {
UserVO userVO = new UserVO();
BeanUtils.copyProperties(user, userVO);
return userVO;
})
.collect(Collectors.toList());
return new PageResult<>(userVOs, userPage.getTotal(), page, size);
}
}
5 控制器层(Controller)
// controller/UserController.java
@RestController
@RequestMapping("/api/users")
@Validated
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/login")
public Result<UserVO> login(@Valid @RequestBody LoginDTO loginDTO) {
UserVO userVO = userService.login(loginDTO);
return Result.success(userVO);
}
@PostMapping
public Result<UserVO> createUser(@Valid @RequestBody UserCreateDTO userCreateDTO) {
UserVO userVO = userService.createUser(userCreateDTO);
return Result.success(userVO);
}
@GetMapping
public Result<PageResult<UserVO>> getUserList(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size) {
return Result.success(userService.getUserList(page, size));
}
}
6 统一响应封装
// common/result/Result.java
@Data
public class Result<T> {
private Integer code;
private String message;
private T data;
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>();
result.setCode(200);
result.setMessage("success");
result.setData(data);
return result;
}
public static <T> Result<T> error(Integer code, String message) {
Result<T> result = new Result<>();
result.setCode(code);
result.setMessage(message);
return result;
}
}
// common/exception/BusinessException.java
public class BusinessException extends RuntimeException {
private Integer code;
public BusinessException(String message) {
super(message);
this.code = 500;
}
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
}
7 全局异常处理
// common/exception/GlobalExceptionHandler.java
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result<Void> handleValidationException(MethodArgumentNotValidException e) {
String message = e.getBindingResult().getFieldErrors().stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.joining(", "));
return Result.error(400, message);
}
@ExceptionHandler(BusinessException.class)
public Result<Void> handleBusinessException(BusinessException e) {
log.error("业务异常:{}", e.getMessage());
return Result.error(e.getCode(), e.getMessage());
}
@ExceptionHandler(Exception.class)
public Result<Void> handleException(Exception e) {
log.error("系统异常:", e);
return Result.error(500, "系统内部异常");
}
}
配置说明
1 Maven依赖
<dependencies>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis-Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
2 配置文件
# application.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/ecommerce?useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true
规范的调用流程
Controller(接收请求)→ DTO(数据校验)→ Service(业务逻辑)→ Repository(数据操作)
↓ ↓
VO(视图响应) Entity(持久化对象)
这个分层架构的好处:
- 解耦性:各层职责清晰,互相隔离
- 可维护性:修改某一层不影响其他层
- 可测试性:各层可以独立进行单元测试
- 安全性:数据在上层进行校验和转换,避免直接暴露底层数据结构