koa使用數據庫mysql-pro/事務

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中
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容