客户端为Angular 8,具有NgRx数据;服务器是NestJs+MySQL。如何使用条件和SQL获取数据?

客户端为Angular 8,具有NgRx数据;服务器是NestJs+MySQL。如何使用条件和SQL获取数据?,nestjs,angular-ngrx-data,Nestjs,Angular Ngrx Data,随着Angular、NgRx数据和NestJs越来越流行,我觉得可能有相当多的程序员对下面的查询语法感到疑惑 我有一个运行中的客户端原型,由Angular 8和NgRx数据组成。 后端是基于NestJs的服务器+MySQL 除了查询,我可以很好地在所有部分之间检索和传递数据。我似乎无法找到有关语法的适当文档 以下是如何设置客户端的示例: // Simple entity example (all ngrx-data metadata are dec

随着Angular、NgRx数据和NestJs越来越流行,我觉得可能有相当多的程序员对下面的查询语法感到疑惑

我有一个运行中的客户端原型,由Angular 8和NgRx数据组成。 后端是基于NestJs的服务器+MySQL

除了查询,我可以很好地在所有部分之间检索和传递数据。我似乎无法找到有关语法的适当文档

以下是如何设置客户端的示例:

                        // Simple entity example (all ngrx-data metadata are declared and set):
export class Hero { 
    id: number;
    name?: string;
    age?: number;
}
实体服务/用于获取数据

@Injectable({providedIn: 'root'})
export class HeroService extends EntityCollectionServiceBase<Hero> {
  constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) {
    super('Hero', serviceElementsFactory);
  }
}
用于显示数据的组件

@Component({
  selector: 'hero-comp',
  templateUrl: './hero.component.html', 
  styleUrls: ['./hero.component.scss']
})
export class HeroComponent {
    heroData$: Observable<Hero[]>;
    constructor(private heroDatService: HeroService) {
        this.heroData$ = this.heroDatService.entities$;
    }

    private getAllData() {
                          // This works nicely, I get all records from the db via server
        this.heroDatService.getAll();
    }

    private queryData() {
                          // This queryParams syntax fails - server complains with this error:
                          //      [HttpExceptionFilter] GET /hero/?age>20 
                          //      QueryFailedError: ER_EMPTY_QUERY: Query was empty
                          // QUESTION: What is the proper syntax?
        let queryParams: QueryParams = {
            'age > 20'
        }
        this.fetchDataService.getWithQuery(queryParams);
    }
以下是与服务器相关的代码摘录:- 这里有一个服务,但为了简单起见,我将repo函数移到了controller函数:

@Controller('hero')
export class HeroController <Hero> {
    constructor(readonly repo: Repository<Hero>) {}

                          // This returns nicely all Hero records from the MySQL db server
@Get()
async getAll(): Promise<Hero[]> {
    return await this.repo.find();
} 
                          // This does not work !
                          // I am not sure about any piece of the code here !
@Get('query')
async query(@Query() sql): Promise<any> {
                          // Does the sql argument need to be manipulated into parameters: {...} ?
                          // If yes - how ?
    let parameters: undefined;
    return await this.repo.query(sql, parameters);
}
请参阅每个代码行上方的注释-问题已在此处详细说明

以下是一些重要的问题:

在客户机上,我们如何正确传递以下示例的查询条件: -{'age>20'} -{'年龄在20到40'} -{'age=20或age=30或age=40'} -{'name=Superman'} -{'name LIKE Super%'} -等等

另外,传递完整SQL语句的语法是什么,例如: -{'SELECT*来自名字像Super%和年龄>20岁的英雄;'} 并从服务器获取结果

要使这些查询正常工作,客户端和服务器端都需要做些什么


非常感谢所有的输入。

您似乎对HTTP查询参数和SQL查询这两个不同的主题感到困惑。HTTP上下文中的查询参数是可以从客户端传递到服务器并修改HTTP调用结果的参数。查询参数总是从?在URL中,格式为=并用&分隔

SQL查询是一个特定字符串,它告诉SQL server要查询的表、列和条件。通常以从何处选择的形式;,但它们可能比这复杂得多

既然定义已经过时,那么您尝试访问的端点应该是/hero/query。最后,您需要在服务器端执行大量数据处理、清理、确保传入字符串适合SQL WHERE子句、确保不会受到SQL注入的攻击如果您将查询参数直接传递到查询,您将,但是一个非常非常幼稚的方法看起来是这样的:

@控制器“英雄” 导出类控制器{ constructor@InjectRepositoryHero私有只读repo:Repository{} @获取“查询” queryForHero@Query槲寄生{ 返回此.repo.query`SELECT FROM Hero WHERE${queryParams.query};`; } } 出于对世界上一切美好事物的热爱,请不要实际使用上述代码。它100%容易受到各种SQL注入的攻击

相应的请求可能类似于

卷曲http:///hero/query?query=Name%3D%27Superman%27 这将导致服务器使用查询

从名为“超人”的英雄中选择; 在将数据发送到SQL server之前,您真的需要在服务器上添加大量的验证


希望这能帮助您走上正确的道路。

我感谢您的意见。您能否概述或指出避免SQL注入的“最佳实践”?在服务器安全方面,这通常是一个很好的标准