mirror of
https://github.com/YunaiV/ruoyi-vue-pro.git
synced 2025-10-27 11:46:05 +08:00
9.9 KiB
9.9 KiB
💻 开发指南
快速上手企业级开发,掌握最佳实践!
🛠 开发环境搭建
IDE 推荐配置
⚡ IntelliJ IDEA(强烈推荐)
# 1. 必装插件
- Lombok Plugin
- MyBatis X
- Maven Helper
- Alibaba Java Coding Guidelines
# 2. 导入代码风格
导入:script/idea/settings.jar
# 3. 启动配置
Main class: cn.iocoder.yudao.server.YudaoServerApplication
VM options: -Dspring.profiles.active=local
🔧 IDEA 优化配置
# VM 配置优化
-Xmx2048m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
# 编码设置
File → Settings → Editor → File Encodings
设置为 UTF-8
# 自动导包
File → Settings → Editor → General → Auto Import
勾选所有选项
🚀 核心开发技能
🎯 项目结构理解
yudao-module-{module}/
├── controller/ # 控制器层 - 接收请求
├── service/ # 业务逻辑层 - 核心业务
│ └── impl/ # 实现类
├── dal/ # 数据访问层
│ ├── dataobject/ # 数据对象(DO)
│ └── mysql/ # MyBatis Mapper
├── convert/ # 对象转换类
├── vo/ # 视图对象
│ ├── req/ # 请求对象
│ └── resp/ # 响应对象
└── enums/ # 枚举类
🔥 必会开发模式
1. CRUD 标准开发流程
// 1. 创建 DO (Data Object)
@TableName("system_user")
public class UserDO extends BaseDO {
private Long id;
private String username;
// ...
}
// 2. 创建 Mapper
@Mapper
public interface UserMapper extends BaseMapperX<UserDO> {
default PageResult<UserDO> selectPage(UserPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<UserDO>()
.likeIfPresent(UserDO::getUsername, reqVO.getUsername())
.betweenIfPresent(UserDO::getCreateTime, reqVO.getCreateTime()));
}
}
// 3. 创建 Service
@Service
public class UserServiceImpl implements UserService {
@Override
public Long createUser(UserCreateReqVO createReqVO) {
// 校验用户名唯一性
validateUserUnique(createReqVO.getUsername());
// 插入用户
UserDO user = UserConvert.INSTANCE.convert(createReqVO);
userMapper.insert(user);
return user.getId();
}
}
// 4. 创建 Controller
@RestController
@RequestMapping("/admin-api/system/user")
public class UserController {
@PostMapping("/create")
@PreAuthorize("@ss.hasPermission('system:user:create')")
public CommonResult<Long> createUser(@Valid @RequestBody UserCreateReqVO createReqVO) {
return success(userService.createUser(createReqVO));
}
}
2. 统一异常处理
// 定义错误码
public interface ErrorCodeConstants {
ErrorCode USER_NOT_EXISTS = new ErrorCode(1_002_001_000, "用户不存在");
ErrorCode USERNAME_DUPLICATE = new ErrorCode(1_002_001_001, "用户名已存在");
}
// 使用异常
public void validateUserUnique(String username) {
if (userMapper.selectByUsername(username) != null) {
throw exception(USERNAME_DUPLICATE);
}
}
3. 权限控制
// 菜单权限
@PreAuthorize("@ss.hasPermission('system:user:query')")
// 数据权限
@DataPermission(enable = false) // 禁用数据权限
@DataPermission(enable = true, includeScope = DeptDataPermissionRespVO.class)
// 多租户
@TenantIgnore // 忽略多租户
🧰 开发神器
代码生成器
# 1. 访问代码生成
http://localhost:48080 → 系统管理 → 代码生成
# 2. 一键生成
- Controller (控制器)
- Service (业务层)
- Mapper (数据层)
- Vue 页面
- SQL 脚本
接口调试
# Swagger 文档
http://localhost:48080/doc.html
# 接口测试
http://localhost:48080/swagger-ui
# 数据库文档
http://localhost:48080/doc/db
实用工具类
// 1. 集合工具
CollUtil.isEmpty(list)
CollUtil.convertList(list, User::getName)
// 2. 字符串工具
StrUtil.isBlank(str)
StrUtil.format("用户{}不存在", username)
// 3. 日期工具
LocalDateTimeUtil.now()
LocalDateTimeUtil.parse("2023-01-01 12:00:00")
// 4. Bean 拷贝
BeanUtil.copyProperties(source, target)
// 5. 分页工具
PageUtils.build(pageNo, pageSize)
🧪 测试最佳实践
单元测试模板
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
class UserServiceImplTest extends BaseDbUnitTest {
@Resource
private UserService userService;
@Test
public void testCreateUser_success() {
// given - 准备数据
UserCreateReqVO reqVO = randomPojo(UserCreateReqVO.class,
o -> o.setUsername("test"));
// when - 执行操作
Long userId = userService.createUser(reqVO);
// then - 验证结果
assertNotNull(userId);
UserDO user = userService.getUser(userId);
assertPojoEquals(reqVO, user);
}
@Test
public void testCreateUser_usernameDuplicate() {
// given
insertUser(o -> o.setUsername("test"));
UserCreateReqVO reqVO = randomPojo(UserCreateReqVO.class,
o -> o.setUsername("test"));
// when & then
assertServiceException(() -> userService.createUser(reqVO),
USERNAME_DUPLICATE);
}
}
Mock 测试技巧
@MockBean
private RedisTemplate<String, String> redisTemplate;
@Test
public void testWithMock() {
// Mock 返回值
when(redisTemplate.opsForValue().get("key")).thenReturn("value");
// 验证调用
verify(redisTemplate).opsForValue();
}
🎨 代码规范速查
命名规范
| 类型 | 规范 | 示例 |
|---|---|---|
| Controller | {模块}{功能}Controller |
UserController |
| Service | {模块}{功能}Service |
UserService |
| DO | {模块}{功能}DO |
UserDO |
| VO | {模块}{功能}{类型}VO |
UserCreateReqVO |
方法命名
| 操作 | 命名 | 示例 |
|---|---|---|
| 查询分页 | get{模块}Page |
getUserPage |
| 查询详情 | get{模块} |
getUser |
| 创建 | create{模块} |
createUser |
| 更新 | update{模块} |
updateUser |
| 删除 | delete{模块} |
deleteUser |
🔧 常用开发技巧
1. 快速生成测试数据
// 使用 RandomUtils 生成测试数据
UserDO user = randomPojo(UserDO.class, o -> {
o.setId(null); // 不设置ID
o.setUsername("test" + randomString()); // 随机用户名
});
2. 数据库操作技巧
// 批量插入
userMapper.insertBatch(userList);
// 条件构造器
LambdaQueryWrapperX<UserDO> query = new LambdaQueryWrapperX<UserDO>()
.eqIfPresent(UserDO::getStatus, reqVO.getStatus())
.likeIfPresent(UserDO::getUsername, reqVO.getUsername())
.betweenIfPresent(UserDO::getCreateTime, reqVO.getCreateTime());
3. 缓存使用技巧
// Spring Cache
@Cacheable(value = "user", key = "#id")
public UserDO getUser(Long id) {
return userMapper.selectById(id);
}
// Redis 工具类
stringRedisTemplate.opsForValue().set("key", "value", Duration.ofMinutes(30));
4. 异步处理
@Async("taskExecutor")
public CompletableFuture<Void> sendEmailAsync(String email, String content) {
// 异步发送邮件
emailService.send(email, content);
return CompletableFuture.completedFuture(null);
}
🐛 调试技巧
1. 日志调试
// 使用 Slf4j
@Slf4j
@Service
public class UserServiceImpl {
public void createUser(UserCreateReqVO reqVO) {
log.debug("创建用户,参数:{}", reqVO);
// 业务逻辑
log.info("用户创建成功,ID:{}", user.getId());
}
}
2. 远程调试
# 启动时加上调试参数
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar app.jar
# IDEA 配置远程调试
Run → Edit Configurations → + → Remote JVM Debug
3. 性能分析
# JVM 参数
-XX:+PrintGCDetails
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/logs/heapdump.hprof
# 分析工具
jstack <pid> # 线程栈
jmap -dump:format=b,file=heap.dump <pid> # 内存快照
🚀 性能优化建议
1. SQL 优化
-- 添加索引
ALTER TABLE system_user ADD INDEX idx_username (username);
-- 避免 SELECT *
SELECT id, username, status FROM system_user WHERE status = 1;
-- 使用 LIMIT
SELECT * FROM system_user ORDER BY id DESC LIMIT 10;
2. 缓存策略
// 缓存热点数据
@Cacheable(value = "user", key = "#id", condition = "#id != null")
// 缓存失效策略
@CacheEvict(value = "user", key = "#user.id")
// 缓存更新
@CachePut(value = "user", key = "#user.id")
3. 连接池配置
spring:
datasource:
druid:
initial-size: 5
max-active: 20
min-idle: 5
max-wait: 60000
📚 学习资源
| 资源 | 链接 | 说明 |
|---|---|---|
| 🎥 视频教程 | B站教程 | 项目讲解视频 |
| 📖 在线文档 | 官方文档 | 详细开发文档 |
| 💬 技术交流 | QQ群:3147719 | 开发问题交流 |
| 🐛 问题反馈 | Gitee Issues | Bug反馈 |
🎯 快速定位问题
- 启动问题 → 检查端口、JDK版本、数据库连接
- 权限问题 → 检查
@PreAuthorize注解和角色配置 - 数据问题 → 检查多租户、数据权限配置
- 性能问题 → 开启SQL日志、检查索引、分析慢查询