前言
昨天發現的框架,看了下官方文件,號稱Nodejs
版本的spring(java)
開發模式有ng6
既視感,這對有ng
經驗的小夥伴來說,莫名的親切..
適合嚐嚐鮮,目前有1W+ star
, 上正式線我覺得等version 6
會穩定些,
這個系列我會以一個真實專案的開發進展作為基礎,一邊爬坑一邊水文;
後臺大佬用的PHP
,我打算用空閒時間拿nestjs
重寫我們後臺管理系統提供的那部分介面
其他就不多說了
-
2018-12-7:
mysql 8
連結報認證問題遠端資料庫是
5.7
, 備份下來切換到本地的mysql8
,因為mysql 8
升級了安全機制,沒法類似以前那樣直連.我們需要修改下,使其支援
# 登入/切換資料庫/用新的機制更新我們的密碼/ 重新整理許可權 -> mysql -u root -> use mysql -> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456'; -> flush privileges; 複製程式碼
效果圖
失敗
失敗的原因有那麼幾個;
- 資料庫的配置資訊跟實際要連結的資料庫資料不一致(比如資料庫名字,比如使用者名稱密碼)
- 隧道轉發的埠給本地其他服務佔用了,比如mysql本地啟動的(預設3306)
- 這時候要麼改埠對映,要麼關閉本地資料庫
mysql 8+
需要修改特權認證ts
語法錯誤
成功
程式碼
db.ts(src/config)
溫馨提示: 若是要用__dirname
,確保配置檔案在根目錄,否則請改用相對路徑,不然會找不到實體
synchronize
是同步,會自動同步到資料庫,比如建表什麼的(根據實體)
import { join } from 'path';
const EntityRecursivePath = join('..', '/**/*.entity{.ts,.js}');
export const MySqlConfig: any = {
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: '!=basestagging**',
database: 'shengxi_v2',
entities: [EntityRecursivePath],
synchronize: true,
};
複製程式碼
app.module.ts
UsersModule 裡面寫了對應的服務,實體的關聯
import { Module, NestModule, MiddlewareFunction } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
// 使用者模組,註冊,登入,更新個人資訊
import { UsersModule } from './modules/users/users.module';
// 資料庫ORM
import { TypeOrmModule } from '@nestjs/typeorm';
import { MySqlConfig } from './config/db';
@Module({
imports: [TypeOrmModule.forRoot(MySqlConfig), UsersModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule implements NestModule {
// consumer 這裡可以掛在中介軟體什麼的
configure(consumer: MiddlewareFunction): void {
consumer
.apply(null)
.with('AppModule')
.forRoutes('/');
}
}
複製程式碼
users.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
// entity裝飾器提供一個options可以配置關聯的表名,引擎等等,具體看她的interface
// 不提供name的話,,類名就是表名了
@Entity({
name: 'sx_admin',
})
export class Users {
@PrimaryGeneratedColumn() id: number;
// 使用者名稱
@Column('varchar', { length: 100 })
admin_name: string;
// 使用者密碼
@Column('varchar', { length: 255 }) admin_passwd: string;
// 建立時間
@Column('timestamp') created_at: number;
// 更新時間
@Column('timestamp') updated_at: number;
// 是否啟用
@Column('int') admin_status: number;
}
複製程式碼
剩下的姿勢,就在services
裡面注入實體和orm
的Repository
;
再到controller
注入服務呼叫即可...返回的是Promise
要點提示及溫馨提示
SSH隧道轉發(SSH Tunnel)
遠端資料庫我們一般不暴露外接埠直連,安全隱患太高;
一般選擇走ssh 隧道
(很常用的接入方式),
通過ssh
登入認證伺服器,再轉發本地的埠到遠端埠,達到資料打通的姿勢
ssh
命令轉發
ssh的命令解釋(官方手冊): 英文,寫的很詳細;
我們主要用了以下幾個引數
-L
: 埠轉發
-C
: 壓縮傳送資料
-f
: 後臺執行
-N
: 不執行遠端命令
常規alias
# 這條命令會在後臺執行
alias mstunnel=ssh -L 3306:localhost:3306 root@xxx.xx.xx.xx -NCf
# 若是遠端轉遠端 用-R 替換-L
複製程式碼
傳遞引數的alias
shell
的alias
不支援引數的傳遞,要傳遞只能寫成function
再賦值到alias
可以設定多個佔位符,依次遞增(比如埠,域名都變成外部傳入什麼的,看自己喜好了)
# ssh tunnel
function sst(){
ssh -L 3306:localhost:3306 root@$1 -NCf
}
alias sst=sst
複製程式碼
關閉會話(ssh tunnel)
分步進行的依賴lsof
,kill
- 找到對應的程式PID ,
lsof -i tcp:22
(查詢誰用著22的埠,ssh tunnel
預設走tcp
) kill -9 pid
, -9 是終止程式
若是要一步到位的,就要藉助幾個命令一起了,awk
,xargs
以及管道(|
)
# 意思就是
# 查詢TCP且埠22的程式
# 輸出第二行的第二列(第一行是列名)
# stdin 轉為arguments 給kill
lsof -i tcp:22 | awk 'NR==2 { print $2}' |xargs kill -9
# 當然也可以當做一個表示式來寫
kill -9 $(lsof -i tcp:22 | awk 'NR==2 { print $2}')
# 若是要同時關閉多個引用該埠的程式 , NR!=1 即可 , kill 支援殺多程式
# 有傳遞引數的alias記得用function 來實現!!!
複製程式碼
若是ssh沒有配置定時傳送訊號,一段時間後會自動停止會話(packet_write_wait:
);
此時要麼去配置,要麼我們改寫下alias
, 用-o ServerAliveInterval=60
來保持連線的連線這
ssh -o ServerAliveInterval=60 -L 3306:localhost:3306 root@xxxx.xxx.xxx -NCf
複製程式碼
走IPV6
就帶上 -6
- npm模組的姿勢
可以通過安裝ssh2,Promise
成功後再去連結資料庫;
不考慮用這種,因為實際伺服器都是內部直連的,隧道我們也在開發過程用的比較多
總結
語法轉義
- 若是使用
js
檔案
目前的版本,還是要考慮commonjs
的寫法,為什麼這樣說,
我把資料庫連結的配置檔案分離出來,不能用export default
匯入的時候也不能用...(rest)
解耦的方式. 不然會報語法錯誤
ts
檔案
可以任性使用ES6+
語法
有不對之處請留言,會及時修正,謝謝閱讀