闲话少说,直接开启第二弹 相较于昨日,更改了一些bug,之前都是在公司写的,回家懒得测试 今天更新了一些bug,然后完成了自动填充注解 话不多b,直接看代码
export function fieldFill(type: ("DEFAULT" | "INSERT" | "UPDATE" | "INSERT_UPDATE")) {
return (target: any, name: string) => {
let className = "";
store.classNameArr.forEach(item => {
if (item[target.constructor.name]) {
className = item[target.constructor.name];
}
})
className = className || target.constructor.name; //存储的是表名,如果有自定义表名就是自定义表名,没有就是类名
let a = false;
store.classFieldFill.forEach(item => {
const key = Object.keys(item)[0]; //User
if (className === key) {
a = true;
}
})
if (!a) {
const strObj = JSON.parse(`{"${className}":{
"defaults":[],
"insert":[],
"update":[],
"insert_update":[]
}}`)
store.classFieldFill.push(strObj)// 如果没有就初始化
}
type A = "defaults" | "insert" | "update" | "insert_update"
let types: A = (type.toLocaleLowerCase() as A);
store.classFieldObj[className]?.forEach(item => {
if (item[name]?.alias) {
name = item[name].alias
}
})
store.classFieldFill.forEach(item => {
if (item[className]) {
if (types.toString() === "default") {
types = "defaults";
}
item[className][types]?.push(name)
}
})
}
}
分为了四种模式,分别是default无作为,insert插入时填充,update更新时填充以及insert_update,插入或者更新时都填充
在这要说一个注意点
@fieldFill():要在@tableField()前使用,否则会导致字段名匹配不正确导致sql执行失败
这个是因为装饰器是洋葱模型,由外往内进入,由内往外执行,如果顺序不对的话,在指定了映射字段时,因为顺序问题,执行fieldFill()逻辑时获取不到映射字段导致更新失败 自动填充的使用方式:
const db = createDb({
localhost: "localhost",
root: "root",
password: "123456",
database: "tb_shudong",
})
初始化mysql实例
const queryWrapper = db.createWrapper(Demo); //实例化以便使用crud方法
db.initAutoWire(Demo);//返回值是三个函数,分别对应insert update insert_update
- autoWireInsert({[propname:string]:Function}):插入时自动填充的逻辑
- autoWireUpdate():更新时
- autoWireUpAndIn():插入和更新时
传递参数的形式:{键:函数},函数必须有返回值,返回值作为列的值进行填充
键的形式,比如说类属性叫做addTime,那么键可以是addTime add_time或者@tableField指定
/**
* 自动建表 ok
* insertInfo ok
* deleteList ok 逻辑删除 ok
* deleteById ok 逻辑删除 ok
* getAll ok 逻辑删除 ok
* getById ok 逻辑删除 ok
* selectList ok 逻辑删除 ok
* page ok
* updateById ok 逻辑删除 ok
* update ok 逻辑删除 ok
* @fieldFill():要在@tableField()前使用,否则会导致字段名匹配不正确导致sql执行失败
*/
这是目前的功能,今天下午也已经通过测试
逻辑删除的话就是在方法内判断了一下罢了,简单贴一个栗子
async updateById(arr: T, id: string | number) {
const update = this.objs.update;
update.forEach((item: T) => {
for (let i in item) {
arr[i] = item[i]
}
})
const update2 = this.objs.insert_update;
update2.forEach((item: T) => {
for (let i in item) {
arr[i] = item[i]
}
})
const { valueArr, updateStr } = this.getKeyAndValue(arr);
let query = `update ?? set ${updateStr} where ${this.tableId}=?`;
const arrss = [this.table, ...valueArr, id];
if (this.options.logic_delete_field) {
query += ` and ${this.options.logic_delete_field}!=?`;
arrss.push(this.options.logic_delete_value)
}
const res = await this.sql(query, arrss);
return res;
}
主要就是前边的update以及update2的处理,但是这样的话自定义sql并不会应用自动填充,这也是后续要实现的功能,今天确实没有做很多,主要都是在改bug了,毕竟一次写完也没测试坑还是蛮多的heheheh
interface Options {
localhost: string;
root: string;
password: string;
database: string;
tb_prefix?: string; //表前缀
logic_delete_field?: string; //逻辑删除字段
logic_delete_value?: string | number; //删除时的值
logic_not_delete_value?: string | number; //没有删除时的值
}
贴一下初始化参数吧,主要是增加了后三个参数,然后改了一下两个类,初始化的类更专注于初始化,提供方法的类更注重方法,尽量让两个分工明确
具体代码就不贴了,毕竟改动蛮多了看着有点水哈哈哈哈
今天就说这么多,祝大家天天开心