Sequelize ORM方面已經做得很好了,不過現在有一個完全就是for TypeScript的ORM模組出現,就是TypeORM,TypeORM支援MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, WebSQL,而且支援平台眾多,如:Browser, Ionic, Cordova and Electron。(想多瞭解可以看這篇中文翻譯http://www.cnblogs.com/brookshi/p/6446155.html)
這還蠻吸引筆者的目光,當然要來點開TypeORM技能,不用擔心這不好學,花不到一小時改一下Sequelize ORM的寫法,換成TypeORM的寫法,整個就搞定了XDDDD。
USE [IronManNest]
GO
/****** Object: Table [dbo].[Users] Script Date: 2017/12/20 下午 10:47:14 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Users](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NULL,
[Age] [int] NULL,
CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
npm install --save @nestjs/typeorm mssql typeorm
'use strict';
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class Users {
//主鍵,SQL Server識別種子
@PrimaryGeneratedColumn()
ID: number;
@Column({ length: 50 })
Name: string;
@Column('int')
Age: number;
}
'use strict';
import { createConnection } from 'typeorm';
export const databaseProviders = [
{
provide: 'TypeORMInstance',
useFactory: async () => await createConnection({
type: 'mssql',
host: 'localhost',
port: 1433,
username: 'sa',
password: 'Aa123456',
database: 'IronManNest',
entities: [
__dirname + '/Users/*.entity{.ts,.js}'
]
})
}
]
entities屬性可以直接load進整個目錄的entity.ts,這還蠻方便的。
'use strict';
import { Users } from './users.entity';
import { Connection, Repository } from 'typeorm';
export const UsersProvider = {
provide: 'UsersRepository',
useFactory:(connection:Connection)=>connection.getRepository(Users),
inject:['TypeORMInstance']
}
'use strict';
import { Component, Inject } from '@nestjs/common';
import { Users } from './users.entity';
import { IUsers, IUsersService } from './interfaces/index';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
@Component()
export class UsersServices implements IUsersService {
constructor(
@InjectRepository(Users)
private readonly usersRepository: Repository<Users>) { }
public async findAll(): Promise<Array<Users>> {
return await this.usersRepository.find();
}
//findOne()可以加入各種option,以下示範常見的where
//注意findOne() 找到一筆就會立即return data,不會繼續往下找。
public async findOne(options: Object): Promise<Users | null> {
return await this.usersRepository.findOne(options);
}
//restful API很常用。
public async findById(ID): Promise<Users | null> {
return await this.usersRepository.findOneById(ID);
}
public async create(users: IUsers): Promise<Users> {
return await this.usersRepository.create(users);
}
public async update(ID: number, newValue: IUsers): Promise<Users | null> {
//先找出單筆資料
let user = await this.usersRepository.findOneById(ID);
//該筆資料不存在
if (!user.ID) {
console.error("user doesn't exist");
}
//呼叫user Model的方法
await this.usersRepository.updateById(ID, newValue);
return await this.usersRepository.findOneById(ID);
}
public async delete(ID: number): Promise<number> {
//成功會回傳1,失敗回傳0
await this.usersRepository.deleteById(ID);
let user = await this.usersRepository.findOneById(ID);
if (!user) {
//刪除成功
return 1;
}
else {
//刪除失敗
return 0;
}
}
}
比Sequelize寫法更為簡化也更直覺,像updateById(),可以傳入兩個參數,一個是ID,一個是新數據,內建就是部分更新,不用更新完整的資料。
整體我覺得TypeORM蠻不錯的,尤其是支援WebSQL,寫法也比Sequelize來得更好,不過生態還不成熟,Prod產品可能還不適合導入,但切入學習是很OK的易上手。
程式碼都在github