koa使用數據庫(mysql-pro,此模塊可以使用事務,占位符等功能)
//核心代碼
const koa = require('koa');
const pathlib = require('path');
const router = require('koa-router')
const mysql = require('mysql-pro');
//使用new來初始化mysql
const db = new mysql({
mysql:{
host:'localhost',
port:3306,
user:'root',
password:'root',
database:'koadb'
}
});
//初始化router
let r1 = router();
let server = new koa();//初始化koa
server.listen(8087);
server.use(r1.routes());
r1.get('/user',async ctx=>{
let id = ctx.request.query.id;//http://localhost:8087/user?id=1獲取?后面的參數id的值
try{
await db.startTransaction();//開啟事務
let data = await db.executeTransaction('select * from user');
let query = await db.executeTransaction('select * from user where id=?',[id]);//占位符,防止sql注入
await db.stopTransaction();//關閉事務,此處應該是提交事務
ctx.response.body=[data,query];
}catch(e){
ctx.response.body='出錯';
}
})
知乎實戰(zhàn)項目(往數據庫導入數據)
//將數據導入mysql的核心代碼
const fs=require('fs');//文件模塊
const Mysql=require('mysql-pro');//數據庫模塊
//創(chuàng)建數據庫連接信息
const db=new Mysql({
mysql: {
host: 'localhost',
port: 3306,
user: 'root',
password: 'root',
database: 'zhihu'
}
});
//讀取.topics數據文件,讀出為二進制文件,toString方法轉化為string;使用json.parse函數將json字符串轉化為對象
const arr=JSON.parse(fs.readFileSync('.topics').toString());
//創(chuàng)建數據庫的映射對象,以及初始ID
let topics={}, topic_ID=1;
let authors={}, author_ID=1;
let questions={}, question_ID=1;
let answers={}, answer_ID=1;
// console.log(arr[0]);
//循環(huán)讀取的數據文件
arr.forEach(question=>{
//topic,每個問題的標簽,每個問題有多個標簽,我們的數據庫表中,topic表只有id與title
question.topics=question.topices.map(json=>{
let {title}=json;//解構賦值,json中有title與url,此處獲取title
title=title.replace(/^\s+|\s+$/g, '');//將title中前后空格處理掉
//判讀如果topics中沒有title,便設置該title對應的id即topic_ID++;
if(!topics[title]){
topics[title]=topic_ID++;
}
return topics[title];//return 當前question中的topics的title的值
}).join(',');//將topics用逗號分隔,返回字符串
//author,作者,取最佳回答中的作者與其他回答中的所有作者,此處用剩余參數(見1-11筆記);
[question.bestAnswer.author, ...question.answers.map(answer=>answer.author)].forEach((author,index)=>{
let old_id=author.id;//最佳答案的作者id
//判讀如果authors中沒有當前作者id,便設置該作者的id對應的author對象;
if(!authors[old_id]){
authors[author.id]=author;
author.id=author_ID++;//把原author對象的id設置為我們的定義的ID
if(index==0){
//delete 操作符用于刪除對象的某個屬性;如果沒有指向這個屬性的引用,那它最終會被釋放。
delete question.bestAnswer.author;//刪掉原有的對象
question.bestAnswer.author_ID=author.id;//用對象ID代替
}else{
delete question.answers[index-1].author;
question.answers[index-1].author_ID=author.id;
}
}
return authors[old_id];//return 原始ID的值
});
//question
let ID=question_ID;
questions[question_ID++]=question;//直接將問題復制給id
// console.log(questions);
//answers,同上,循環(huán)賦值給id
[question.bestAnswer, ...question.answers].forEach(answer=>{
answer.id=answer_ID;
answer.question_ID=ID;
answers[answer_ID++]=answer;
});
});
(async()=>{
function dataJoin(...args){
return "('"+args.map(item=>{
item=item||'';
item=item.toString().replace(/'/g, '\\\'');
return item;
}).join("','")+"')";
}
//topics
let aTopics=[];
for(let title in topics){
let ID=topics[title];
aTopics.push(dataJoin(ID, title));
}
let topic_sql=`INSERT INTO topics VALUES${aTopics.join(',')}`;
//authors
let aAuthors=[];
for(let id in authors){
let author=authors[id];
aAuthors.push(dataJoin(author.id, author.type, author.name, author.gender, author.userType, author.img_url, author.headline, author.followerCount));
}
let author_sql=`INSERT INTO author VALUES${aAuthors.join(',')}`;
//questions
let aQuestions=[];
for(let ID in questions){
let question=questions[ID];
// console.log(ID);
aQuestions.push(dataJoin(ID, question.title, question.question_content, question.topics, question.attention_count, question.view_count, question.bestAnswer.id));
}
let question_sql=`INSERT INTO question VALUES${aQuestions.join(',')}`;
//answers
let aAnswers=[];
for(let ID in answers){
let answer=answers[ID];
// console.log(answer.author_ID);
aAnswers.push(dataJoin(ID,answer.author_ID, answer.question_ID, answer.content, answer.createdTime));
}
let answer_sql=`INSERT INTO answer VALUES${aAnswers.join(',')}`;
//插入數據
// await db.startTransaction();
// await db.executeTransaction(topic_sql);
// await db.executeTransaction(author_sql);
// await db.executeTransaction(question_sql);
// await db.executeTransaction(answer_sql);
// await db.stopTransaction();
//將數據打印到文件中
// fs.writeFileSync('topic_sql',topic_sql,'utf8')
// fs.writeFileSync('author_sql',author_sql,'utf8')
// fs.writeFileSync('question_sql',question_sql,'utf8')
// fs.writeFileSync('answer_sql',answer_sql,'utf8')
console.log('完成');
})();
擴展
事務
事務擁有ACID四個特性
A 原子性;只會全部發(fā)生或者全部不發(fā)生;
C 持久性;只要事務提交了,就是永久性生效的;
I 隔離性;各個事務之間是獨立的;
D 一致性;食事務前后狀態(tài)是一致的;
控制臺命令 >
node a.js>a.txt
運行a.js將js中consloe.log的內容打印到a.txt中