Kiến trúc tổng thể¶
Kiến trúc LarkBatis gồm hai pha tách biệt rõ ràng và một mô hình biểu diễn trung gian (Intermediate Representation - IR). Mọi công việc phân tích, kiểm tra kiểu dữ liệu và sinh mã nguồn diễn ra hoàn toàn trong pha build; runtime chỉ là một lớp mỏng gọi JDBC trực tiếp.
flowchart LR
subgraph build["Pha Build (javac annotation processing)"]
A["Mapper Interface<br/>@Select / @Insert"] --> F
B["Mapper XML<br/><select> <if> <foreach>"] --> F
F["Frontend Parser<br/>phân tích cú pháp · kiểm tra kiểu · gập hằng"] --> IR["MapperModel<br/>(IR)"]
IR --> E["JavaPoet Emitter"]
end
subgraph run["Pha Runtime (~1.500 dòng code, JDBC thuần)"]
E --> G1["UserMapper$$Impl"]
E --> G2["UserRow"]
E --> G3["LarkBatisMappers"]
E --> G4["LarkBatisMapperConfiguration"]
G1 --> RT["larkbatis-runtime<br/>LarkBatisSession · JdbcCodec · SqlFragment"]
RT --> JDBC[("JDBC Driver")]
end
Phân chia Repository và Module¶
| Repository | Module | Phạm vi sử dụng |
|---|---|---|
larkbatis |
larkbatis-annotations |
Annotation-only (phạm vi CLASS), không chứa logic |
larkbatis-runtime |
Runtime core: JDBC thuần (~1.500 dòng code) | |
larkbatis-processor |
Build-time only: Annotation processor sinh mã nguồn | |
larkbatis-gradle-plugin |
Plugin ID io.github.larkbatis |
Build-time only: Tự động cấu hình Gradle task và incremental input |
larkbatis-maven-plugin |
Maven Plugin | Build-time only: Cấu hình compiler path và refresh XML |
larkbatis-spring |
larkbatis-spring, starter, autoconfigure |
Tích hợp Spring Boot và DataSourceUtils |
Quy tắc bất biến: Các module build-time tuyệt đối không xuất hiện trên runtime classpath của ứng dụng.
Pha Build (Compile-Time)¶
Frontend Parser¶
LarkBatis hỗ trợ 2 frontend đầu vào: Java Annotation (@Select, @Insert, v.v.) và XML Mapper. Cả hai đều được chuyển đổi về cùng một cấu trúc MapperModel (IR) duy nhất:
- Phân tích cú pháp câu SQL, chuyển
#{}thành các vị trí parameter bind và kiểm tra an toàn cho${}. - Kiểm tra kiểu dữ liệu tĩnh của các tham số và truy vết getter thuộc tính.
- Phân tích danh sách SELECT để cố định index đọc cột trong
ResultSet. - Chọn hàm chuyển đổi kiểu dữ liệu tối ưu trong
JdbcCodec. - Biên dịch các biểu thức
testtrong thẻ<if>thành mã Java boolean tương ứng. - Tối ưu tiền tố/hậu tố của
<where>,<set>,<trim>. - Inlined các thẻ
<sql>/<include>trực tiếp vào vị trí gọi. - Biên dịch
<foreach>thành hai vòng lặp duyệt tuần tự.
Intermediate Representation (IR)¶
MapperModel đóng vai trò là ranh giới trừu tượng độc lập giữa frontend parser và backend code emitter. IR mang đầy đủ thông tin về statement, kiểu tham số, cấu trúc kết quả và chiến lược đọc dòng.
JavaPoet Emitter¶
Hệ thống sử dụng JavaPoet để sinh ra 4 nhóm file Java:
| Emitter | File sinh ra | Nhiệm vụ |
|---|---|---|
MapperImplEmitter |
UserMapper$$Impl.java |
Lớp triển khai JDBC cho từng mapper interface |
RowReaderEmitter |
UserRow.java |
Lớp đọc dữ liệu ResultSet cho từng POJO kết quả |
RegistryEmitter |
LarkBatisMappers.java |
Static factory khởi tạo các mapper trong lần build |
SpringConfigurationEmitter |
LarkBatisMapperConfiguration.java |
Class @Configuration đăng ký Spring Bean |
Pha Runtime¶
Thư viện runtime larkbatis-runtime có kích thước nhỏ gọn:
| Thành phần | Vai trò |
|---|---|
LarkBatisSession |
Interface quản lý kết nối JDBC, giải phóng connection và dịch mã lỗi |
JdbcLarkBatisSession |
Triển khai cho standalone JDBC, tích hợp LarkBatisTx |
SpringLarkBatisSession |
Triển khai cho Spring Boot, tích hợp DataSourceUtils |
JdbcCodec |
Tập hợp các static helper đọc/ghi dữ liệu JDBC có xử lý null an toàn |
SqlFragment |
Cổng kiểm soát duy nhất cho các chuỗi SQL động |
LarkBatisSql |
Các hàm tiện ích hỗ trợ runtime (trackVariants, padPow2, sum) |
RowReader, StatementBinder |
Functional interfaces phục vụ các truy vấn động thủ công |
LarkBatisException |
Cây unchecked exception mang theo câu lệnh SQL gây lỗi |
Chiến lược kiểm chứng chất lượng¶
- Emitter Specification Tests: Đo lường mã nguồn sinh ra so với các class mẫu viết tay chuẩn mực.
- Snapshot Testing (Golden Master): Lưu trữ bản chụp mã nguồn sinh ra của kho mapper và kiểm tra sự sai khác (diff) qua từng lần commit.
- Differential Testing với MyBatis: Chạy song song cùng một mapper trên cả hai runtime (MyBatis và LarkBatis), so sánh từng chuỗi SQL sinh ra và từng tham số JDBC bind trên cùng một DataSource mô phỏng.
- CompileFailTest: Đảm bảo tất cả các quy tắc vi phạm cú pháp hoặc kiểu dữ liệu đều được
javacbắt chính xác và báo lỗi biên dịch rõ ràng.