| 組件 | 原文版本 | 建議現代版本 | 說明 |
|---|---|---|---|
| IDE | Spring Tool Suite (STS) | IntelliJ IDEA 2024.x | STS 已停止獨立發佈,功能整合進 IDEA 插件 |
| JDK | 1.8 | 17 / 21 (LTS) | 長期支援、性能更強、語法更現代 |
| Spring | 4.x (隱含) | Spring Boot 3.2+ / Spring Framework 6.x | Boot 3 基線 JDK 17,自動配置極大簡化 XML |
| MyBatis | 3.4.x | MyBatis 3.5+ / MyBatis-Plus 3.5+ | Plus 提供 CRUD 封裝、分頁、代碼生成 |
| MySQL | 5.5 | 8.0 / 8.4 LTS | CBO 優化器、窗口函數、JSON、CTE |
| 構建工具 | Maven 3.3+ | Maven 3.9+ / Gradle 8.x | Gradle 配置更簡潔、增量構建更快 |
parent-project (pom, packaging=pom) ├── common-module # 通用工具、常量、異常、DTO ├── domain-module # 實體、VO、Repository 接口 ├── infrastructure-module # MyBatis Mapper、配置、第三方適配 ├── application-module # Service 實現、事務邊界、業務編排 └── web-module # Controller、配置、啟動類 (Spring Boot)
<!-- parent/pom.xml -->
<properties>
<java.version>17</java.version>
<spring-boot.version>3.2.5</spring-boot.version>
<mybatis-plus.version>3.5.5</mybatis-plus.version>
<mysql.version>8.0.33</mysql.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
@Configuration
@MapperScan("com.example.infrastructure.mapper")
public class MyBatisConfig {
@Bean
public DataSource dataSource(@Value("${spring.datasource.url}") String url,
@Value("${spring.datasource.username}") String user,
@Value("${spring.datasource.password}") String pass) {
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl(url); ds.setUsername(user); ds.setPassword(pass);
ds.setMaximumPoolSize(20);
return ds;
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource ds) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(ds);
bean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:mapper/**/*.xml"));
bean.setTypeAliasesPackage("com.example.domain.entity");
return bean.getObject();
}
}
spring:
datasource:
url: jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
servlet:
multipart:
max-file-size: 10MB
max-request-size: 50MB
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: ASSIGN_ID # 雪花算法 ID
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
// domain/entity/User.java
@Data @TableName("sys_user")
public class User {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
private String username;
private String password;
private Integer status;
private LocalDateTime createTime;
}
// infrastructure/mapper/UserMapper.java
@Mapper
public interface UserMapper extends BaseMapper {
@Select("SELECT * FROM sys_user WHERE username = #{username}")
User findByUsername(String username);
}
// infrastructure/mapper/UserMapper.xml (可選,複雜 SQL)
<mapper namespace="com.example.infrastructure.mapper.UserMapper">
<resultMap id="UserMap" type="com.example.domain.entity.User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="createTime" column="create_time"/>
</resultMap>
</mapper>
@Service @RequiredArgsConstructor @Transactional
public class UserService {
private final UserMapper userMapper;
private final PasswordEncoder passwordEncoder;
public Long register(String username, String rawPassword) {
if (userMapper.findByUsername(username) != null) throw new BizException("用戶已存在");
User user = new User();
user.setUsername(username);
user.setPassword(passwordEncoder.encode(rawPassword));
user.setStatus(1);
user.setCreateTime(LocalDateTime.now());
userMapper.insert(user);
return user.getId();
}
}
@RestController @RequestMapping("/api/users") @RequiredArgsConstructor
public class UserController {
private final UserService userService;
@PostMapping("/register")
public R register(@RequestBody @Valid RegisterDTO dto) {
return R.ok(userService.register(dto.getUsername(), dto.getPassword()));
}
}
@SpringBootApplication
@EnableTransactionManagement
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
運行後訪問 https://localhost:8080/api/users/register 測試。
| 問題 | 原因 | 解決 |
|---|---|---|
| Mapper 掃描失效 | 包路徑不匹配 | @MapperScan 基礎包精確到 mapper 所在層 |
| 下劃線轉駝峰失效 | 配置錯誤 | mybatis-plus.configuration.map-underscore-to-camel-case=true |
| 事務不生效 | 方法非 public / 同類內調用 / 異常被吞 | public 方法、AOP 代理調用、rollbackFor=Exception.class |
| ID 衝突/重複 | 自增 ID 分庫分表 | 雪花算法 ASSIGN_ID 或 UUID |
現代 Spring Boot + MyBatis-Plus 專案**零 XML 配置、約定優於配置、啟動極快**。本文提供從依賴管理、分層架構、核心配置到業務代碼的完整最佳實踐模板,可直接作為新專案脚手架。