從零開始實現一個簡單的rest風格服務器 (1) —— typescript 開發環境配置
從零開始實現一個簡單的rest風格服務器 (2) —— 集成 koa
從零開始實現一個簡單的rest風格服務器 (3) —— 自動編譯
終於寫到要連接數據庫啦,有些讀者可能等得有點不耐煩了。以前的幾篇寫的都是些花架子,只有連上數據庫,纔是能算是一個完整的 rest 風格服務器嘛。
這裏選用 sequelize 這個 ORM 框架來連接 postgresql 數據庫,當然你也可以直接用 sql 來操作數據庫。爲什麼會選擇 ORM 框架呢,還是爲了獲得 IDE 的更多提示嘛。文章有點長,我爲每一個步驟標上序號,大家耐心點。
1、安裝 sequelize,數據庫驅動 pg 以及與 typescript 相關的包
yarn add sequelize sequelize-typescript pg reflect-metadata
2、新建數據庫配置文件夾 conf 及 配置文件 db.conf.ts
/**
* @name: 數據庫配置
* @param : undefined
* @return : undefined
*/
export const dbConfig = {
host: 'localhost',
database: 'demo',
dialect: 'postgres',
username: 'postgres',
password: '123456'
}
3、連接數據庫,新建文件夾 db 及 配置文件 db.ts
/*
* @Description: 數據庫連接類
*/
import * as path from 'path'
import { Sequelize } from 'sequelize-typescript'
import { dbConfig } from '../conf/db.conf'
class DbContext {
private sequelize: Sequelize
constructor() {
const { host, database, dialect, username, password } = dbConfig
this.sequelize = new Sequelize({
host: host,
database: database,
dialect: dialect,
username: username,
password: password,
define: {
timestamps: true, //開啓時間戳 create_at delete_at update_at
paranoid: true, //開啓假刪除
underscored: true, //下劃線
charset: 'utf8',
freezeTableName: true //固定表名爲單數 默認表名是xxxs
},
pool: {
max: 10,
min: 0,
acquire: 30000,
idle: 10000
},
timezone: '+08:00',
modelPaths: [path.resolve(__dirname, `./models`)]
})
this.sequelize.sync()
}
init(): Boolean {
return !!this.sequelize
}
getInstance(): Sequelize {
return this.sequelize
}
isInit(): Boolean {
return !!this.sequelize
}
}
export const dbContext = new DbContext()
4、數據庫實體類,新建文件夾 models 及文件 user.ts
/*
* @Description: 數據庫實體類
*/
import { Table, Column, Model } from 'sequelize-typescript'
@Table({
tableName: 'user'
})
export default class User extends Model<User> {
@Column({
comment: '自增ID',
primaryKey: true,
autoIncrement: true,
})
id: number
@Column
username: string
@Column
password: string
}
5、編寫業務邏輯接口,在 src 目錄下新建文件夾 dao、service,在 dao 目錄下新建 UserDao.ts 及子目錄 impl,在 service 目錄下新建 UserService.ts 及子目錄 impl
/*
* @Description: 數據庫表操作基礎接口 UserDao.ts
*/
export interface UserDao {
/**
* @name: 查詢
* @param :
* @return : Array<User>
*/
findAll();
/**
* @name: 查詢
* @param :
* @return : Array<User>
*/
findByName(username:string);
/**
* @name: 新增
* @param : undefined
* @return : undefined
*/
create(entity:UserInfo);
/**
* @name: 刪除
* @param : undefined
* @return : undefined
*/
delete(id:number);
}
export interface UserInfo {
username:string;
password:string;
}
==================================================
/*
* @Description: service接口 UserService.ts
* @version:
*/
export interface UserService{
/**
* @name: 查詢
* @param : undefined
* @return : undefined
*/
findAll();
/**
* @name: 查詢
* @param : undefined
* @return : undefined
*/
findByName(username:string);
/**
* @name: 新增
* @param : undefined
* @return : undefined
*/
create(username:string,password:string);
/**
* @name: 刪除
* @param : undefined
* @return : undefined
*/
delete(id:String);
}
6、編寫業務邏輯實現類 UserDaoImpl.ts、UserServiceImpl.ts
/*
* @Description: 數據庫表操作基礎實現類 UserDaoImpl.ts
*/
import { dbContext } from '../../db/db'
import { UserDao, UserInfo } from '../UserDao';
import User from '../../db/models/user';
export class UserDaoImpl implements UserDao{
constructor(){
dbContext.init();
}
/**
* @name: 查詢
* @param : undefined
* @return : undefined
*/
public async findAll(){
const results = await User.findAll({
raw: true
})
return results;
}
/**
* @name: 查詢
* @param : undefined
* @return : undefined
*/
public async findByName(username:string){
const results = await User.findOne({
where:{
username:username
}
})
return results;
}
/**
* @name: 新增
* @param : entity
* @return : undefined
*/
public async create(entity:UserInfo) {
const results = await User.create(entity)
return results;
}
/**
* @name: 刪除
* @param : undefined
* @return : undefined
*/
public async delete(id: number) {
const results = await User.destroy({
where:{
id:{
$eq:id
}
}
});
return results;
}
}
========================================================
/*
* @Description: service實現類 UserServiceImpl.ts
*/
import { UserService } from "../UserService";
import { UserDao } from "../../dao/UserDao";
import { UserDaoImpl } from "../../dao/impl/UserDaoImpl";
export class UserServiceImpl implements UserService{
private userDao:UserDao;
constructor(){
this.userDao = new UserDaoImpl();
}
/**
* @name: 查詢
* @param : undefined
* @return : undefined
*/
public findAll() {
return this.userDao.findAll();
}
/**
* @name: 查詢
* @param : undefined
* @return : undefined
*/
public findByName(username:string) {
return this.userDao.findByName(username);
}
/**
* @name: 新增
* @param : entity
* @return : undefined
*/
public create(username: string, password: string) {
return this.userDao.create({username,password});
}
/**
* @name: 刪除
* @param : undefined
* @return : undefined
*/
public delete(id: String) {
return this.userDao.delete(~~id);
}
}
7、查看成果,修改 router/index.ts
/*
* @Description: 後臺路由組件
* @version: 0.1.0
*/
import * as Router from 'koa-router';
import { UserInfo } from '../dao/UserDao';
import { UserService } from '../service/UserService';
import { UserServiceImpl } from '../service/impl/UserServiceImpl';
const router = new Router();
const userService:UserService =new UserServiceImpl();
router.get('/*', async (ctx) => {
ctx.body = await userService.findAll();
})
export { router }
8、瀏覽器輸入 http://localhost:8080
數據庫連接成功!!!
目錄結構: