0
点赞
收藏
分享

微信扫一扫

Node.js _Type ORM 写一个关联表查询并Group By,Order by, Where

司马吹风 2023-03-05 阅读 130


listPopularTopics: async (args: any, context: any) => {
const postRepository = getCustomRepository(PostRepository);

const post = await postRepository
.createQueryBuilder('post')
// .innerJoinAndSelect('post.topic_id', 'topic')
.leftJoinAndSelect(Topic, 'topic', 'post.topic_id = topic.id')
.select('topic.name')
.addSelect('SUM(1)', 'sum')
.groupBy('post.topic_id')
.addGroupBy('topic.id')
.where('post.topic_id is not null')
.orderBy('sum', 'DESC')
.limit(5)
.getRawMany();
console.log(post);
return post;
}

createQueryBuilder(‘别名’)

什么是别名?

我们使用​​createQueryBuilder("user")​​。 但什么是"user"? 它只是一个常规的 SQL 别名。 我们在任何地方都使用别名,除非我们处理选定的数据。

​createQueryBuilder("user")​​ 相当于:

createQueryBuilder()
.select("user")
.from(User, "user");

这会生成以下 sql 查询:

SELECT ... FROM users user

在这个 SQL 查询中,​​users​​​是表名,​​user​​是我们分配给该表的别名。

稍后我们使用此别名来访问表:

createQueryBuilder()
.select("user")
.from(User, "user")
.where("user.name = :name", { name: "Timber" });

以上代码会生成如下 SQL 语句:

SELECT ... FROM users user WHERE user.name = 'Timber'

看到了吧,我们使用了在创建查询构建器时分配的​​user​​别名来使用 users 表。

一个查询构建器不限于一个别名,它们可以有多个别名。 每个选择都可以有自己的别名,你可以选择多个有自己别名的表,你可以使用自己的别名连接多个表。 你也可以使用这些别名来访问选择的表(或正在选择的数据)。

​​#​​ 使用参数来转义数据

我们使用了​​where("user.name = :name", { name: "Timber" })​​​. ​​{name:“Timber”}​​​代表什么? 这是我们用来阻止 SQL 注入的参数。 我们可以写:​​where("user.name ='"+ name +"')​​​,但是这不安全,因为有可能被 SQL 注入。 安全的方法是使用这种特殊的语法:​​where("user.name =name",{name:"Timber"})​​​,其中​​name​​​是参数名,值在对象中指定: ​​{name:"Timber"}​​。

.where("user.name = :name", { name: "Timber" })

是下面的简写:

.where("user.name = :name")
.setParameter("name", "Timber")

注意:不要在查询构建器中为不同的值使用相同的参数名称。如果多次设置则后值将会把前面的覆盖。

还可以提供一组值,并使用特殊的扩展语法将它们转换为SQL语句中的值列表:

.where("user.name IN (:...names)", { names: [ "Timber", "Cristal", "Lina" ] })

该语句将生成:

WHERE user.name IN ('Timber', 'Cristal', 'Lina')

添加​​GROUP BY​​表达式

添加 ​​GROUP BY​​ 表达式很简单:

createQueryBuilder("user").groupBy("user.id");

将会生成以下 SQL 语句:

SELECT ... FROM users user GROUP BY user.id

如果要使用更多 group-by, 则可以使用 c​​addGroupBy​​:

createQueryBuilder("user")
.groupBy("user.name")
.addGroupBy("user.id");

如果使用了多个​​.groupBy​​​ ,则后面的将会覆盖之前所有的 ​​ORDER BY​​ 表达式。

​​#​​​ 添加​​LIMIT​​表达式

添加 ​​LIMIT​​ 表达式很简单:

createQueryBuilder("user").limit(10);

将会生成以下 SQL 语句:

SELECT ... FROM users user LIMIT 10

生成的 SQL 查询取决于数据库的类型(SQL,mySQL,Postgres 等)。 注意:如果你使用带有连接或子查询的复杂查询,LIMIT 可能无法正常工作。 如果使用分页,建议使用​​take​​代替。

添加​​ORDER BY​​表达式

添加 ​​ORDER BY​​ 很简单:

createQueryBuilder("user").orderBy("user.id");

将会生成一下 SQL 语句:

SELECT ... FROM users user ORDER BY user.id

你可以将排序方向从升序更改为降序(或反之亦然):

createQueryBuilder("user").orderBy("user.id", "DESC");

createQueryBuilder("user").orderBy("user.id", "ASC");

也可以添加多个排序条件:

createQueryBuilder("user")
.orderBy("user.name")
.addOrderBy("user.id");

还可以使用排序字段作为一个 map:

createQueryBuilder("user").orderBy({
"user.name": "ASC",
"user.id": "DESC"
});

如果你使用了多个​​.orderBy​​​,后面的将覆盖所有之前的​​ORDER BY​​表达式。

举报

相关推荐

0 条评论