SmartAccess 与 Spring Data JPA
两者都允许只声明 Repository/Access 接口,但底层实现方式和成熟度差异很大。
概念对照
| SmartAccess | Spring Data JPA |
|---|---|
Access<T, PK> | Repository<T, ID> |
JpaAccess<T, PK> | CrudRepository / JpaRepository |
| 方法名派生查询 | Query Method |
Page / PageResult | Pageable / Page |
@Select / @Execute | @Query / @Modifying |
@Lock | @Lock |
@Transactional + Rain Hook | Spring Transaction AOP |
| ASM 生成实现类 | Repository Factory + Proxy |
同样的业务接口
SmartAccess:
interface StudentAccess : JpaAccess<Student, Int> {
fun findByNameAndAgeGteOrderByAgeDesc(
name: String,
age: Int,
page: Page,
): PageResult<Student>
}Spring Data JPA:
interface StudentRepository : JpaRepository<Student, Int> {
fun findByNameAndAgeGreaterThanEqualOrderByAgeDesc(
name: String,
age: Int,
pageable: Pageable,
): Page<Student>
}思路相同,但关键字词汇不同。SmartAccess 使用 Gte、Lte、Isn 等短后缀,Spring Data 使用更完整的 GreaterThanEqual、IsNull。
实现复杂度
Spring Data 通过 Repository 元数据、QueryLookupStrategy、代理和多层扩展点支持派生查询、Specifications、Query by Example、审计、投影等大量能力。
SmartAccess 的主路径更短:
MethodInterpreter
→ AbstractQuery
→ JpaAccessMaker
→ ASM 生成实现方法这正是 Rain 生态强调的“简单实现”:核心机制可以在少量源码中追完,调用时也不是动态代理分发。代价是解析关键字、返回类型、事务和查询生态远少于 Spring Data JPA。
分页差异
Spring Pageable 通常使用页码、页大小和 Sort;SmartAccess Page 直接保存 offset (start) 与 limit (num)。
Page.page(pIndex = 3, pSize = 20) // start=40, num=20SmartAccess 的 PageResult 只有 total 和 data,没有总页数、当前页、是否首尾页等派生信息,调用方可自行计算。
显式查询差异
Spring Data 的 @Query 明确支持 JPQL/nativeQuery,并整合 SpEL、命名参数、投影和修改查询。SmartAccess 的 @Select / @Execute 更接近把查询字符串交给生成器和底层 JPA Query;高级语义应直接使用 EntityManager 或扩展 AccessMaker。
事务差异
Spring Data 默认对部分 Repository 方法应用事务,并可与完整 Spring Transaction 传播规则结合。SmartAccess 不默认给每个 Access 方法包事务,业务层通过 Rain Hook @Transactional 声明边界。
这种做法鼓励把事务放在业务用例层,但当前实现尚不具备 Spring 的传播、隔离、只读和完善异常规则。
何时选择 SmartAccess
- 应用已经使用 Rain,希望保持同一 DI、类加载和生命周期。
- CRUD 与派生查询较简单,希望接口实现直接且源码可掌控。
- 团队愿意为数据库行为编写集成测试,并能补充框架缺口。
- 不需要 Spring Data 丰富的投影、Specification、审计和生态集成。
复杂查询模型、成熟事务治理和大量数据库生态适配是首要需求时,Spring Data JPA 更稳妥。SmartAccess 的价值不在于复制全部 Spring Data,而在于用更少的机制覆盖 Rain 应用最常见的数据访问路径。