【问题标题】:Strongly-typed database access with Node.JS and TypeScript使用 Node.JS 和 TypeScript 进行强类型数据库访问
【发布时间】:2016-04-01 13:35:27
【问题描述】:

当我们使用C# 时,我们可以使用 Code-First 方法以强类型的方式访问我们的数据库:

public class Blog 
{ 
    public int BlogId { get; set; } 
    public string Name { get; set; } 
    public virtual List<Post> Posts { get; set; } 
}
...
public class Database : DbContext 
{ 
    public DbSet<Blog> Blogs { get; set; } 
    public DbSet<Post> Posts { get; set; } 
}
var db = new Database()
var blog = new Blog { Name = "My new blog", BlogId = 1 }; 
db.Blogs.Add(blog); 
db.SaveChanges(); // save object to database

编译器将确保我们只访问现有的属性/方法,并且我们在代码中的任何地方都使用正确的类型。

我怎样才能对 TypeScriptNode.JS 做同样的事情?

我找到了用于数据库访问的 Knex.JSbookshelf 库,但我找不到任何关于如何将它们与强类型 TypeScript 对象和类一起使用的示例。

【问题讨论】:

  • 我不使用 Typescript 但有书架和 Knex 的定义,您可以使用tsd 来管理/安装这些定义。安装后,一个不错的代码编辑器将使用自动完成和文档的定义(例如 Visual Studio Code)。

标签: javascript node.js typescript bookshelf.js knex.js


【解决方案1】:

我在网上搜索了有关如何将 Bookshelfjs 与 Typescript 一起使用的示例,但没有任何文章或博客文章可以提供帮助。我确实在 github 上找到了作为 DefinatelyTyped test file 的一部分分发的测试,这是一个很好的起点。此外,您很可能希望将每个模型存储在自己的文件中,这需要 Bookshelfjs 注册表插件。 This article 解释了原因,但在常规 javascript 的上下文中。

假设您已经正确安装了 knexjs 和 bookshelfjs 的类型。以您的代码为灵感,进一步阅读:

您可能有一个名为“Config.ts”的文件,其中包含所有数据库详细信息:

import * as Knex from 'knex';
import * as Bookshelf from 'bookshelf';

export class Config {

    private static _knex:Knex = Knex({
        client: 'mysql',
        connection: {
            host     : '127.0.0.1',
            user     : 'your_database_user',
            password : 'your_database_password',
            database : 'myapp_test',
            charset  : 'utf8'
        }
    });

    private static bookshelf:Bookshelf = Bookshelf(Config.knex);

    public static bookshelf(): Bookshelf {
        Config.bookshelf.plugin('registry');
        return Config._bookshelf;
    }
}

您可能有一个名为“Blog.ts”的文件来保存博客模型(另一个名为“Post.ts”的文件来保存帖子模型):

import {Config} from './Config';
import {Post} from './Post';

export class Blog extends Config.bookshelf.Model<Blog> 
{ 
    get tableName() { return 'books'; }

    // strongly typed model properties linked to columns in table
    public get BlogId(): number {return this.get('id');}
    public set BlogId(value: number) {this.set({id: value})}
    public get Name(): string {return this.get('name');}
    public set Name(value: string) {this.set({name: value});}

    posts(): Bookshelf.Collection<Post> {
        return this.hasMany(Post);
    } 
}

module.exports = Server.bookshelf.model('Blog', Blog);

在您的“App.ts”文件中,您可以像这样运行您的代码:

import {Config} from './Config';
import {Blog} from './Blog';

var blog = new Blog();
blog.set({ Name : "My new blog", BlogId : 1 }); 
    .save(); 

我没有在这里测试代码,所以我可能有一些小错别字,但你明白了。请注意,我对类属性使用了标题大小写,但我对数据库字段使用了蛇形大小写。为了使 Bookshelf 开箱即用,必须遵守某些命名约定,例如每个表的 Id 字段被称为“id”,并且关系的外键具有表名的单数版本(例如,对于 users 表,表中的 Id 将是 'id' 但登录表中的外键是 'user_id')。

无论如何,要想弄清楚如何将 Bookshelfjs 与 TypeScript 思想结合使用(鉴于缺乏关于该主题的文档),最好的方法是结合 DefinatelyTyped typedef bookshelf.d 查看 Bookshelfjs 文档。 ts 文件。

【讨论】:

  • 这是一个很好的答案 - 帮助我在我的项目中使用它,谢谢!
【解决方案2】:

您可以在 github 上的 DefinitelyTyped 存储库中找到许多 js 库的类型定义。

您还可以使用 here 找到的 tsd 工具将这些定义文件添加到您的项目中。

简而言之,您需要在终端中运行这 4 个命令。

$ npm install tsd -g
$ tsd init
$ tsd install knex
$ tsd install bookshelf

【讨论】:

    【解决方案3】:

    正在要求目前不可用的东西。
    但是,实际上可以做到!你将不得不做一些艰苦的工作!

    您(可能)知道,TypeScript 仅在开发时使用,没有任何东西进入运行时,因此您要求针对您的数据库结构进行类型验证。

    您必须创建一个在 typescript 编译器之前运行的构建步骤,这个新的构建步骤应该从您的数据库结构中生成一个 d.ts 文件。它应该连接到数据库,对其进行调查,并输出描述其结构的接口。

    请注意,此结构会根据您使用的数据库而改变...

    另一种解决方案是自己手动创建 d.ts 文件,一旦您的数据库结构发生变化,您还必须(手动)在定义文件中反映这一点。

    【讨论】:

    • d.ts 文件可以在书架和 knex 中找到,只需将它们添加到项目中即可。 :)
    • 我看到了你的回答,我认为他没有要求这些定义。他想要数据的实际结构......
    • hm.. 你是对的,再次阅读这个问题听起来更像是他想要为他存储在数据库中的对象定义类型。
    猜你喜欢
    • 1970-01-01
    • 2010-12-07
    • 2020-06-03
    • 1970-01-01
    • 2023-03-08
    • 2014-11-16
    • 1970-01-01
    • 2018-01-08
    • 1970-01-01
    相关资源
    最近更新 更多