node.js+mysql learning notes

Posted by FrOzeN on Wed, 12 Jan 2022 03:15:32 +0100

I'm almost finished. I've sorted out some nodes JS + MySQL notes.

fs module

fs common methods

const fs = require('fs')

// read file
// fs.readFile(path[, options], callback)  
// options: indicates the encoding format to read the file (optional). If not selected, it is output as a Buffer object
// Callback: after reading the file, get the read result through the callback function
fs.readFile('./files/1.txt', 'utf8', (err, dataStr) => {
    if(err) {
        return console.log(err) // If the reading succeeds, err = null, and fails, an error object is output
    }
    console.log(dataStr) // undefined if the read fails
})

// Write content
// fs.writeFile(file, data[, options], callback)
// File: file path string
// data: written content
// options: indicates the encoding format to write to the file (optional). If not selected, it is output as a Buffer object
// Callback: the callback function after the file is written
// Note:
// 1. When writing a file, the folder must exist, and the file may not exist. If the file does not exist, a new file will be created
// 2. When calling repeatedly, the newly written content will overwrite the previous old content
fs.writeFile('./files/1.txt', 'Go!', 'utf8', (err) => {
    if(err) {
        return console.log(err) // If the write succeeds, err = null, and fails, an error object is output
    }
    fs.readFile('./files/1.txt', 'utf8', (err, dataStr) => {
        if(err) {
            return console.log(err)
        }
        console.log('The data written is:' + dataStr)
    })
})

fs path dynamic splicing problem

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-hheehoox-1641953333866) (D: \ typera \ image-20220108171708425. PNG)]

// __ dirname indicates the directory where the current file is located
const fs = require('fs')

fs.readFile(__dirname + '/files/1.txt', 'utf8', (err, dataStr) => {
    if(err) {
        return console.log(err)
    }
    console.log(dataStr)
})

path module

const path = require('path')

// Splice full path string
// path.join()
const pathStr = path.join('/a', '/b/c', '../', '/d', 'e')
console.log(pathStr) // Output \ a\b\d\e, where '.. /' Will offset a layer of path 

const pathStr2 = path.join(__dirname, '/files/1.txt')
console.log(pathStr2) // Output the \ files \ 1.0 of the directory under the current path txt

// Resolve file name from path string
// path.basename(path[, ext])
// ext is the file extension
const fpath  = path.join(__dirname, '/files/2.txt')

let fullName = path.basename(fpath)
console.log(fullName) // Output 2 txt

let nameWithoutExt = path.basename(fpath, '.txt')
console.log(nameWithoutExt) // Output 2

// Gets the extension of the file in the path
// path.extname(path)
let ext = path.extname(fpath)
console.log(ext) // Output txt

http module

Port 80 in the URL can be omitted, and each port number cannot be occupied by multiple web services

// Create web server
const http = require('http')

// Create a web server instance
const server = http.createServer()

// Bind the request event for the server instance. This event will be triggered when you visit this web page
// Req request object: access data or attributes related to the client in the event handler function, such as req url request url address (/ followed by content, including '/') req Method request type
// res response object: access server related data or attributes in the event handler function
server.on('request', (req, res) => {
    console.log('Someone visit our web server!')
    const str = `Your request url is ${req.url == '/'? 'root directory': req.url}, and request method is ${req.method}.`   
    // Prevent response garbled code
    res.setHeader('Content-Type', 'text/html;  charset=utf-8')
    // Respond to client content
    res.end(str)
})

// Start the server
server.listen(80, () => {
    console.log('http server running at http://127.0.0.1')
})

http dynamic response content

// Create web server
const http = require('http')
const fs = require('fs')

// Create a web server instance
const server = http.createServer()

// Bind the request event for the server instance. This event will be triggered when you visit this web page
server.on('request', (req, res) => {
    const url = req.url
    // Optimize resource request path
    let fpath = ''
    if(url == '/'){
        fpath = path.join(__dirname, './clock/index.html')
    } else {
        fpath = path.join(__dirname, './clock', url)
    }
    fs.readFile(fpath, 'utf8', (err, dataStr) => {
        if (err) return res.end('<h1>404 Not found!</h1>')
        res.end(dataStr)
    })
})

