likes
comments
collection
share

typeorm +QueryBuilder 实战

作者站长头像
站长
· 阅读数 44

在实际开发过程中,会遇到各种各样的语法问题,我个人偏向于 从 场景 + 语法 实现,让你更快的上手typeorm中的 QueryBuilder

内容会持续更新.... 如果你有遇到什么问题,可以持续在下方留言

包版本说明

截止2023-05-23 包都是最新版本

node v18.15.0 (14+ 应该都没问题)
"mysql2": "^3.3.1"
"typeorm": "^0.3.16"
"express": "^4.18.2"

mysql 数据库版本:8.0.32

官网创建 Query Builder 的方式有5种, 选择自己合适的就行; 我个人偏向于使用 基于 repository 的 创建query builder

实战案例

以下都是js版本的实现,TypeScript版本的差不多

表达 is not null

场景: 我想查询一个表里面,某个字段不为null的数据

SELECT * FROM repository as r where r.service_name IS NOT NULL

使用 typeorm 实现

/entity/repository.js 实体

import { EntitySchema } from 'typeorm'

export default new EntitySchema({
  name: 'Repository',
  columns: {
    id: {
      primary: true,
      type: 'int',
      generated: true,
      comment: '仓库id'
    },

    name: {
      type: 'varchar',
      length: 100
    },
    description: {
      type: 'varchar',
      length: 255,
      comment: '项目描述',
      // 可为空
      nullable: true
    },
    web_url: {
      type: 'varchar',
      comment: 'web地址',
      nullable: true,
      // 唯一
      unique: true
    },
    ssh_url_to_repo: {
      type: 'varchar',
      comment: 'SSH地址',
      nullable: true,
      // 唯一
      unique: true
    },

    readme_url: {
      type: 'varchar',
      comment: 'README路径',
      nullable: true
    },
    last_activity_at: {
      type: 'datetime',
      comment: '最后更新时间'
    },
    created_at: {
      type: 'datetime',
      comment: '创建时间'
    },
    default_branch: {
      type: 'varchar',
      length: 50,
      comment: '默认分支',
      // 新仓库可能是没有分支的
      nullable: true
    },

    group_name: {
      type: 'varchar',
      comment: '项目组名称',
      nullable: true
    },
    group_web_url: {
      type: 'varchar',
      comment: '项目组地址',
      nullable: true
    },
    group_id: {
      type: 'int',
      comment: '项目组id',
      nullable: true
    },
    service_name: {
      type: 'varchar',
      nullable: true,
      comment: 'jenkins服务名',
      length: 60
    }
  }
})

service.js

import Repository from '../entity/repository.js'
import { Not, IsNull } from 'typeorm'

const repositoryEntity = dataSource.getRepository(Repository)

const fn = async() => {
    await repositoryEntity
    .createQueryBuilder('repo')
    .select([
      'repo.id',
      'repo.ssh_url_to_repo',
      'repo.name',
      'repo.service_name',
      'repo.description'
    ])
    .where({
      service_name: Not(IsNull())
    })
    .getMany()
}

fn()

以下为错误写法

await repositoryEntity
    .createQueryBuilder('repo')
    .select([
        'repo.id',
        'repo.ssh_url_to_repo',
        'repo.name',
        'repo.service_name',
        'repo.description'
    ])
    // 想表达 is not null 场景,这里的语法不能这么写,会报语法异常
    // Cannot convert a Symbol value to a string
    .where('repo.service_name = :service_name', {
        service_name: Not(IsNull())
    })
    .getMany()

上述不能通过 参数来转义数据 的方式来实现 where 条件查询, 按理说,应该可以的, 应该是 typeorm 没有实现, 毕竟使用参数转义,是 typeorm 推荐的写法,防止sql 注入

转载自:https://juejin.cn/post/7237052860512796729
评论
请登录