本文目录导读:

我来为你详细介绍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(持久化对象)
这个分层架构的好处:
- 解耦性:各层职责清晰,互相隔离
- 可维护性:修改某一层不影响其他层
- 可测试性:各层可以独立进行单元测试
- 安全性:数据在上层进行校验和转换,避免直接暴露底层数据结构
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播