// Start the server
server.listen(80, () => {
    console.log('http server running at http://127.0.0.1')
})

Node.js module

Node. Module scope in JS

The variables, methods and other members defined in the user-defined module can only be accessed in the current module. This module level access restriction is called module scope.

Members in the scope of the shared module need to use module Exports object

const username = 'wj'

function makeMoney() {
    console.log('30w')
}

// When the outside world uses the require() method to import a custom module, the result is module The object that exports points to
// Among them, using the require() method to load modules belongs to the CommonJS specification 
module.exports = {
    username,
    makeMoney
}

module.exports.income = '30w'
module.exports.go = () => {
    console.log('go!')
}
// Above module Exports can be replaced by exports. By default, they point to the same object
// a key:
// The final shared result is module The object pointed to by exports shall prevail
// Note:
// 1.module.exports = {} cannot be replaced by exports because if exports = {} is used, exports will point to another new object
// 2. If mixing is required, it is best to use only module exports. New1 and exports New2 form

Semantic version specification of package

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-goidedtg-1641953333867) (D: \ typera \ image-20220110161005639. PNG)]

npm switch package image source

npm config get registry
npm config set registry=https://registry.npm.taobao.org/

i5ting_toc is a gadget that converts md documents into html pages

i5ting_toc -f 'To convert md File path' -o

Module loading mechanism

After the module is loaded for the first time, the cache is destroyed. Calling require() multiple times will not cause the module's code to be executed multiple times.

Built in modules have the highest loading priority.

When using require() to load a custom module, you must specify and/ Or... / path identifier. If there is no node, it will be loaded as a built-in module or a third-party module.

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-1f9hv8qi-1641953333867) (D: \ typera \ image-20220110194741040. PNG)]

express Foundation

Create web server

const express = require('express')

// Create web server
const app = express()

// Start the web server
app.listen(80, () => {
    console.log('express server running at http://127.0.0.1')
})

Listen for GET requests and responses res.send()

/* app.get('Request URL ', (req, RES) = >{
    // Processing function
}) */

app.get('/user', (req,res) => {
    res.send({name:'wj', income:'30w'})
})

app.post('/user', (req,res) => {
    res.send('Request succeeded!')
})

Get the query parameter req carried in the URL query

app.get('/', (req,res) => {
    // req.query is used by the client? Name = WJ & income = 30W is a string form, and {} is used by default
    res.send(req.query)
})

Get the dynamic parameter req carried in the URL params

app.get('/:id/:name', (req,res) => {
    // req. Params: the URL address matches the dynamic parameter value in the form of parameter name
    // : id in id is req Property name of params object 
    // Write directly on request http://http://localhost/256/wj
    res.send(req.params) // Output JSON object {"id":"256","name":"wj"}
})

Managed static resource express static()

// Create a static resource server
// There is no need to add the level of public when accessing, and the folder can not be called public
// Multiple folders can also be managed, and the required files will be found according to the addition order of directories
app.use(express.static('public'))
app.use(express.static('clock'))

// You can mount the path prefix before the static resource accesses the path
// Later, if you need to access the files in the public folder, you must add the / public prefix. The prefix can be arbitrary. Generally, the directory name is used
app.use('/public', express.static('public')) // http://http://localhost/public/clock/index.html To access

express routing

Routing concept

express routing refers to the mapping relationship between the client's request and the server's processing function.

// app.METHOD(PATH, HANDLER)
app.get('/user', (req,res) => {
    res.send({name:'wj', income:'30w'})
})

app.post('/user', (req,res) => {
    res.send('Request succeeded!')
})
// All the above are routes
// The matching is performed in the order of routing

Modular routing

// The steps of route separation into separate modules are as follows js

// Create the corresponding routing module js file
const express = require('express')

