Skip to content

Commit c5b87e2

Browse files
committed
feat: add a new example project simple-user and update documents
1 parent 7b4b831 commit c5b87e2

File tree

62 files changed

+2899
-1082
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+2899
-1082
lines changed
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
---
2+
description:
3+
globs:
4+
alwaysApply: true
5+
---
6+
# Fust 微服务开发框架 - 开发规范
7+
8+
## Model 规范与规则
9+
10+
### 通用要求
11+
- Model 类必须使用 `@Table` 注解标明对应的数据库表名和 schema
12+
- 所有主键必须使用 `@Id` 注解标识
13+
- 自动生成/填充的字段需要使用 `@DbAutoColumn` 注解标识,例如 createdAt, updatedAt 等时间字段
14+
- Model 类应该是 Plain Java Object,不要包含业务逻辑
15+
- 所有属性应当使用包装类型而非基本类型,例如使用 `Long` 而非 `long`
16+
17+
### @Table 注解规范
18+
- 必须指定真实的表名,推荐在类中定义表名常量
19+
- 若数据库有 schema,必须在注解中指定 schema
20+
- 示例: `@Table(name = UserModel.TABLE_NAME, schema = "user")`
21+
22+
### @Id 注解规范
23+
- 每个 Model 必须有一个属性被标记为 `@Id`
24+
- 通常情况下,`@Id` 应用于主键字段,如 `id`
25+
- 若使用手动设置主键的策略,则需添加 `@ManualId` 注解
26+
27+
### @DbAutoColumn 注解规范
28+
- 应用于由数据库自动生成的列,如创建时间、更新时间等
29+
- 被 `@DbAutoColumn` 标记的字段在创建和更新操作中会被忽略
30+
- 示例: `@DbAutoColumn private LocalDateTime createdAt;`
31+
32+
## Dao 规范与规则
33+
34+
### 通用要求
35+
- 所有 Dao 接口必须使用 `@Mapper` 注解标识
36+
- Dao 接口必须继承 `TemplateDao<T>` 接口,其中 T 为对应的 Model 类
37+
- 所有 Dao 方法必须使用 MyBatis 注解方式定义,避免使用 XML 配置
38+
39+
### TemplateDao 使用规范
40+
- 继承 TemplateDao 后自动获得基础的 CRUD 操作方法
41+
- 继承的基础方法包括: `create`, `find`, `update`, `remove`, `batchCreate`, `patch`, `batchPatch`
42+
- 若有特殊需求,可以在 Dao 接口中添加自定义方法
43+
44+
### 自定义方法规范
45+
- 自定义 Dao 方法必须使用 MyBatis 注解方式定义
46+
- 常用注解包括: `@Select`, `@Insert`, `@Update`, `@Delete`
47+
- 复杂查询推荐使用 `@ResultMap` 注解映射结果集
48+
- 对于批量操作,推荐使用 `@Lang(CollectionDriver.class)` 处理集合参数
49+
50+
### 示例规范
51+
```java
52+
@Mapper
53+
public interface UserDao extends TemplateDao<UserModel> {
54+
// 表名常量定义
55+
String TABLE_NAME = "t_user";
56+
57+
// 自定义查询方法
58+
@Select({"SELECT * FROM", TABLE_NAME, "WHERE name = #{name}"})
59+
@ResultMap("UserModel")
60+
UserModel findByName(@Param("name") String name);
61+
62+
// 批量查询使用 CollectionDriver
63+
@Lang(CollectionDriver.class)
64+
@Select("SELECT * FROM " + TABLE_NAME + " WHERE id IN @ids")
65+
@ResultMap("UserModel")
66+
List<UserModel> findByIds(@Param("ids") Collection<Long> ids);
67+
}
68+
```
69+
70+
## 测试规范与规则
71+
72+
### 单元测试规范
73+
- 使用 JUnit 5 进行单元测试
74+
- 使用 Mockito 模拟外部依赖
75+
- 不要使用 SpringBoot 的测试注解进行单元测试
76+
- 针对单一功能点编写测试
77+
- 测试类和方法名称要清晰表达测试意图
78+
79+
### 单元测试示例
80+
```java
81+
@ExtendWith(MockitoExtension.class)
82+
class UserServiceTest {
83+
@Mock
84+
private UserDao userDao;
85+
86+
@InjectMocks
87+
private UserServiceImpl userService;
88+
89+
@Test
90+
void testGetUserById_WhenExists_ReturnsUser() {
91+
// Arrange
92+
UserModel mockUser = new UserModel();
93+
mockUser.setId(1L);
94+
when(userDao.find(1L)).thenReturn(mockUser);
95+
96+
// Act
97+
UserModel result = userService.getUserById(1L);
98+
99+
// Assert
100+
assertNotNull(result);
101+
assertEquals(1L, result.getId());
102+
verify(userDao, times(1)).find(1L);
103+
}
104+
}
105+
```
106+
107+
### 集成测试规范
108+
- 集成测试可以使用 SpringBoot 的测试能力
109+
- 使用 `@SpringBootTest` 进行完整应用上下文测试
110+
- 使用 `@WebMvcTest` 进行控制器层测试
111+
- 使用 `@DataJpaTest` 或类似注解进行数据访问层测试
112+
- 使用 `@ActiveProfiles("test")` 激活测试配置
113+
- 使用 `@Transactional` 确保测试方法间的数据隔离
114+
115+
### 集成测试示例
116+
```java
117+
@SpringBootTest
118+
@ActiveProfiles("test")
119+
@Transactional
120+
class UserServiceIntegrationTest {
121+
@Autowired
122+
private UserService userService;
123+
124+
@Autowired
125+
private UserDao userDao;
126+
127+
@Test
128+
void testCreateAndFindUser() {
129+
// Arrange
130+
UserModel user = new UserModel();
131+
user.setName("Test User");
132+
133+
// Act
134+
boolean created = userService.createUser(user);
135+
UserModel found = userService.getUserById(user.getId());
136+
137+
// Assert
138+
assertTrue(created);
139+
assertNotNull(found);
140+
assertEquals("Test User", found.getName());
141+
}
142+
}
143+
```
144+
145+
### 测试最佳实践
146+
- 确保测试覆盖正常路径和异常路径
147+
- 编写可重复、快速和独立的测试
148+
- 避免测试间的状态依赖
149+
- 使用恰当的断言验证测试结果
150+
- 测试类应保持与被测试类相同的包结构
151+
- 单元测试文件名应以 `Test` 结尾,集成测试文件名可以以 `IT` 结尾

examples/simple-user/.gitignore

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
target/
2+
!.mvn/wrapper/maven-wrapper.jar
3+
*.DS_Store
4+
*.log
5+
.vscode
6+
mod_lib/
7+
lib/
8+
services/
9+
gen-src/
10+
generated-cache/
11+
### STS ###
12+
.apt_generated
13+
.classpath
14+
.factorypath
15+
.project
16+
.settings
17+
.springBeans
18+
19+
### IntelliJ IDEA ###
20+
.idea
21+
*.iws
22+
*.iml
23+
*.ipr
24+
25+
### NetBeans ###
26+
nbproject/private/
27+
build/
28+
nbbuild/
29+
dist/
30+
nbdist/
31+
.nb-gradle/
32+
33+
### python env ###
34+
venv/
35+
gen-py/
36+

0 commit comments

Comments
 (0)