TypeORM
Install TypeORM Plugin
npm install @summer-js/typeorm
npm install mysql2
Add DataSource Config
in default.config.ts
import { TypeORMConfig } from '@summer-js/typeorm'
export const TYPEORM_CONFIG: TypeORMConfig = {
DATA_SOURCE: {
type: 'mysql',
host: 'localhost',
database: 'dbname',
username: 'root',
password: 'root'
// you don't need to add entities/migrations, summer will auto collect them
}
}
Summer TypeORM plugin can auto collect entities and migrations
Create an Entity
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'
@Entity()
export class Todo {
@PrimaryGeneratedColumn()
id: number
@Column()
content: string
@Column()
isDone: boolean
}
Do CRUD by Repository
Repository<T, DataSourceName?: string = FirstDataSource> is a generic injectable class.
The Repository instance connect to the first DataSource by default, however, you can set the second param to specify another DataSource.
import { Service } from '@summer-js/summer'
import { Repository } from '@summer-js/typeorm'
import { Todo } from '../entity/Todo'
@Service
export class TodoService {
todoRepository: Repository<Todo>
async getTodos() {
return await this.todoRepository.find()
}
async addTodo() {
const todo = new Todo()
return await this.todoRepository.save(todo)
}
}
Get Repository From DataSouse
You can also get repository by calling getDataSource("DATA_SOURCE_NAME").getRepository(entity).
The inject instance way mentions before looks more elegant, but only works in class. getRepository() can be called everywhere.
import { EntityTarget } from 'typeorm'
import { getDataSource } from '@summer-js/typeorm'
export const getRepository = <T>(entity: EntityTarget<T>) => {
return getDataSource('DATA_SOURCE').getRepository(entity)
}
import { Service } from '@summer-js/summer'
import { getRepository } from '../DataSource.ts'
import { Todo } from '../entity/Todo'
@Service
export class TodoService {
todoRepository = getRepository(Todo)
}
Transaction
Summer provide Transaction decorator for DB transaction, the following code will not save todo data because there is an Error in Transaction scope.
import { Service } from '@summer-js/summer'
import { Repository, Transaction, transaction} from '@summer-js/typeorm'
import { Todo } from '../entity/Todo'
@Service
export class TodoService {
todoRepository: Repository<Todo>
// using decorator
@Transaction
async addTodo1() {
let todo = new Todo()
todo.id = 1
todo.content = 'coding'
todo.isDone = false
await this.todoRepository.save(todo)
throw new Error('error')
}
// you can also use transaction function
async addTodo2() {
await transaction(async ()=>{
let todo = new Todo()
todo.id = 1
todo.content = 'coding'
todo.isDone = false
await this.todoRepository.save(todo)
throw new Error('error')
})
}
}
DB Migration
install ts-node
npm install ts-node --save-dev
Create a file named ormconfig.ts
import { DataSource } from 'typeorm'
import { DBNamingStrategy } from '@summer-js/typeorm'
export default new DataSource({
type: 'mysql',
host: 'localhost',
database: 'summer-db',
username: 'root',
password: 'root',
namingStrategy: new DBNamingStrategy(),
entities: ['./src/entity/**/*.ts']
})
Add migration generation script in package.json
{
....
"scripts": {
"generate-migration": "typeorm-ts-node-commonjs migration:generate src/migrations/migration -d ormconfig.ts -p"
},
....
}
Run the script, this will help to generate a new migration version in src/migrations/
npm run generate-migration
Run migration before the server start.
import { getDataSource } from '@summer-js/typeorm'
import { summerStart, handler, Logger } from '@summer-js/summer'
import './auto-imports'
export { handler }
const runMigrations = async () => {
const output = await getDataSource('DATA_SOURCE').runMigrations()
output.forEach((m) => {
Logger.info('Run migration: ' + m.name)
})
}
summerStart({
async before(config) {
await runMigrations()
},
after(config) {}
})
For more usage please check TypeORM official DOC