// Call express The router() function creates a routing object
const router = express.Router()

// Mount a specific route to the routing object
router.get('/user/list', (req,res) => {
    res.send({name:'wj', income:'30w'})
})

// Use moudule Exports share routing objects outward
router.post('/user/add', (req,res) => {
    res.send('Request succeeded!')
})

// Use app The use() function registers the routing module
module.exports = router
// call
const express = require('express')
const app = express()
const userRouter = require('./router/router1')

app.listen(80, () => {
    console.log('express server running at http://127.0.0.1')
})

// app. The use() function registers the global middleware
// At the same time, you can add a routing prefix, which must be added when accessing
app.use('/api', userRouter)
// The get and post methods in userRouter are triggered upon request

express Middleware

Role of middleware: * * multiple middleware share a req and res** Based on this feature, custom attributes and methods can be added to req or res objects in upstream middleware for downstream middleware or routing.

[the transfer of external chain pictures fails. The source station may have an anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-S8RkLsQX-1641953333867)(D:\typora\image-20220110214414703.png)]

Middleware essence: function processing function

// The formal parameter list of the middleware function must contain the next function, while the routing processing function only contains req and res
app.get('/user', (req, res, next) => {
	next()
})
// next() indicates that the flow relationship is transferred to the next middleware or route

// Define middleware functions
// The constant mv points to a middleware function
const mw = function(req, res, next){
    // The middleware function must call the next() function to transfer the flow relationship to the next middleware or route
    next()
}

Global Middleware

// The middleware that will be triggered when any request from the client arrives at the server is called global middleware
// By calling app Use (middleware function) to define a global middleware
const mw = function(req, res, next){
    // The middleware function must call the next() function to transfer the flow relationship to the next middleware or route
    next()
}

app.use(mw)
// Flow relationship: after passing through one middleware, it will be transferred to the next middleware. If there is no middleware, it will be transferred to the router
// Middleware flows in defined order

// Simplified writing
app.use((req, res, next) => {
    next()
})

Local Middleware

// The middleware directly defined in the route is a local middleware, which only takes effect in the current route
app.get('/about', (req, res, next) => {
    next()
},(req, res) => {
    res.send('About Page')
})

// Multiple local middleware can be defined at one time, and the execution order is the order of definition
app.get('/', mw1, mw2, (req, res) => {})
app.get('/', [mw1, mw2], (req, res) => {})

5 considerations for Middleware

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-v9rwjg97-1641953333867) (D: \ typera \ image-20220111100358561. PNG)]

express middleware classification

Except for the middleware with error level, all other middleware shall be registered between routes!!!

Application level Middleware

// Via app Use () or app Get () or app Post (), the middleware bound to the app instance is called application level middleware
app.get('/about', (req, res, next) => {
    next()
},(req, res) => {
    res.send('About Page')
})

app.use((req, res, next) => {
    next()
})

Routing level Middleware

// Bind to express The middleware on the router () instance is called the routing level middleware, express Router () is a routing instance
const express = require('express')
const app = express()

const router = express.Router()

router.use((req, res, next) => {
    next()
})

app.listen(80, () => {
	console.log('http://127.0.0.1')
})

Error level Middleware

be careful!!! Error level middleware must be registered after all routes!!!

// Specifically catch the abnormal errors in the whole project, so as to prevent the abnormal collapse of the project
// And the error level middleware must contain four formal parameters
app.get('/', (req, res) => {
    throw new Error('Throw a error!')
    res.send('Home page.')
})

app.use((err, req, res, next) => {
    res.send('Error! ' + err.message)
})

express built-in Middleware

// 1.express.static is a built-in middleware for quickly hosting static resources, without compatibility problems
app.use(express.static('public'))

// 2.express.json parses the request body data in JSON format, which can only be used in version 4.16.0 +
app.use(express.json())

app.post('/user', (req, res) => {
    // On the server side, you can use req The body attribute is used to receive the request body data sent by the client
    // This middleware req is not added by default body = undefined
    console.log(req.body)
    res.send('ok')
})

