koa2後臺步驟(5)——sequelize操作數據庫

orm的方式:
數據表使用js的模型 (class或者對象) 來代替
一條或多條記錄,用js的一個對象或者數組替代
sql語句用對象的方法代替。

拋開後臺項目,新建文件夾sequelize-test

npm init -y
npm i mysql2 sequelize -d

查看package.json

 "dependencies": {
	    "mysql2": "^2.0.2",
	    "sequelize": "^5.21.2"
  }

ps: 參考https://www.npmjs.com/package/mysql2,思考在不使用orm工具時候如何連接數據庫,如何操作數據庫。

git config --global core.autocrlf false 可以解決一個報錯

新建src文件夾下新建文件seq.js 參考getting-started

創建sequelize模型,連接數據庫

const Sequelize = require('sequelize');
const conf = {
  host: 'localhost',
  dialect: 'mysql'
}
const seq = new Sequelize('flyingfish_db', 'root', '950210zsrtxdy', conf)
module.exports = seq
// 接下來就可以使用這個實例進行模型創建以及查詢等操作

測試連接,註釋掉module.exports = seq
在seq.js文件夾下方添加如下代碼

seq
  .authenticate()
  .then(() => {
    console.log('Connection has been established successfully.');
  })
  .catch(err => {
    console.error('Unable to connect to the database:', err);
  });

運行src/seq.js
在這裏插入圖片描述

創建模型
新建model.js

const Sequelize = require('sequelize')
const seq = require('./seq.js')
// 創建 User 模型,雖然下面是user,但是數據表的名字會變成users
const User = seq.define('user', {
    // id會自動創建並設爲主鍵,並且自增
    userName: {
      type: Sequelize.STRING,  //varchar(255)
      allowNull: false  //不能爲空
    },
    password: {
      type: Sequelize.STRING,
      allowNull: false
    },
    nickName: {
        type: Sequelize.STRING,
        comment:'暱稱'
        // allowNull defaults to true
    }
// 自動創建createdAt和updatedAt
  }, {
    // options
  });
  module.exports = { User }

新建sync.js

const seq = require('./seq.js')

require('./model.js')

// 3 測試連接
seq.authenticate()
    .then(() => {
        console.log('Connection has been established successfully.');
    })
    .catch(err => {
        console.error('Unable to connect to the database:', err);
    });

// 4 執行同步
seq.sync({force: true}).then(()=>{
    console.log('sync ok')
    process.exit() //不退出sequelize會一直佔用進程
})

在這裏插入圖片描述
自動生成的
在這裏插入圖片描述
在添加comment之後。
在這裏插入圖片描述
接着創建blog

const Blog = seq.define('blog', {
    title: {
        type: Sequelize.STRING,
        allowNull: false
    },
    content: {
        type: Sequelize.TEXT,
        allowNull: false
    },
    userId: {
        type: Sequelize.INTEGER,
        allowNull: false
    },
})

輸出

module.exports = { User, Blog }

在這裏插入圖片描述
總結: 連接數據庫 —— 創建數據模型 —— 測試連接 ——執行同步

創建外鍵的代碼
在model.js裏

// 外鍵關聯
Blog.belongsTo(User,{
    // 創建外鍵 Blog.userId -> User.id 是一個多對一的關係。
    foreignKey: 'userId'
})

還有Blog.belongsTo(User)這種寫法,
我們需要把之前創建Blog模型的userId這一項給去掉,其實User的id還有Blog的userId都可以自動生成的。(這種寫法並不推薦,不明顯)

創建外鍵的兩種用法

// 外鍵關聯
Blog.belongsTo(User,{
    // 創建外鍵 Blog.userId -> User.id 是一個多對一的關係。
    foreignKey: 'userId'
})
// 創建外鍵的另一種方式
User.hasMany(Blog,{
    // 創建外鍵 Blog.userId -> User.id 是一個一對多的關係。
    foreignKey: 'userId'
})

爲什麼要兩個一起寫呢?因爲可以誰在前面誰就可以優先索引。
測試
在這裏插入圖片描述
這裏有一個問題就是爲什麼從users裏面看不到外鍵,而從blogs裏面可以看得到?
畫一下ER圖,navicat怎麼畫ER圖?
選擇report 然後點擊右下角的在這裏插入圖片描述
就可以看到ER圖:
在這裏插入圖片描述
怎麼導出爲pdf以後再想吧。

插入數據
新建create.js文件
IO操作是異步操作,使用async和await

