,如果是一些简单的操作,类似定时脚本什么的,可能就直接生写SQL语句来实现功能了,而如果是在一些大型项目中,数十张、上百张的表,之间还会有一些(一对多,多对多)的映射关系,那么引入一个ORM(Object...在结合着VS Code开发时可以得到很多动态提示,类似findAll,create之类的操作都会有提示: Animal.create({ abc: 1, // ^ abc不是Animal...细心的同学可能会发现,getList的返回值是一个Animal[]类型的,所以上边并没有leg属性,Bird的两个属性也是如此。...,而不用担心返回值类型了 const dogList = await Dog.getList() console.log(dogList[0].leg) // success 小结 本文只是一个引子,...当然了,ORM这种东西也不是说要一股脑的上,如果是初学者,从个人层面上我不建议使用,因为这样会少了一个接触SQL的机会 如果项目结构也不是很复杂,或者可预期的未来也不会太复杂,那么使用ORM也没有什么意义
还是就像上边所说的,因为是一个动态的脚本语言,所以很难有编辑器能够在开发期间正确地告诉你所要调用的一个函数需要传递什么参数,函数会返回什么类型的返回值。 ?...而在TS中,对于一个函数,首先你需要定义所有参数的类型,以及返回值的类型。 这样在函数被调用时,我们就可以很清晰的看到这个函数的效果: ?...controllers只负责处理逻辑,通过操作model对象,而不是数据库来进行数据的增删改查 鉴于公司绝大部分的Node项目版本都已经升级到了Node 8.11,理所应当的,我们会尝试新的语法...@Column({ comment: '性别' }) gender: number } 因为sequelize建立连接也是需要对应的数据库地址、账户、密码、database等信息.../number-comma' 每添加一个新的util,就去index中添加对应的索引,这样带来的好处就是可以通过一行来引入所有想引入的utils: import {getUid, numberComma
loadEnv 方法 其实 Vite 内置一个 loadEnv 方法, 也可以实现同样的功能,但是目前对 TS 的支持不太友好,返回的是一个 Record 类型,不能获得代码的自动提示..."editor.formatOnSave": true, // 控制编辑器在键入一行后是否自动格式化该行。...而数据库创建连接非常消耗时间,关闭连接也消耗时间,严重的浪费数据库的资源,并且极易造成数据库服务器内存溢出、宕机。...② 什么是连接池 在数据库连接池是负责创建,分配,释放数据库连接的对象,在项目启动时会创建一定数量的数据库连接放到连接池对象中,并允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。...而连接的建立,断开都有连接池自身来管理。
下面介绍几款node的ORM框架,介绍之前先介绍ORM的两种模式: Active Record 模式:活动记录模式,领域模型模式一个模型类对应关系型数据库中的一个表,模型类的一个实例对应表中的一行记录。...,而DataMapper更加适合长线开发,保持业务逻辑与数据存储独立的复杂项目。...Sequelize 这个被star数最多了一个ORM框架,官方居然不给中文文档,找个CLI命令快速构建也没有,也没找到个合适轮子,只能自己搭了,也不是少了轮子就不能活了。...不过Sequelize的官网文档看着很顺眼,不得不称赞一下,需要注意的一点Sequelize v5版本发生了比较大的变化,这里我以最新版本v5版本为主,老版本可以自己看看下官方文档。...删除 }); Person.find({ name: "admin"}) .limit(3) .offset(2)//跳过 .only("name", "age")//返回字段
下面介绍几款node的ORM框架,介绍之前先介绍ORM的两种模式:Active Record 模式:活动记录模式,领域模型模式一个模型类对应关系型数据库中的一个表,模型类的一个实例对应表中的一行记录。...,而DataMapper更加适合长线开发,保持业务逻辑与数据存储独立的复杂项目。...Sequelize这个被star数最多了一个ORM框架,官方居然不给中文文档,找个CLI命令快速构建也没有,也没找到个合适轮子,只能自己搭了,也不是少了轮子就不能活了。...不过Sequelize的官网文档看着很顺眼,不得不称赞一下,需要注意的一点Sequelize v5版本发生了比较大的变化,这里我以最新版本v5版本为主,老版本可以自己看看下官方文档。...});//删除});Person.find({ name: "admin"}) .limit(3) .offset(2)//跳过 .only("name", "age")//返回字段
type: DataTypes.INTEGER, allowNull: false, defaultValue: 0, comment: '是否为管理员 0不是管理员...email:{ type: DataTypes.STRING, allowNull: true, comment: '邮箱' } }) 方法一 这中返回的格式...,是将另一个表的数据放到一个对象中的,如下 const User = require('.....Sequelize.col('表名.想要的字段名') const { count, rows } = await User.findAndCountAll({ where..., offset: (currentPage - 1) * pageSize, limit: Number(pageSize),
前言 上一篇介绍了如何使用 Sequelize 连接 MySQL,接下来,在原来代码的基础上进行扩展,实现用户的注册和登录功能。...这里需要简单提一下两个概念 JWT 和 单点登录: JWT JWT(JSON Web Token)是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准(RFC 7519)。...(error); return void 0; } } } 现在,findOne() 的功能更符合它的方法名了,查到了,就返回用户信息,查不到,就返回 undefined。...四、登录验证 前面列了一大堆代码,是时候检验效果了,我们就按照原来注册的信息,进行登录请求: ? ? 图中可以看到,已经返回了一长串 token 了,而且控制台也打印了登录的步骤和用户信息。...可以看到,返回 401 状态码,Unauthorized 表示未授权,也就是判断你没有登录。
问题1解决与相关讲解 结果 预期结果 0 2 1 4 2 6 3 8 4 10 运行后的结果 5 undefined 5 undefined 5 undefined 5 undefined...await几点说明: await执行的那一行语句是同步的。...就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。...我对阮一峰老师的话再具体说明一下,可能有些同学还不是特别理解。...(注意:await执行之后应该是一个resolve的结果而不是promise对象了)。
: string): Promise { const sql = ` SELECT user_id id, real_name realName...if (user) { return { code: 200, // 返回状态码,可自定义 data: { user,...这说明之前的配置生效了,我们试着用之前的参数请求一下接口: ? 返回“查无此人”,说明数据库没有叫“Kid”的用户。 我们改成正确的已存在的用户名再试试: ?...总结 这篇介绍了 MySQL 的数据准备、Sequelize 的配置、Nest 怎么通过 Sequelize 连接上 MySQL,以及用一条简单的查询语句去验证连接情况。...而使用原生 SQL,只需要学一种语言就够了,换个工具,也能用,而且就算改了字段,也只会在请求接口的时候报错,到时候再针对那个语句修改就好了,而且现在查找替换功能这么强大,批量修改也不是难事。
在 RBAC 中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。 2....,抛开注释,总共才15行, 构造器里的 role: number 是通过路由传入的可配置参数,表示必须小于等于这个数字的角色才能访问。...然后,重新登录,重新登录,重新登录,重要的事情说 3 遍,再请求: ? 返回成功信息,再看看数据库: ? 如图,创建商品功能测试成功。...现在问题来了,因为麦林炮手的介绍不太“和谐”,所以需要删除,于是我们请求一下删除接口: ? 返回“无权操作”,只好提升角色,或者联系管理员帮忙删除啦,剩下的事情和之前的一样,不再赘述。 5....请求一下只有管理员才有权限的删除操作: ? 涛声依旧。 总结 本篇介绍了 RBAC 的概念,以及如何使用拦截器和守卫实现 RBAC 0,原理简单到 15 行代码就搞定了。
那时我在想怎么才能从这种嵌套回调中解脱出来,我想到让Dao层的DML执行结果返回Promise对象,或者是Service层用流程控制库比如async,step,在这个反复的纠结的过程中也接触到目前流行的...的每次DML操作结果都是返回一个Promise对象,这是符合我的初衷的,业务层通过执行then函数处理成功返回的结果,通过catch函数捕获异常对象,另外Sequelize支持外键查询以及事务处理,完全符合我们的项目开发要求...最终的架构图如图5所示,如图6所示,我们代码的类似这样,相比前面两种是不是逻辑清晰很多,职责更加明确一些呢?...如果参数合法,异步调用Service业务层,Service层会对Dao层发起异步DML操作,Dao层会通过Sequelize的ORM技术操作数据库,Sequelize执行完返回Promise对象给Dao...操作成功,则会执行then函数,then函数以及catch函数的执行结果通过callback的方式返回给路由处理层。
你可以考虑使用typescript方式的来初始化项目,但是我们这里直接使用javascript而不是它的超级typescript来初始化项目。...引入数据库 这里使用的数据库是mysql,但是我们不是直接使它,而是安装封装过的mysql2和egg-sequelize。...复制代码 当然,这是通过包egg-sequelize处理的,我们也要将其引入,告诉eggjs去使用这个插件。 // config/plugin.js ......复制代码 在完成接口的编写后,你可以通过postman 应用去验证下是否返回的数据。 前端对接接口 接下来就得切回来client文件夹进行操作了。我们在上面已经简单封装了请求方法。...|| undefined, group: res.data && res.data.group || undefined, }) } else {
通常函数中的变量应该是局部的,这样当你执行完函数时它们就会释放。 4. Delete vs Splice 使用splice而不是使用delete从一个数组中删除一个项。...请注意,事实上它并没有被设置为undefined的值,而是将该属性从数组中移除,使其看起来undefined。...; }); // [1, 4, 9, 16] Immutability - 原来的数组将不受影响。...Cleaner code - 当做相同的事情时,map几乎总是可以用比for更少的代码来写。它有时可以清楚地写在一行上,而for至少需要两行或一般需要三行,并包括括号。...var pi =3.1415; pi = pi.toFixed(2); // pi will be equal to 3.14 注意:toFixed()返回的是字符串而不是数字。
注意,typeof是一个操作符而不是一个函数,因此例子中的圆括号尽管可以使用,但不是必须的。 调用typeof null会返回Object,因为特殊值null被认为是一个空的对象引用。...,那么最好将该变量初始化为null而不是其他值。...第一个函数Number()可以用于任何数据类型,而另外两个函数则专门用于把字符串转换为数值。...用parseInt()转换空字符串会返回NaN(Number()对空字符返回0)。...此时,a中保存的值为 100 ,当使用 a 来初始化 b 时,b 中保存的值也为100,但b中的100与a中的是完全独立的,该值只是a中的值的一个副本,此后, 这两个变量可以参加任何操作而相互不受影响
在 JavaScript 中一共有七种主要类型: String Number Boolean Null Undefined Symbol Object 前六种为基本数据类型,Object 为引用类型(对象类型...),值得注意一点的是用 typeof null 会返回 Object,这实际上是一个bug,Null 实际上是基本类型的值。...根据 JavaScript 对语言类型的分类,很容易知道,并不是 JavaScript 万物皆对象,或者说任何非基本类型的都是对象类型。...基本类型:包括上述中的六种,基本类型的值是一种简单的数据段。存储在栈内存中;当复制基本类型的值时,复制它的值(改变其中一个,另一个不受影响),比较时,按其值比较。...,使用 new 操作符创建的引用类型的实例,在执行流离开当前作用域之前一直都保存在内存中,而自动创建的基本包装类型的对象,则只存在与一行代码的执行瞬间,然后被立即销毁。
行 {4} 检测要过滤的 key 是否在当前对象中,如果是将值赋予 key 行 {5} 对于对象元素,如果 key 不在当前对象中,设置一个随机值,使得其它 key 不受影响,例如 [{a: 1},...name; return this; } 这样手动给个返回值,行 {2} result 会拿到一个返回的对象,否则 result 返回 undefined,最后就只能将 obj 给返回。...arguments 类数组转化为数组 行 {5} 执行函数 fn 行 {6} 记得删除上下文绑定的 fn 函数 行 {7} 如果该函数有返回值,将结果返回 /* * 实现一个自己的 call 方法..., undefined]; const arr2 = [undefined, undefined].mayJunMap(Number.call, Number); const arr3 = [undefined...是可以链式调用的,对于值穿透的场景要做判断,如果不传,则返回一个函数,也就是将上个结果进行传递 行 {9} then 方法必须返回一个 promise 对象 行 {10}、{11} 、{12} 也是 then
({ // 查询某字段不重复的【数量】,而不是记录,默认是id,如果需要其他字段就写 定义 col distinct: true, // 查出 name 不重复的数量 col: 'name...', }); 注意这里是查出数量,不是数据,比如下面以name 为重复字段的,虽然有 6条数据,但是 counts 是 2 3.1 查询条件 查询条件用 sequelize 之后可以简化很多,使用各种逻辑操作符组合的方式...这里不是说限制单个person 的 comments 返回数量,比如这样 await person.findAll({ include: [ { model: personComment...CASCADE: 从父表中删除或更新对应的行,同时自动删除或更新子表中匹配的行。ON DELETE CANSCADE和ON UPDATE CANSCADE都被InnoDB所支持。 2....SET NULL: 从父表中删除或更新对应的行,同时将子表中的外键列设为空。注意,这些在外键列没有被设为NOT NULL时才有效。
而 Docker 其中一个作用就是将上面 mariadb 和 redis 都打成不同 image(镜像),使用 DockerHub 统一管理,使用 Docker 就可以快速配置一个服务。...up -d Dockerfile 不过,在生产环境时每次都要跑 npm 这两条命令还是很烦,能不能把这两行也整全到 docker-compose 里呢?...描述 “流水线” 的叫 Dockerfile (注意这里不是驼峰写法)。 注意:正常的镜像构建和启动应该是整个项目 CICD 其中的一环,这里只是打个比方。...修改 mariadb 的连接: // 连接数据库 const sequelize = new Sequelize({ host: process.env.NODE_ENV === 'docker'...而 docker-compose 的作用则是 “一键拉起” N 个容器。 上面整个例子放在 Github 这里了,可以 Clone 下来自己捣鼓玩玩。
领取专属 10元无门槛券
手把手带您无忧上云