功能梳理完了之後,我們就能夠開始數據庫表設計了:
數據庫表圖:html
首先打開Navicat Premium 建立數據庫 blognode
配置以下:mysql
課前學習:
一、Sequelize 中文API文檔【強烈推薦】 https://itbilu.com/nodejs/npm...
二、Sequelize 和 MySQL 對照
https://segmentfault.com/a/11...
三、使用Sequelize
http://www.liaoxuefeng.com/wi...
四、Sequelize API
https://sequelize.readthedocs...
五、關於「時間」的一次探索
https://segmentfault.com/a/11...
在blogNodejs/models 下web
首先新建 mysql.js 進行mysql鏈接配置(基於Sequelize)sql
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爲示例 單獨說下:express
/** * 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.jsnpm
** * 數據庫表關係創建 */ 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, };
好。到這裏,我們我們打開json
blogNodejs/app.js 寫入如下代碼segmentfault
/** * 主入口啓動文件 * 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