docs: README 模型字段去掉下划线前缀,DbContext 示例改用 prop 声明
This commit is contained in:
@@ -28,13 +28,13 @@ import simcu::orm.*
|
|||||||
|
|
||||||
@Table["users"] // 指定表名(不写则用类简单名)
|
@Table["users"] // 指定表名(不写则用类简单名)
|
||||||
public class User {
|
public class User {
|
||||||
public var _id: Int64 = 0 // 整型 _id → 主键 + 数据库自增
|
public var id: Int64 = 0 // 整型 id → 主键 + 数据库自增
|
||||||
public var _name: String = "" // 列名 name
|
public var name: String = "" // 列名 name
|
||||||
@Column["full_name"]
|
@Column["full_name"]
|
||||||
public var _alias: String = "" // 注解覆盖列名
|
public var alias: String = "" // 注解覆盖列名
|
||||||
@Ignore
|
@Ignore
|
||||||
public var _temp: String = "" // 不映射
|
public var temp: String = "" // 不映射
|
||||||
public var _age: Int32 = 0
|
public var age: Int32 = 0
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -50,8 +50,8 @@ import simcu::orm.macros.*
|
|||||||
|
|
||||||
@DbContext
|
@DbContext
|
||||||
public class AppDbContext {
|
public class AppDbContext {
|
||||||
public var users: DbSet<User>
|
prop users: DbSet<User>
|
||||||
public var orders: DbSet<Order>
|
prop orders: DbSet<Order>
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
@@ -60,19 +60,19 @@ main() {
|
|||||||
|
|
||||||
// 2. 增
|
// 2. 增
|
||||||
let user = User()
|
let user = User()
|
||||||
user._name = "alice"
|
user.name = "alice"
|
||||||
db.users.add(user) // 入队 INSERT
|
db.users.add(user) // 入队 INSERT
|
||||||
db.saveChanges() // 事务内执行,回读自增主键到 user._id
|
db.saveChanges() // 事务内执行,回读自增主键到 user.id
|
||||||
|
|
||||||
// 3. 改
|
// 3. 改
|
||||||
user._age = 30
|
user.age = 30
|
||||||
db.users.update(user) // 入队 UPDATE(全部非主键列)
|
db.users.update(user) // 入队 UPDATE(全部非主键列)
|
||||||
db.saveChanges()
|
db.saveChanges()
|
||||||
|
|
||||||
// 4. 查
|
// 4. 查
|
||||||
let list = db.users.query()
|
let list = db.users.query()
|
||||||
.filter("_age", ">", Int64(18)) // 属性名/列名自动映射列名
|
.filter("age", ">", Int64(18)) // 属性名/列名自动映射列名
|
||||||
.orderBy("_name")
|
.orderBy("name")
|
||||||
.skip(0).take(10)
|
.skip(0).take(10)
|
||||||
.toList() // ArrayList<User>
|
.toList() // ArrayList<User>
|
||||||
let one = db.users.find(Int64(1)) // ?User,按主键
|
let one = db.users.find(Int64(1)) // ?User,按主键
|
||||||
@@ -84,7 +84,7 @@ main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> 不用宏时手动继承 `DbContext` 等价写法:补 `public init(...) { super(...) }` 构造,每个 DbSet 写成 `public prop users: DbSet<User> { get() { this.set<User>() } }`,并 override `migrations()`。宏就是把这几个样板步骤自动做完(详见「模块说明 3」)。
|
> 不用宏时手动继承 `DbContext` 等价写法:补 `public init(...) { super(...) }` 构造,每个 DbSet 声明为 `public prop users: DbSet<User> { get() { this.set<User>() } }`,并 override `migrations()`。宏就是把这几个样板步骤自动做完(详见「模块说明 3」)。
|
||||||
|
|
||||||
### 3. 迁移
|
### 3. 迁移
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ main() {
|
|||||||
|
|
||||||
// 2. 模型变更后:旧模型快照(上次的 models) vs 新模型 → 增量迁移(表/列增删改)
|
// 2. 模型变更后:旧模型快照(上次的 models) vs 新模型 → 增量迁移(表/列增删改)
|
||||||
let models2 = ArrayList<EntityModel>()
|
let models2 = ArrayList<EntityModel>()
|
||||||
models2.add(ModelCache.get<User>()) // 假设 User 新增了 _age 字段
|
models2.add(ModelCache.get<User>()) // 假设 User 新增了 age 字段
|
||||||
models2.add(ModelCache.get<Product>())
|
models2.add(ModelCache.get<Product>())
|
||||||
let m1 = gen.diff("20250801000000_AddAge", "新增 age 列", models, models2)
|
let m1 = gen.diff("20250801000000_AddAge", "新增 age 列", models, models2)
|
||||||
Migrator(datasource).migrate([m1]) // 旧模型列表 models 由调用方保存,充当快照
|
Migrator(datasource).migrate([m1]) // 旧模型列表 models 由调用方保存,充当快照
|
||||||
@@ -187,8 +187,8 @@ import myapp.migrations.* // 注册文件所在子包(仅 import 触
|
|||||||
|
|
||||||
@DbContext
|
@DbContext
|
||||||
public class MyDbContext {
|
public class MyDbContext {
|
||||||
public var users: DbSet<User>
|
prop users: DbSet<User>
|
||||||
public var orders: DbSet<Order>
|
prop orders: DbSet<Order>
|
||||||
}
|
}
|
||||||
|
|
||||||
main(args: Array<String>) {
|
main(args: Array<String>) {
|
||||||
@@ -257,8 +257,8 @@ orm-cj/
|
|||||||
|------|-----------|------|------|
|
|------|-----------|------|------|
|
||||||
| `@Table["users"]` | `[Table("users")]` | 类 | 指定表名 |
|
| `@Table["users"]` | `[Table("users")]` | 类 | 指定表名 |
|
||||||
| `@Column["full_name"]` | `[Column("full_name")]` | 字段 | 指定列名 |
|
| `@Column["full_name"]` | `[Column("full_name")]` | 字段 | 指定列名 |
|
||||||
| `@Key` | `[Key]` | 字段 | 标记主键(字段名 `_id` 自动为主键) |
|
| `@Key` | `[Key]` | 字段 | 标记主键(字段名 `id` / `_id` 自动为主键) |
|
||||||
| `@AutoIncrement` | `[DatabaseGenerated(Identity)]` | 字段 | 整型主键自增(整型 `_id` 默认自增) |
|
| `@AutoIncrement` | `[DatabaseGenerated(Identity)]` | 字段 | 整型主键自增(整型 `id` 默认自增) |
|
||||||
| `@Ignore` | `[NotMapped]` | 字段 | 不映射该字段 |
|
| `@Ignore` | `[NotMapped]` | 字段 | 不映射该字段 |
|
||||||
| `@Required` | `[Required]` | 字段 | 非空列(仅影响建表 DDL) |
|
| `@Required` | `[Required]` | 字段 | 非空列(仅影响建表 DDL) |
|
||||||
| `@MaxLength[100]` | `[MaxLength(100)]` | 字段 | 字符串列最大长度(仅影响建表 DDL) |
|
| `@MaxLength[100]` | `[MaxLength(100)]` | 字段 | 字符串列最大长度(仅影响建表 DDL) |
|
||||||
@@ -266,9 +266,9 @@ orm-cj/
|
|||||||
### 2. 模型映射约定(对齐 EF Core 数据模型)
|
### 2. 模型映射约定(对齐 EF Core 数据模型)
|
||||||
|
|
||||||
- **表名**:`@Table` 优先,否则类简单名;
|
- **表名**:`@Table` 优先,否则类简单名;
|
||||||
- **列名**:`@Column` 优先,否则按 `ColumnNamingPolicy`(默认 `StripUnderscore`:`_id` → `id`;可切换 `SnakeCase`:`_userName` → `user_name`;`Keep` 原样);
|
- **列名**:`@Column` 优先,否则按 `ColumnNamingPolicy`(默认 `StripUnderscore`:`_id` → `id`、`id` 原样;可切换 `SnakeCase`:`userName` → `user_name`;`Keep` 原样);
|
||||||
- **主键**:`@Key` 标注,或字段名 `_id`;v1 仅支持**单主键**;
|
- **主键**:`@Key` 标注,或字段名 `_id` / `id`;v1 仅支持**单主键**;
|
||||||
- **自增**:`@AutoIncrement`,或整型(Int8-64)`_id` 主键默认自增;INSERT 跳过该列并通过 `RETURNING` 回读;
|
- **自增**:`@AutoIncrement`,或整型(Int8-64)`id` 主键默认自增;INSERT 跳过该列并通过 `RETURNING` 回读;
|
||||||
- **客户端生成主键**:`String` 主键默认客户端生成(`GuidUtil`:时间戳 + 自增序号 hex),INSERT 时为空自动生成;
|
- **客户端生成主键**:`String` 主键默认客户端生成(`GuidUtil`:时间戳 + 自增序号 hex),INSERT 时为空自动生成;
|
||||||
- **实体要求**:字段必须是 `public var` 标量类型,且提供无参 `public init()`。
|
- **实体要求**:字段必须是 `public var` 标量类型,且提供无参 `public init()`。
|
||||||
|
|
||||||
@@ -276,7 +276,7 @@ orm-cj/
|
|||||||
|
|
||||||
### 3. DbContext / DbSet(对齐 EF Core)
|
### 3. DbContext / DbSet(对齐 EF Core)
|
||||||
|
|
||||||
**推荐:`@DbContext` 宏**。把 `DbSet` 声明为属性(字段也行),宏自动补继承/构造/注入/`migrations()`:
|
**推荐:`@DbContext` 宏**。把 `DbSet` 声明为 `prop`,宏自动补继承/构造/注入/`migrations()`:
|
||||||
|
|
||||||
```cangjie
|
```cangjie
|
||||||
import simcu::orm.*
|
import simcu::orm.*
|
||||||
@@ -286,8 +286,8 @@ import std.collection.* // migrations() 签名需要 ArrayList
|
|||||||
|
|
||||||
@DbContext
|
@DbContext
|
||||||
public class AppDbContext {
|
public class AppDbContext {
|
||||||
public var users: DbSet<User>
|
prop users: DbSet<User>
|
||||||
public var orders: DbSet<Order>
|
prop orders: DbSet<Order>
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用法(宏生成 (driverName, connStr) 构造)
|
// 用法(宏生成 (driverName, connStr) 构造)
|
||||||
@@ -344,12 +344,12 @@ public class AppDbContext <: DbContext {
|
|||||||
```cangjie
|
```cangjie
|
||||||
let qb = db.users.query() // 宏方式直接 db.users;等价 db.set<User>().query()
|
let qb = db.users.query() // 宏方式直接 db.users;等价 db.set<User>().query()
|
||||||
|
|
||||||
qb.filter("_age", ">", Int64(18)) // (属性名, 操作符, 值):自动映射列名
|
qb.filter("age", ">", Int64(18)) // (属性名, 操作符, 值):自动映射列名
|
||||||
let ps = ArrayList<Any>() // (SQL 片段, 参数):按 ? 顺序,写原始列名
|
let ps = ArrayList<Any>() // (SQL 片段, 参数):按 ? 顺序,写原始列名
|
||||||
ps.add(Int64(18))
|
ps.add(Int64(18))
|
||||||
ps.add(true)
|
ps.add(true)
|
||||||
qb.filter("age > ? AND active = ?", ps)
|
qb.filter("age > ? AND active = ?", ps)
|
||||||
qb.orderBy("_name").orderByDesc("_age") // 排序
|
qb.orderBy("name").orderByDesc("age") // 排序
|
||||||
qb.skip(10).take(5) // 分页(LIMIT/OFFSET)
|
qb.skip(10).take(5) // 分页(LIMIT/OFFSET)
|
||||||
qb.toList() // ArrayList<User>
|
qb.toList() // ArrayList<User>
|
||||||
qb.first() // ?User
|
qb.first() // ?User
|
||||||
@@ -379,7 +379,7 @@ cjpm test # 纯逻辑单元测试(模型映射/SQL 生成/DDL 生成/QueryB
|
|||||||
|
|
||||||
## 已知限制(v1)
|
## 已知限制(v1)
|
||||||
|
|
||||||
- **cjc 1.1.3 编译器缺陷(重要)**:类上带 `@Table[...]` 注解时,若成员变量带 ≥2 个注解且用 `= ""` 做空字符串初始化(如 `@Required @MaxLength[100] public var _x: String = ""`),编译报 `expected expression after '=', found '<EOF>'`。规避:默认值改用 `= String()` 或直接省略初始化器。`orm-cj` 包内代码与 e2e 示例均按此规避写法;
|
- **cjc 1.1.3 编译器缺陷(重要)**:类上带 `@Table[...]` 注解时,若成员变量带 ≥2 个注解且用 `= ""` 做空字符串初始化(如 `@Required @MaxLength[100] public var x: String = ""`),编译报 `expected expression after '=', found '<EOF>'`。规避:默认值改用 `= String()` 或直接省略初始化器。`orm-cj` 包内代码与 e2e 示例均按此规避写法;
|
||||||
- **仅单主键**;不支持复合主键;
|
- **仅单主键**;不支持复合主键;
|
||||||
- **不支持 Option 字段**(`?String` 等请改用具体标量类型)与**父类字段**(不扫描继承字段);
|
- **不支持 Option 字段**(`?String` 等请改用具体标量类型)与**父类字段**(不扫描继承字段);
|
||||||
- 不支持导航属性 / 延迟加载 / 级联删除(对齐 EF Core 这些能力属于 v2+);
|
- 不支持导航属性 / 延迟加载 / 级联删除(对齐 EF Core 这些能力属于 v2+);
|
||||||
|
|||||||
Reference in New Issue
Block a user