// insert 語句
const { Blog, User } = require('./model.js')
// ! 表示忽略之前的出現錯誤,隔開下面的代碼,是自保的一種方法。
!(async function(){
    // 創建用戶,通過create的方式插入一條新的數據
    const zhangsan = await User.create({
        userName: 'zhangsan',
        password: '123',
        nickName: '張三'
    })

    console.log('zhangsan: ',zhangsan.dataValues)
	console.log('zhangsanId: ',zhangsan.dataValues.id)
	const lisi = await User.create({
        userName: 'lisi',
        password: '123',
        nickName: '李四'
    })
    console.log('lisiId: ',lisi.dataValues.id)
    const blog1 = await Blog.create({
       title:'標題1',
       content:'內容1',
       userId:zhangsan.dataValues.id
    })
    const blog2 = await Blog.create({
        title:'標題2',
        content:'內容2',
        userId:lisi.dataValues.id
     })
     const blog3 = await Blog.create({
        title:'標題3',
        content:'內容3',
        userId:lisi.dataValues.id
     })
     console.log('blog1: ',blog1.dataValues) 
     console.log('blog2: ',blog2.dataValues) 
     console.log('blog3: ',blog3.dataValues) 
})()

查詢數據
新建一個select.js

查詢單條數據

const { User, Blog } =require('./model.js') 
!(async function(){
// 查詢一條記錄
const zhangsan = await User.findOne({
	where:{
		userName:'zhangsan'
	}
})
console.log('zhangsan:',zhangsan.dataValues)
// 查詢特定的列項
const zhangsanColumns = await User.findOne({
	attributes: ['userName','nickName'],
	where:{
		userName:'zhangsan'
	}
})
console.log('zhangsanColumns:', zhangsanColumns.dataValues)
})()

查詢一個列表

const zhangsanBlogList = await Blog.findAll({
	where:{
		userId:2
	},
	order:[
		['id','desc']
	]
})

想想怎麼輸出這個zhangsanBlogList

zhangsanBlogList.forEach(item=>{
	console.log(item.dataValues)
})

還有這種

console.log('zhangsanBlogList :', zhangsanBlogList.map(blog=>
	blog.dataValues
))

map後面是怎麼寫的。
分頁

const zhangsanBlogList = await Blog.findAll({
	limit:2,
	offset:0,
	where:{
		userId:2
	},
	order:[
		['id','desc']
	]
})
console.log('zhangsanBlogList :', zhangsanBlogList.map(blog=>
	blog.dataValues
))

查詢總數

const blogListAndCount = await Blog.findAndCountAll({
	limit:2,
	offset:0,
	order:[
		['id','desc']
	]
})
console.log(blogListAndCount.count,
	blogListAndCount.rows.map(blog=>blog.dataValues))

連表查詢依賴於之前做的外鍵關聯
爲什麼外鍵關聯要兩個一起寫?
連表查詢1

// 需要找出blog列表,而且每一條需要包含作者的名字和暱稱
const blogListWithUser = await Blog.findAndCountAll({
	order:[
		['id','desc']
	],
	include:[{
		model:User,
		attributes:['userName','nickName'],
		where:{
			id:2
		}
	}]
		
	
})
console.log(blogListWithUser.count, 
	blogListWithUser.rows.map(blog=>{
		const blogVal = blog.dataValues;
		const userVal = blogVal.user.dataValues;
		blogVal.user = userVal
		return blogVal
	}))

連表查詢2

在這裏插入圖片描述

每個博客對應一個用戶,一個用戶對應多個博客,從用戶表做索引的話
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
更新
更新用戶暱稱
在這裏插入圖片描述
這個是返回結果
在這裏插入圖片描述
如果這個修改元素的第一個數大於0就是修改成功了。
在這裏插入圖片描述

在這裏插入圖片描述
刪除一個用戶的話也會把他對應的文章給刪除掉,因爲已經做了外鍵關聯了,他們之間有刪除的關係
因爲外鍵不是我們自己建的,它會自動的restrict模式,不一定能夠刪除成功
在這裏插入圖片描述
所以我們試着刪一下,不成功可以再改
在這裏插入圖片描述
在這裏插入圖片描述
刪除更新遇到問題如果是跟外鍵有關,就可以去可視化操作界面
在這裏插入圖片描述
連接池:
問:什麼是連接池? 連接池是數據庫本身的機制,連接池本身存在在內存或進程中提供了很多現成的連接
問:線上環境怎麼實現連接池(pool),其中的max和min的參數的意義?idle參數的意思?如果一個連接池多長時間內沒有被使用,被釋放

conf.pool = {
	max:5,
	min:0,
	idle:10000 //10s
}

問:怎麼判斷線上環境還是線下環境?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章