// 3.express.urlencoded parses the request body data in URL encoded format, which can only be used in version 4.16.0 +
// URL encoded is a form format in the form of key value pairs
app.use(express.urlencoded({ extended: false }))

app.post('/book', (req, res) => {
    // This middleware req is not added by default body = {}
    console.log(req.body)
    res.send('ok')
})

Note:

Send JSON format request body data using postman:

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-ouxuzpue-1641953333868) (D: \ typera \ image-20220111110129048. PNG)]

Send request body data in URL encoded format using postman:

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-lznpx3wo-1641953333868) (D: \ typera \ image-20220111110100607. PNG)]

Third party Middleware

In express@4.16.0 In the past, the body parser third-party middleware was used to parse the request body data.

const parser = require('body-parser')
// Parsing request body data in URL encoded format
app.use(parser.urlencoded({ extended: false }))

Custom Middleware

// Modular -- > middleware js
// node.js has built-in querystring module, and parse() is specially used to query strings.
const qs = require('querystring')

function bodyParser(req, res, next) {
    // Listen to the data time of the req object to get the data sent by the client to the server
    // If the amount of data is too large to be sent at one time, the client will cut the data and send it to the server in batches, so the data event may be triggered multiple times
    // The data obtained by each trigger is only a part of the complete data, and the received data needs to be spliced manually
    let str = ''
    req.on('data', (chunk) => {
        // Splice request body data, implicitly converted to string
        str += chunk
    })
    // When the request body data is received, the end event of req will be triggered automatically
    req.on('end', () => {
        // At this time, str is the complete request body data
        const body = qs.parse(str)
        req.body = body
        next()
    })
}

module.exports = {
    bodyParser
}

/*-----------------------------------------------------*/

// Call -- > main js
const express = require('express')
const app = express()
const myBodyParser = require('./diymw')

app.use(myBodyParser.bodyParser)

app.post('/user', (req, res) => {
    res.send(req.body)
})

app.listen(80, () => {
    console.log('http://127.0.0.1')
})

Using express write interface

GET interface

// Module -- > apirouter js
const express = require('express')
const apiRouter = express.Router()

apiRouter.get('/get', (req, res) => {
    const query = req.query
    res.send({
        status: 0,   // Status, 0 indicates success and 1 indicates failure
        msg: 'GET Request succeeded', // State description
        data: query  // Specific data to the client is required
    })
})

module.exports = apiRouter

POST interface

const express = require('express')
const apiRouterPost = express.Router()

apiRouterPost.post('/post', (req, res) => {
    const body = req.body
    res.send({
        status: 0,  // Status, 0 indicates success and 1 indicates failure
        msg: 'POST Request succeeded', // State description
        data: body     // Specific data to be responded to the client
    })
})

module.exports = apiRouterPost

Call interface

const express = require('express')
const app = express()
const apiRouterGet = require('./apiRouter/apiRouterGet.js')
const apiRouterPost = require('./apiRouter/apiRouterPost.js')

// Note: when obtaining the request body data, you need to use middleware to parse it
app.use(express.json())
app.use(express.urlencoded({ extended: false }))

app.use('/api', apiRouterGet)
app.use('/api', apiRouterPost)

app.listen(80, () => {
    console.log('http://127.0.0.1')
})

Solve cross domain problems

// If the protocol, domain name or port number is different, there is a cross domain problem
// Solution
// 1.CORS (cross domain resource sharing) middleware must be registered before routing
// CORS is essentially a list of HTTP response headers
// CORS has compatibility problems. Only browsers that support XMLHttpRequest Level 2 can normally access the server interface with CORS enabled
const cors = require('cors')
app.use(cors())

