最近用NestJS作为Web主力框架,积极拥抱TypeScript。奈何找不到一款类似MyBatis那样可以直接写SQL的数据库工具,而NestJS通常用的数据库工具都是一些很自定义语法的ORM框架,用着蛮别扭。不得已自己通过TS的装饰器写了一个类似MyBatis的注解工具——SpeedSQL,现分享给大家。
看代码,以下是使用方法(后面有详解),是不是很眼熟啊:
import { Injectable } from '@nestjs/common';
import { Delete, Update, Param, ResultType, Insert } from 'speedsql';
import { UserDto } from './entity/user.dto';
import { ParamDto } from './entity/param.dto';
@Injectable()
export class AppService {
@Update('update user set age = #{age} where name = #{name}')
setUserAge(@Param('name') name: string, @Param('age') age: number): number {return;}
@Delete('delete from user where name = #{name}')
deleteUser(@Param('name') name: string): number {return;}
@ResultType(UserDto)
@Select('select `name`, `age` from `user` where `uid` = #{uid} and `name` = #{name}')
getRecords(paramDto: ParamDto): UserDto[] {return;}
@Insert('insert into user (name, age) value (#{name}, #{age})')
addUser(user: UserDto): number {return;}
}
@Param
, @ResultType
, @Select
, @Insert
, @Update
, @Delete
.
在你的package.json
里面加入依赖。
"dependencies": {
"speedsql": "latest"
}
db.provider.ts
import { createPool, Pool } from 'speedsql';
export const DbProviders = [
{
provide: 'SPEED_POOL',
useFactory: async (): Promise<Pool> => {
return await createPool({
host: 'localhost',
user: 'root',
port: 3306,
password: 'qwer1234',
database: 'test',
});
},
},
];
entity/param.dto.ts
export class ParamDto {
constructor(public name: string, public age: number) {}
}
entity/user.dto.ts
export class UserDto {
constructor(public name: string, public age: number) {}
}
app.mudule.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { SpeedService } from 'speedsql';
import { DbProviders } from './db.provider';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService, SpeedService, ...DbProviders],
})
export class AppModule {}
在你的Service类里面,使用Select,Insert,Update,Delete等注解。
app.service.ts
import { Injectable } from '@nestjs/common';
import { Delete, Update, Param, ResultType, Insert } from 'speedsql';
import { UserDto } from './entity/user.dto';
import { ParamDto } from './entity/param.dto';
@Injectable()
export class AppService {
@Update('update user set age = #{age} where name = #{name}')
setUserAge(@Param('name') name: string, @Param('age') age: number): number {return;}
@Delete('delete from user where name = #{name}')
deleteUser(@Param('name') name: string): number {return;}
@ResultType(UserDto)
@Select('select `name`, `age` from `user` where `uid` = #{uid} and `name` = #{name}')
getRecords(paramDto: ParamDto): UserDto[] {return;}
@Insert('insert into user (name, age) value (#{name}, #{age})')
addUser(user: UserDto): number {return;}
}
调用你的Service。
app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
import { ParamDto } from './entity/param.dto';
import { UserDto } from "./entity/create-cat.dto";
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
async getHello() {
await this.appService.setUserAge("zzz", 20);
return "hello world";
}
}
参数绑定在@Select
, @Insert
, @Update
, @Delete
增删查改注解上都可以使用。
参数绑定有两种方式:(不能两种同时用在一个操作上面)
我们可以通过建立一个实体类作为参数输入,这样挺面向对象的。
export class ParamDto {
constructor(public name: string, public age: number) {}
}
然后在查询上面定义实体类参数
import { ResultType, Select } from 'speedsql';
@ResultType(UserDto)
@Select('select `name`, `age` from `user` where `uid` = #{uid} and `name` = #{name}')
getRecords(paramDto: ParamDto): UserDto[]{return;}
最后是使用
const users: UserDto[] = await this.appService.getRecords(
new ParamDto("zzz", 10)
);
@Param
注解定义了绑定参数。
和MyBatis类似,SpeedSQL支持命名的方式绑定参数,而不像mysql2库那样只能通过问号占位符。
import { ResultType, Select, Param } from 'speedsql';
@ResultType(UserDto)
@Select(select `name`, `age` from `user` where `uid` = #{uid} and `name` = #{name}')
getRecords(@Param('uid') uid:number, @Param('name') name:string): UserDto[]{return;}
使用方式:
const users: UserDto[] = await this.appService.getRecords('zzz', 10);
SpeedSQL使用 @ResultType
来注解查询结果数据的实体类,它会返回一个该实体类的数组。
建立实体类:
export class UserDto {
constructor(public name: string, public age: number) {}
}
然后查询
import { ResultType, Select, Param } from 'speedsql';
@ResultType(UserDto)
@Select('select `name`, `age` from user where uid = #{uid} and name = #{name} ')
getRecords(@Param('uid') uid:number, @Param('name') name:string): UserDto[] {return;}
如果返回数据的字段名与实体类的参数对应不上,那么可以通过SQL语法的AS
来修正到一直。
import { ResultType, Select, Param } from 'speedsql';
@ResultType(UserDto)
@Select('select `realname` as `name`, `age` from user where uid = #{uid} and name = #{name} ')
getRecords(@Param('uid') uid:number, @Param('name') name:string): UserDto[] {return;}
@Insert
也支持绑定参数。
@Insert
返回一个数值,就是新增记录的ID,当然也可以忽略。
import { Insert } from 'speedsql';
@Insert('insert into user (name, age) value (#{name}, #{age})')
addUser(user: UserDto): number {return;}
@Update
和 @Delete
也支持绑定参数。
它们也会返回一个数值,指代的是影响行数,可忽略。
import { Delete, Update, Param } from 'speedsql';
@Update('update user set age = #{age} where name = #{name}')
setUserAge(@Param('name') name: string, @Param('age') age: number): number {return;}
@Delete('delete from user where name = #{name}')
deleteUser(@Param('name') name: string): number {return;}
有任何问题或指教,请提Issue:https://github.com/SpeedPHP/speedsql/issues