SQL 语句辅助生成器
sql_tool_kit 库提供了一系列派生宏(GenFields, GenSelect, GenValues, GenSet, GenWhere),
用于自动派生与 SQL 语句构建相关的 trait 实现。这些宏简化了根据结构体字段生成 SQL 语句的过程。
派生宏介绍
#[derive(GenFields)] 和 #[derive(GenSelect)]
这两个派生宏功能相似,主要区别在于命名。它们都处理字段及其上的 #[field(...)] 和 #[select(...)] 宏。
使用方法:StructName::generate_fields_clause() 和 StructName::generate_select_clause()
分别生成字段名称数组(如 ["field1", "field2", ...])。
应用场景:通过 .join(", ") 方法将返回的数组拼接为字符串,可用于 SQL 语句的 SELECT 和 INSERT 部分。
字段宏参数:
ignore- 忽略该字段rename- 字段重命名
导入
/// 导入 GenFields 和对应实现的 trait
use ;
/// 导入 GenSelect
use ;
使用
generate_fields_clause; // 输出: [“field1", "rename_field"]
generate_fields_clause; // 输出: [“field1", "rename_field"]
#[derive(GenValues)]
GenValues 生成用于 insert 语句中 values 部分,通过 StructName::generate_values_clause() 得到
["$1", "$2", ...]。
需要在结构上使用宏 #[config(...)] 来配置序列化的方式:
宏参数:
#[config(...)]: 设置全局配置。database- 指定生成的数据库类型,目前支持postgresqlmysqlmariadbsqlitemssqlindex- 指定开始的序列,仅postgresqlmssql上有效
#[value(...)] 接受的参数:
ignore- 忽略该字段index- 设置当前值的index,当设置了这个参数后,全局的 index 不会加一value- 直接替换当前的${index},当设置了这个参数后,全局的 index 不会加一- 例如:
#[value(value = "true")]=> ["$1", "true",...]
- 例如:
使用方式
use ;
generate_values_clause; // 输出:["$2", "20", "$1::bit(4)"]
#[derive(GenWhere)]
用于生成 SQL WHERE 语句部分。此宏依赖于 WhereAttributeMacro trait。
使用方法 where_data.generate_where_clause() 会返回一个字段和条件组成的字符串数组。
使用方法 where_data.generate_where_clause_with_index(index) 可以设置开始初始的 index 值。
使用方式
use ;
let data = WhereStruct ;
data.generate_where_clause; // 输出:["field1 = $1", "rename_field = $2", "field4 >= $3", "field5 not null", "field5 = $4::bit(4)", "field7 = $1"]
宏参数:
-
#[config(...)]: 设置全局配置。database: 指定数据库类型,影响占位符格式(支持 postgres, mysql, sqlite, mariadb, mssql)。index: 设置占位符的起始索引。ignore_none: 是否忽略Option::None值,默认为true。ignore_no_macro_where: 是否忽略没有#[r#where(...)]宏的字段,默认值为true, 为true时可配合GenSet宏使用。
-
#[r#where(...)]: 字段级别宏,用于自定义字段在WHERE语句中的表现。ignore: 忽略该字段。rename: 字段重命名,接受字符串类型。condition: 指定字段的比较条件,默认值为 ”=“,如果该值设置为空及 "", 会报错。condition_all: 应用于所有字段的通用条件,缺省值为"{name} {condition} {index}"。{name}: 字段名称或rename指定的名称。{condition}:condition参数指定的比较条件。如果condition_all。{index}:index参数指定的占位符索引。如果字段未设置index,则使用全局index。
ignore_none: 当字段为Option::None时是否忽略,接受布尔类型。value: 自定义字段的值,接受字符串类型。index: 自定义占位符序号(如果数据库支持),接受整型。
字段宏属性优先级:
ignore > ignore_none > condition_all > rename = condition = value > index
#[derive(GenSet)]
用于生成 SQL UPDATE 语句中的 SET 部分。它依赖于 SetAttributeMacro trait。
例如,update table_name set field1 = $1, field2 = $2 ... where ...
使用方法 update_data.generate_set_clause() 返回值类似于 ["field1 = $1", "field2 = $2", ...]。
为了方便接入后续的 where 语句,在 #[set(...)] 添加了 where 参数,它可以为 where 或 where = "..."
通过方法 generate_set_and_where_clause() 返回值一个元组 (["field1 = $1", ...], ["field5 = $5", "field6 > $6", ...]),
第一个为 set 的值,第二个为 where 的值
使用方式
use ;
let data = UpdateForm ;
let = data.generate_set_and_where_clause; // ["title = $1", "description = $2", "updated_at = now()"]
宏参数:
-
#[config(...)]: 设置一些配置。database: 指定数据库类型,影响占位符的格式(支持 mysql, postgres, sqlite, mariadb, mssql)。index: 设置占位符的起始索引。ignore_none: 是否忽略Option::None值,默认为true。ignore_no_macro_set: 默认忽略没有#[set(...)]宏的字段,为true时配合GenWhere宏使用。ignore_set_and_where: 当#[set(...)]存在where参数是,会忽略set值,默认为false
-
#[set(...)]: 字段级别的宏,用于自定义字段在生成的SET语句中的表现。ignore: 忽略该字段。r#where: 将该字段设置为 where,有多种使用方式。1.#[set(r#where)]#[set(r#where = "{field = {index}")]ignore_none: 当字段为Option::None时是否忽略,接受布尔类型。ignore_set: 在 set 上忽略该字段。rename: 字段重命名,接受字符串类型。condition: 当设置r#where时生效value: 自定义字段的值,接受字符串类型。index: 自定义占位符序号(如果数据库支持),接受整型。
宏的优先级:ignore > ignore_none > r#where = ignore_set > rename = value = condition > index
使用示例
insert 语句
update 更新语句
// ignore_no_macro_set = false, 设置不忽略没有设置 #[set()] 字段的结构
// index = 1, 设置 index 从 1 开始,默认值:如果不设置,index 则默认为 1
async
select 查询
use *;
async
delete 语句
后续可能的扩展
- 完整的 sql 语句生成
- 优化 sqlx 的绑定值步骤