/*
Extension:
1.CORS Response header access control allow origin
Access-Control-Allow-Origin: <origin> | *
The value of the origin parameter specifies the foreign domain URL that is allowed to access the resource
res.setHeader('Access-Control-Allow-Origin', 'http://www.baidu.com')

2.CORS Response header access control allow header
 By default, CORS only supports the client to send the following 9 request headers to the server:
Accept, Accept-Language, Content-Language, DPR, Downlink, Sava-Data, Viewport-Width, Width, Content-Type
 And the value is limited to one of text / plain, multipart / form data, application / x-www-form-urlencoded
 If the client sends additional request header information to the server, it needs to declare the additional request header on the server through access control allow header, otherwise the request will be invalid
res.setHeader('Access-Control-Allow-Header', 'Content-Type, X-Custom-Header')

3.CORS Response header access control allow methods
 By default, CORS only supports GET, POST and HEAD requests initiated by the client
 If you need to request the server's resources through PUT, DELETE, etc., you need to specify the allowed HTTP methods through access control allow methods
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, DElETE, HEAD')
res.setHeader('Access-Control-Allow-Methods', '*')

4.CORS classification
 Simple request: one of GET, POST and HEAD, and the header information does not exceed the following. There is no custom header field
Accept, Accept-Language, Content-Language, DPR, Downlink, Sava-Data, Viewport-Width, Width, Content-Type
 Pre inspection request:
(1) GET,POST,HEAD Requests other than
(2) The request header contains a custom header field
(3) Data in application/json format was sent to the server
 Before the browser formally communicates with the server, the browser will send an OPTION request for pre check to know whether the server allows the actual request. Therefore, this OPTION request is called "pre check request".
After the server successfully responds to the pre check request, it will send the real request and carry the real data.

*/

// 2.JSONP (only GET requests are supported)
// Concept: the browser side requests data on the server through the src attribute of the < script > tag, and the server returns a function call. This method is called JSONP
// jsonp interface
app.get('/api/jsonp', (req, res) => {
    // Gets the name of the callback function sent by the client
    const funcName = req.query.callback

    // Get the data to be sent to the client in the form of JSONP
    const data = { name: 'wj', age: 25 }

    // According to the data obtained in the first two steps, splice the string of a function call
    const scriptStr = `${funcName}(${JSON.stringify(data)})`

    // The string response obtained in the previous step is sent to the < script > tag of the client for parsing and execution
    res.send(scriptStr)
})

/*---------------------------------------------------*/

// JSONP request in jQuery
$('#btnJSONP').on('click', function () {
	$.ajax({
		method: 'GET',
		url: 'http://127.0.0.1/api/jsonp',
		dataType: 'jsonp',
		success(res) {
		console.log(res)
		}
	})
})

MySQL data types and fields

DataType data type:

(1) int shaping

(2) varchar(len) string

(3) tinyint(1) string

Special representation of fields:

(1) PK (Primary Key) Primary Key and unique ID

(2) NN (Not Null) value cannot be null

(3) UQ (Unique) value is Unique

(4) AI (Auto Increment) value increases automatically

SQL statement

SELECT

-- from FROM Query all data in the specified table
-- SELECT * FROM Table name
SELECT * FROM users;

-- from FROM In the specified table, query the data of the specified field
-- SELECT Column name FROM Table name
SELECT username, password FROM users;

-- use WHERE query
-- SELECT Column name FROM Table name WHERE Column operator value
SELECT * FROM users WHERE id <> 4;

-- use AND and OR operator
SELECT * FROM users WHERE id <> 2 AND username = 'wj';
SELECT * FROM users WHERE id > 2 OR id < 2;

-- SQL Keywords in statements( SELECT,FROM Etc.) case insensitive

INSERT INTO

-- Insert the following columns of data into the specified table, and the values of the columns are values One by one designation
-- Columns and values should correspond to each other one by one, and multiple columns and values should be separated by English commas
-- INSERT INTO table_name(Column 1, Column 2, ...) VALUES (Value 1, Value 2, ...)
INSERT INTO user (username, password) VALUES ('lmj', '7856');

UPDATE

-- Specify which table data to update
-- use SET Specifies the new value for the column
-- use WHERE Specify the conditions for the update
-- UPDATE Table name SET Column name = New value WHERE Column name = Certain value
UPDATE users SET password = '123789', status = 1 WHERE username = 'lmj01';

DELETE

-- From the specified table WHERE Delete the corresponding data row by condition
-- DELETE FROM Table name WHERE Column name = value
DELETE FROM users WHERE username = 'temp';

ORDER BY

-- ORDER BY Sort ascending by default
-- ASC Keywords represent ascending sort
SELECT * FROM users ORDER BY status;
SELECT * FROM users ORDER BY status ASC;
-- DESC Descending sort
SELECT * FROM users ORDER BY status DESC;

-- Multiple sorting
-- First according to status Sort in descending order, and then sort by username Sort alphabetically in ascending order
SELECT * FROM users ORDER BY status DESC, username ASC;

COUNT(*)

-- query users In the table status Total number of data pieces with 0
SELECT COUNT(*) FROM users WHERE status = 0;

AS

-- Remove column names from COUNT(*) Change to total
SELECT COUNT(*) AS total FROM users WHERE status = 0;
-- Ordinary columns can also be used
SELECT username AS uname, password as pwd FROM users WHERE status = 0;

mysql module configuration

const mysql = require('mysql')

// Establish a connection with MySQL
const db = mysql.creatPool({
    host: '127.0.0.1',
    user: 'root',
    password: 'admin123',
    database: 'my_db_01'
})

The mysql module executes sql query statements

// db.query() executes sql query statements
db.query('select * from users', (err, res) => {
    if (err) return console.log(err.message)
    console.log(res)
})

The mysql module executes sql insert statements

// db.query() executes sql add statement
const user = { username: 'Spider-Man', password: 'pcc321' }
// The sql statement to be executed, where? Represents a placeholder
const sqlStr = 'insert into users (username, password) values (?,?)'
// The array forms used are as follows:? Placeholders specify specific values
db.query(sqlStr, [user.username, user.password], (err, res) => {
    if (err) return console.log(err.message)
    if(res.affectedRows === 1) console.log('Insert data succeeded')
})

// If each attribute of the data object corresponds to the field of the data table one by one, you can quickly insert data in the following ways
const user = { username: 'Spider-Man', password: 'pcc321' }
const sqlStr = 'insert into users set ?'

db.query(sqlStr, user, (err, res) => {
    if (err) return console.log(err.message)
    if(res.affectedRows === 1) console.log('Insert data succeeded')
})

The mysql module executes sql update statements

// db.query() executes sql update statements
const user = {id: 3, username: 'znova01', password: '666666'}
const sqlStr = 'update users set username=?, password=? where id=?'

db.query(sqlStr, [user.username, user.password, user.id], (err, res) => {
    if (err) return console.log(err.message)
    if(res.affectedRows === 1) console.log('Data update succeeded')
})

// If each attribute of the data object corresponds to the field of the data table one by one, you can quickly update the data in the following ways
const user = {id: 3, username: 'znova01', password: '666666'}
const sqlStr = 'update users set ? where id=?'

db.query(sqlStr, [user, user.id], (err, res) => {
    if (err) return console.log(err.message)
    if(res.affectedRows === 1) console.log('Data update succeeded')
})

The mysql module executes sql delete statements

// db.query() execute sql delete statement
const sqlStr = 'delete from users where id=?'

db.query(sqlStr, 10, (err, res) => {
    if (err) return console.log(err.message)
    if(res.affectedRows === 1) console.log('Data deleted successfully')
})

// Mark deletion: set a status field like status in the table to mark whether the current data is deleted
// Instead of deleting the data, the user executes an update statement to mark the corresponding status field as deleted
const sqlStr = 'update users set status=1 where id=?'

db.query(sqlStr, 9, (err, res) => {
    if (err) return console.log(err.message)
    if(res.affectedRows === 1) console.log('Data deleted successfully')
})

Topics: Javascript node.js MySQL