簡體   English   中英

如何在Typeorm中使用queryBuilder優化查詢以選擇內容?

[英]How can I optimze my queries to select things using queryBuilder in Typeorm?

我有3個實體User,Spot和Thing。 用戶可以有很多地點,一個地點可以有很多東西。

目前,我正在編寫兩個查詢,一個查詢用於驗證該點是否存在於用戶中,然后一個查詢從該點獲取事物。 (請參閱index.js )。

如何使用createQueryBuilder編寫一個查詢(不使用repo.find )以基於user.idspot.id選擇所有內容? 我知道有一些加入,但我無法解決。

這是代碼的相關部分:

const spot = await spotRepo.createQueryBuilder('spot')
  .innerJoin('spot.user', 'user')
  .where('user.id = :id', { id: 1 })
  .andWhere('spot.id = :id', { id: 1 })
  .getOne();
if (spot !== undefined) {
  console.log(spot);
  console.log('Got the spot');
  const spotWithThings = await spotRepo.createQueryBuilder('spot')
    .leftJoinAndSelect('spot.things', 'things')
    .where('spot.id = :id', { id: spot.id })
    .getOne();
  console.log(spotWithThings);
}

運行該項目的步驟:

  1. git clone https://github.com/fabianmoronzirfas/typeorm-how-to-write-smarter-queries-questionmark.git ./test-repo && cd test-repo
  2. 運行npm i命令
  3. ormconfig.json文件中設置數據庫設置
  4. 啟動數據庫docker-compose up
  5. 運行npm start命令

這是index.ts

import "reflect-metadata";
import { createConnection, getRepository } from "typeorm";
import { User } from "./entity/User";
import { Spot } from './entity/Spot';
import { Thing } from './entity/Thing';

createConnection().then(async connection => {
    {
        console.log("Inserting a new data into the database...");
        const user = new User();
        const spot = new Spot();
        // const things = [];
        for (let i = 0; i < 5; i++) {
            const thing = new Thing();
            if (spot.things === undefined) {
                spot.things = [thing];
            } else {
                spot.things.push(thing);
            }
            await connection.manager.save(thing);;
        }
        user.spots = [spot];
        await connection.manager.save(user);
        await connection.manager.save(spot);
        console.log('setup done');
    }
    const spotRepo = getRepository(Spot);
    const spot = await spotRepo.createQueryBuilder('spot')
    .innerJoin('spot.user', 'user')
    .where('user.id = :id', { id: 1 })
    .andWhere('spot.id = :id', {id: 1})
    .getOne();
    if (spot !== undefined) {
        console.log(spot);
        console.log('Got the spot');
        const spotWithThings = await spotRepo.createQueryBuilder('spot')
        .leftJoinAndSelect('spot.things', 'things')
        .where('spot.id = :id', { id: spot.id })
        .getOne();
        console.log(spotWithThings);
    } else {
        console.log(`No spot? with user id ${1}`);
    }
}).catch(error => console.log(error));

這是Spot.ts

import {Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany} from "typeorm";
import { User } from './User';
import { Thing } from './Thing';
@Entity()
export class Spot {
    @PrimaryGeneratedColumn()
    id: number;
    @ManyToOne( _type => User, user => user.spots)
    public user: User;
    @OneToMany(_type => Thing, (thing) => thing.spot, {
        eager: true,
      })
      public things!: Thing[];
}

這是Thing.ts

import {Entity, PrimaryGeneratedColumn, ManyToOne, JoinColumn} from "typeorm";
import { Spot } from './Spot';

@Entity()
export class Thing {

    @PrimaryGeneratedColumn()
    id: number;

    @ManyToOne( _type => Spot, spot => spot.things , {
        cascade: true,
        // eager: true,
      })
      @JoinColumn()
      public spot!: Spot;
}

這是User.ts

import {Entity, PrimaryGeneratedColumn, OneToMany} from "typeorm";
import { Spot } from './Spot';

@Entity()
export class User {

    @PrimaryGeneratedColumn()
    id: number;
    @OneToMany(_type => Spot, spot => spot.user, {
        cascade: true,
      })
      public spots: Spot[];
}

這是ormconfig.json

{
   "type": "postgres",
   "host": "127.0.0.1",
   "port": 5432,
   "username": "postgres",
   "password": "postgres_password",
   "database": "postgres",
   "synchronize": true,
   "dropSchema": true,
   "logging": false,
   "entities": [
      "src/entity/**/*.ts"
   ],
   "migrations": [
      "src/migration/**/*.ts"
   ],
   "subscribers": [
      "src/subscriber/**/*.ts"
   ],
   "cli": {
      "entitiesDir": "src/entity",
      "migrationsDir": "src/migration",
      "subscribersDir": "src/subscriber"
   }
}

這是我的docker-compose.yml

version: '3'
services:
  postgres:
    container_name: 'pgdb'
    image: 'mdillon/postgis:10'
    ports:
      - '5432:5432'

這是package.json

{
   "name": "typeorm-smarter-req",
   "version": "1.0.0",
   "description": "",
   "main": "index.js",
   "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "start": "ts-node src/index.ts"
   },
   "author": "",
   "license": "ISC",
   "dependencies": {
      "pg": "^7.11.0",
      "reflect-metadata": "^0.1.10",
      "typeorm": "0.2.18"
   },
   "devDependencies": {
      "ts-node": "3.3.0",
      "@types/node": "^8.0.29",
      "typescript": "3.3.3333"
   }
}

這是tsconfig.json

{
   "compilerOptions": {
      "lib": [
         "es5",
         "es6",
         "dom"

      ],
      "target": "es5",
      "module": "commonjs",
      "moduleResolution": "node",
      "outDir": "./build",
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "sourceMap": true
   }
}

您想獲取東西,因此從Thing回購開始,並詢問問題很多,並根據基於聯接定義的約束進行過濾:

const thingRepo = entityManager.getRepository(Thing);
const things = thingRepo.createQueryBuilder('thing')
    .leftJoinAndSelect('thing.spot', 'spotThing')
    .leftJoinAndSelect('spotThing.user', 'userSpot')
    .where('spotThing.id = :spotId', {spotId})
    .andWhere('userSpot.id = :userId', {userId})
    .getMany();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM