功能梳理完了以后,咱们就可以开始数据库表设计了:
数据库表图:
首先打开Navicat Premium 创建数据库 blog
配置如下:
课前学习:
1、Sequelize 中文API文档【强烈推荐】https://itbilu.com/nodejs/npm...
2、Sequelize 和 MySQL 对照
https://segmentfault.com/a/11...
3、使用Sequelize
http://www.liaoxuefeng.com/wi...
4、Sequelize API
https://sequelize.readthedocs...
5、关于“时间”的一次探索
https://segmentfault.com/a/11...
在blogNodejs/models 下
首先新建 mysql.js 进行mysql连接配置(基于Sequelize)
var config = require("config-lite");//引入灵活配置文件 var Sequelize = require("sequelize");.//引入Sequelize var Mysql = new Sequelize(config.mysql.database, config.mysql.user, config.mysql.password, { host: config.mysql.host, //数据库服务器ip dialect: "mysql", //数据库使用mysql port: 3306, //数据库服务器端口 pool: { max: 5, min: 0, idle: 10000 }, }); module.exports = Mysql;
然后根据数据库图,依次创建对应的Model
这里以user.js为示例 多带带说下:
/** * User 用户表 */ var Sequelize = require("sequelize");//引入sequelize var Mysql = require("./mysql");//引入mysql实例化 //定义User用户表 var User = Mysql.define("user", { uuid: {//使用uuid 而不使用 type: Sequelize.UUID,//设置类型 allowNull: false,//是否允许为空 primaryKey: true,//主键 defaultValue: Sequelize.UUIDV1,//默认值 }, //uuid email: { //邮箱 type: Sequelize.STRING, allowNull: false, unique: true, //唯一 validate: {//设置验证条件 isEmail: true,// 检测邮箱格式 (foo@bar.com) }, }, password: { //密码 type: Sequelize.STRING, allowNull: false, }, state: { //状态 0未激活邮箱、1已激活邮箱 type: Sequelize.STRING(2),//限制字符个数 defaultValue: "0", //默认值 }, }, { freezeTableName: true, //开启自定义表名 tableName: "User",//表名字 timestamps: true, // 添加时间戳属性 (updatedAt, createdAt) createdAt: "createDate",// 将createdAt字段改个名 updatedAt: "updateDate",// 将updatedAt字段改个名 indexes: [{ // 索引 type: "UNIQUE", //UNIQUE、 FULLTEXT 或 SPATIAL之一 method: "BTREE", //BTREE 或 HASH unique: true, //唯一 //设置索引是否唯一,设置后会自动触发UNIQUE设置//true:索引列的所有值都只能出现一次,即必须唯一 fields: ["uuid"], //建立索引的字段数组。每个字段可以是一个字段名,sequelize 对象 (如 sequelize.fn),或一个包含:attribute (字段名)、length (创建前缀字符数)、order (列排序方向)、collate (较验的字段集合 (排序)) }], comment:"User Table",//数据库表描述 }); module.exports = User;//导出
表都写完后,新建index.js
** * 数据库表关系建立 */ var Mysql = require("./mysql"); //表 var AdminUser = require("./adminUser");//管理员表 var User = require("./user");//用户表 var UserInfo = require("./userInfo");//用户信息表 var Article = require("./article");//文章表 var Category = require("./category");//文章类别表 var Attachment = require("./attachment");//文章附件表 /** * 关系建立 */ //用户-用户资料 User.hasOne(UserInfo); //1:1 //用户-文章 User.hasMany(Article); //1:N Article.belongsTo(User); //1:1 //文章-分类 (定义中间表ArticleCategory 实现多对多) Article.belongsToMany(Category,{through: "ArticleCategory"}); //N:N Category.belongsToMany(Article,{through: "ArticleCategory"}); //N:N //基于sequelize自动创建表//【!!注意 首次执行完请注释掉该段代码 !!】 Mysql.sync({ force: true,//是否清空数据库表 }).then(function() { console.log("ok"); }); module.exports = { AdminUser: AdminUser, User: User, UserInfo: UserInfo, Article: Article, Category: Category, Attachment: Attachment, };
好。到这里,咱们咱们打开
blogNodejs/app.js 写入以下代码
/** * 主入口启动文件 * add by wwj * 2017-08-24 15:01:48 */ var express = require("express"); //web 框架 var logger = require("morgan"); //开发模式下log var bodyParser = require("body-parser"); //json var path = require("path"); //路径 var config = require("config-lite"); //读取配置文件 var winston = require("winston"); //日志 var expressWinston = require("express-winston"); //基于 winston 的用于 express 的日志中间件 var models = require("./models"); //临时添加 为了生成数据库表,后面写到Controllers里面 //实例化express var app = express(); // 设置模板目录 app.set("views", path.join(__dirname, "views")); // 设置模板引擎为 ejs app.set("view engine", "ejs"); // log app.use(logger("dev")); //设置json //格式化JSON的输出 app.set("json spaces", 2); // parse application/x-www-form-urlencoded app.use(bodyParser.urlencoded({ extended: false })); // parse application/json app.use(bodyParser.json()); // 设置静态文件目录 app.use(express.static(path.join(__dirname, "public"))); //注意:中间件的加载顺序很重要。如上面设置静态文件目录的中间件应该放到 routes(app) 之前加载,这样静态文件的请求就不会落到业务逻辑的路由里; //错误请求的日志 app.use(expressWinston.errorLogger({ transports: [ new winston.transports.Console({ json: true, colorize: true }), new winston.transports.File({ filename: "logs/error.log" }) ] })); // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get("env") === "development" ? err : {}; // render the error page res.status(err.status || 500); res.render("error"); }); //app module.exports = app;
执行一下
npm run dev
然后去mysql 下看看是否创建成功了(右击“表”-刷新)
到这里,咱们的数据库已经ok啦
下面学习了解些业务逻辑写法
// 字段类型 // STRING // CHAR // TEXT // INTEGER :A 32 bit integer. // BIGINT :A 64 bit integer. // FLOAT // REAL // DOUBLE // DECIMAL // BOOLEAN // TIME // DATE // BLOB //where $and: {a: 5} // AND (a = 5) $or: [{a: 5}, {a: 6}] // (a = 5 OR a = 6) $gt: 6, // > 6 $gte: 6, // >= 6 $lt: 10, // < 10 $lte: 10, // <= 10 $ne: 20, // != 20 $not: true, // IS NOT TRUE $between: [6, 10], // BETWEEN 6 AND 10 $notBetween: [11, 15], // NOT BETWEEN 11 AND 15 $in: [1, 2], // IN [1, 2] $notIn: [1, 2], // NOT IN [1, 2] $like: "%hat", // LIKE "%hat" $notLike: "%hat" // NOT LIKE "%hat" $iLike: "%hat" // ILIKE "%hat" (case insensitive) (PG only) $notILike: "%hat" // NOT ILIKE "%hat" (PG only) $like: { $any: ["cat", "hat"]} // LIKE ANY ARRAY["cat", "hat"] - also works for iLike and notLike $overlap: [1, 2] // && [1, 2] (PG array overlap operator) $contains: [1, 2] // @> [1, 2] (PG array contains operator) $contained: [1, 2] // <@ [1, 2] (PG array contained by operator) $any: [2,3] // ANY ARRAY[2, 3]::INTEGER (PG only) $col: "user.organization_id" // = "user"."organization_id", with dialect specific column identifiers, PG in this example { rank: { $or: { $lt: 1000, $eq: null } } } // rank < 1000 OR rank IS NULL { createdAt: { $lt: new Date(), $gt: new Date(new Date() - 24 * 60 * 60 * 1000) } } // createdAt < [timestamp] AND createdAt > [timestamp] { $or: [ { title: { $like: "Boat%" } }, { description: { $like: "%boat%" } } ] } // title LIKE "Boat%" OR description LIKE "%boat%"
CURD create result.dataValues; ======================== update result [1]; ======================== find - 从数据库中查找一个指定元素 - findById 按已知id查找 - findOne 按属性查找 result.dataValues ======================== findOrCreate - 从数据库中查找一个指定元素如果不存在则创建记录 ======================== findAndCountAll - 从数据库中查找多个元素,返回数据与记录总数 count - 整数,匹配到的总记录数 rows - 对象数据,通过 limit 和 offset匹配的当前页数据 { count: 0, rows: [] } findAndCountAll同样支持使用include包含,使用包含时只有将required设置为true才会添加到count部分: User.findAndCountAll({ include: [ { model: Profile, required: true} ], limit: 3 }); 使用include时,两个模型之间应该存在主/外键关系,如果不存在就应该在include中手工建立连接。 在上面的示例中,为Profile设置了required,所以在查询时会使用INNER JOIN内连接。 ======================== findAll - 从数据库中查找多个元素 // 查询时使用字符串替换 Project.findAll({ where: ["id > ?", 25] }).then(function(projects) { // projects 是一个包含 Project 实例的数组,各实例的id 大于25 }) ======================== count - 统计数据库中的元素数 max - 查找指定表中最大值 min - 查找指定表中最小值 sum - 对指定属性求和 ======================== destroy result项目实战(提前了解,后面可以再学到controller那一层的时候看代码学习使用) 新增 更新 查询单个 查询全部 模糊查询、分页、排序
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/104081.html
摘要:给上传文件重命名,获取添加后缀名允许最大层文件上传国际化工具类房源附件文件服务文件上传文件文件名相对路径对应值文件大小后面写到前端的时候再说怎么调用 multer文件上传 https://github.com/expressjs/... 在博客系统中会涉及到文件上传,这时候需要用到 multer文件上传 model层 /** * Attachment附件表 * @type {[t...
摘要:从本章开始,正式学习如何使用搭建一个博客。但通常我们都会有许多环境,如本地开发环境测试环境和线上环境等,不同的环境的配置不同,我们不可能每次部署时都要去修改引用或者。会根据环境变量的不同从当前执行进程目录下的目录加载不同的配置文件。 从本章开始,正式学习如何使用 Nodejs + Express + Mysql 搭建一个博客。 开发环境 首先说下开发环境安装的核心依赖版本: Node....
摘要:多一个技能多一条出路,祝你在自学道路上越走越好,掌握自己的核心技能,不只是优秀,还要成为不可替代的人 NodeJs+Express+Mysql + Vuejs 项目实战 最近准备写一系列文章,全面讲述如何基于NodeJs + Express + Mysql + Vuejs 从零开发前后端完全分离项目; 文笔及技术可能在某些方面欠佳,请您指正,共同学习进步 前端:Vuejs全家桶 后端:...
摘要:路由设计路由设计以用户注册为例介绍如何闭环用户注册开发注意点使用邮箱注册验证邮箱是否注册目前真实开发业务大部分都是手机号注册,这块由于没有购买短信服务首先,在文件夹下新建上图中对应真实业务逻辑现附上业务实现代码加密国际化工具类用户服务 路由设计 路由设计 以用户注册为例介绍如何闭环用户注册开发注意点:(1)使用邮箱注册(2)验证邮箱是否注册 【目前真实开发业务大部分都是手机号注册,这块...
阅读 1996·2021-09-30 09:53
阅读 1838·2021-09-24 09:48
阅读 1754·2019-08-30 14:01
阅读 2168·2019-08-29 18:35
阅读 1248·2019-08-26 18:27
阅读 2978·2019-08-26 12:12
阅读 941·2019-08-23 17:16
阅读 930·2019-08-23 15:31