feat: Spring Boot 学习脚手架 v2.0

- 新增 IoC 容器学习模块
- 新增 AOP 切面编程学习模块
- 新增 MyBatis 集成学习模块
- 新增事务管理学习模块
- 新增用户/产品/订单 CRUD
- 新增 7 个交互式学习页面
- 集成性能监控切面
This commit is contained in:
likingcode
2026-03-07 08:37:40 +00:00
commit c04235c655
73 changed files with 4978 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
package com.example.scaffold.service;
import com.example.scaffold.entity.User;
import java.util.List;
import java.util.Optional;
/**
* 用户服务接口 - 演示接口与实现分离
*/
public interface UserService {
List<User> findAll();
Optional<User> findById(Long id);
User save(User user);
void deleteById(Long id);
List<User> searchByUsername(String username);
long count();
}

View File

@@ -0,0 +1,126 @@
package com.example.scaffold.service.impl;
import com.example.scaffold.entity.Order;
import com.example.scaffold.entity.Product;
import com.example.scaffold.mapper.OrderMapper;
import com.example.scaffold.mapper.ProductMapper;
import com.example.scaffold.mapper.UserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.List;
/**
* 订单服务 - 演示事务传播和隔离级别
*
* 学习要点:
* 1. 事务传播行为 - Propagation
* 2. 事务隔离级别 - Isolation
* 3. 事务回滚 - rollbackFor
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderService {
private final OrderMapper orderMapper;
private final ProductMapper productMapper;
private final UserMapper userMapper;
/**
* 创建订单 - 演示事务
* REQUIRED: 有事务则加入,无则新建
*/
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public Order createOrder(Long userId, Long productId, Integer quantity) {
log.info("📦 [OrderService] 创建订单: userId={}, productId={}, quantity={}", userId, productId, quantity);
// 检查用户
if (userMapper.findById(userId) == null) {
throw new RuntimeException("用户不存在: " + userId);
}
// 检查产品
Product product = productMapper.findById(productId);
if (product == null) {
throw new RuntimeException("产品不存在: " + productId);
}
// 扣减库存
int rows = productMapper.decreaseStock(productId, quantity);
if (rows == 0) {
throw new RuntimeException("库存不足");
}
// 创建订单
Order order = new Order();
order.setUserId(userId);
order.setProductId(productId);
order.setQuantity(quantity);
order.setTotalPrice(product.getPrice().multiply(BigDecimal.valueOf(quantity)));
order.setStatus("PENDING");
orderMapper.insert(order);
log.info("✅ [OrderService] 订单创建成功: orderId={}", order.getId());
return order;
}
/**
* 模拟事务回滚
*/
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public Order createOrderWithRollback(Long userId, Long productId, Integer quantity, boolean shouldRollback) {
log.info("📦 [OrderService] 创建订单(可能回滚): userId={}, shouldRollback={}", userId, shouldRollback);
Order order = createOrder(userId, productId, quantity);
if (shouldRollback) {
log.warn("⚠️ [OrderService] 触发回滚!");
throw new RuntimeException("模拟事务回滚");
}
return order;
}
/**
* REQUIRES_NEW - 挂起当前事务,创建新事务
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logOrderOperation(Long orderId, String operation) {
log.info("📝 [OrderService] 记录订单操作: orderId={}, operation={}", orderId, operation);
// 这个方法会在独立事务中执行
// 即使外部事务回滚,这里的记录也会保留
}
/**
* 使用隔离级别 READ_COMMITTED
*/
@Transactional(isolation = Isolation.READ_COMMITTED)
public Order getOrder(Long id) {
return orderMapper.findById(id);
}
public List<Order> findAll() {
return orderMapper.findAll();
}
public List<Order> findByUserId(Long userId) {
return orderMapper.findByUserId(userId);
}
@Transactional
public void updateStatus(Long id, String status) {
orderMapper.updateStatus(id, status);
}
@Transactional
public void deleteById(Long id) {
orderMapper.deleteById(id);
}
}

View File

@@ -0,0 +1,77 @@
package com.example.scaffold.service.impl;
import com.example.scaffold.entity.User;
import com.example.scaffold.mapper.UserMapper;
import com.example.scaffold.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
/**
* 用户服务实现 - 演示 Spring 服务层
*
* 学习要点:
* 1. @Service - 标记为服务组件
* 2. @Transactional - 声明式事务
* 3. @RequiredArgsConstructor - Lombok 构造器注入
* 4. @Slf4j - Lombok 日志
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
private final UserMapper userMapper;
@Override
public List<User> findAll() {
log.info("📊 [UserService] 查询所有用户");
return userMapper.findAll();
}
@Override
public Optional<User> findById(Long id) {
log.info("🔍 [UserService] 查询用户: id={}", id);
// 演示 MyBatis 一级缓存 - 连续两次查询
User user = userMapper.findById(id);
User cached = userMapper.findById(id); // 第二次会命中缓存
if (cached != null) {
log.info("✅ [UserService] 一级缓存命中: id={}", id);
}
return Optional.ofNullable(user);
}
@Override
@Transactional
public User save(User user) {
log.info("💾 [UserService] 保存用户: {}", user.getUsername());
if (user.getId() == null) {
userMapper.insert(user);
} else {
userMapper.update(user);
}
return user;
}
@Override
@Transactional
public void deleteById(Long id) {
log.info("🗑️ [UserService] 删除用户: id={}", id);
userMapper.deleteById(id);
}
@Override
public List<User> searchByUsername(String username) {
log.info("🔎 [UserService] 搜索用户: username={}", username);
return userMapper.findByUsernameLike(username);
}
@Override
public long count() {
return userMapper.count();
}
}