8Java script CHAPTER การทำ� งานกบั ระบบฐานขอ้ มลู Mongo เนื้อหาในบทนี้เป็นการใช้งานเฉพาะระบบฐานข้อมูล Mongo เพียงอย่างเดียวเท่านั้น เพ่ือให้ รูจ้ กั คำ�ส่ังต่างๆ และวธิ ีการจัดการข้อมูลในฐานข้อมูลเทา่ ทจ่ี ำ�เป็นต้องศกึ ษาใชง้ าน ก่อนทจ่ี ะ น�ำ ไปใช้งานรว่ มกับ Express ในล�ำ ดับต่อไป การดาวน์โหลดและตดิ ตง้ั ตวั จดั การฐานขอ้ มลู Mongo ดว้ ย Robo 3T จากเนอ้ื หาของบททแี่ ลว้ ผเู้ ขยี นน�ำ เสนอวธิ กี ารท�ำ งานกบั ระบบฐานขอ้ มลู Mongo ในขน้ั ตน้ ด้วยวธิ ปี ้อนคำ�สัง่ Command Line ซงึ่ เปน็ วธิ ที ี่มากับตวั ระบบฐานขอ้ มูล Mongo โดยตรง คำ�ส่งั พนื้ ฐานที่ส�ำ คญั มี 2 สว่ น ดังนี้ ÂÂ คำ�สั่ง “mongo” หมายถึง สัง่ ให้บรกิ ารฐานขอ้ มูล Mongo ท�ำ งาน ÂÂ คำ�สง่ั “use ชอื่ ฐานข้อมลู ” หมายถึง เราต้องการท�ำ งานกบั ฐานข้อมลู ท่ชี อื่ ว่าอะไร เป็นรูปแบบการทำ�งานกับระบบฐานข้อมูล Mongo ที่เราไม่ได้ใช้โปรแกรมหรือเครื่อง มือใดๆ ช่วยเหลือ เป็นวิธกี ารท�ำ งานท่ตี อ้ งทราบและต้องใช้งานให้เปน็ ส�ำ หรบั หวั ขอ้ นี้ ผเู้ ขยี นขอแนะน�ำ โปรแกรมทช่ี อื่ วา่ “Robo3T”(หรอื ชอื่ เดมิ Robomongo) มหี นา้ ทีจ่ ดั การระบบฐานข้อมูล Mongo ในรูปแบบทีม่ หี นา้ จอแบบ GUI เหน็ รปู ร่างเหน็ หน้าตา ระบบฐานข้อมูลชดั เจน ช่วยใหเ้ ราท�ำ งานกับฐานขอ้ มูลง่ายขึ้น ตวั โปรแกรมท่ใี ชจ้ ัดการข้อมูลใหก้ บั ระบบฐานข้อมูล Mongo มหี ลายตวั ผูเ้ ขียนเลอื ก นำ�เสนอเพียงตวั เดียว เพราวา่ ใชง้ านง่ายไมซ่ บั ซ้อน .Net HTML HTML
การใชง้ านตัวโปรแกรม Robo 3T กับระบบฐานข้อมูล Mongo มขี น้ั ตอนดังนี้ 1. ให้ไปท่เี วบ็ https://robomongo.org/ เพอ่ื ดาวน์โหลดตวั ตดิ ตงั้ Robo 3T เวอรช์ นั ล่าสุดเท่าท่ีมอี ยูม่ าใชง้ านไดฟ้ รี ดังรปู ท่ี 8-1 รูปท ี่ 8-1 แสดงการดาวนโ์ หลด Robo 3T เวอรช์ นั ลา่ สดุ เทา่ ทมี่ อี ยู่ 2. ตอ่ มา ใหด้ บั เบลิ้ คลิกทีไ่ ฟล์ตดิ ตั้ง โดยใชค้ ่าเริ่มต้นที่มากับตวั ตดิ ตง้ั ทง้ั หมด ดังรูป ท่ี 8-2 รูปท ่ี 8-2 แสดงการตดิ ตง้ั Robo 3T สมบรู ณแ์ ลว้ การเชือ่ มตอ่ Robo 3T เขา้ กบั ระบบฐานข้อมูล Mongo หลังจากท่ีติดตั้ง Robo 3T แล้ว ให้เปิดตัวโปรแกรมข้ึนมาเพ่ือเชื่อมต่อกับฐานข้อมูล Mongo ท่ีเรามีอยู่ ในกรณนี ้ีผู้เขียนมฐี านขอ้ มูลที่ช่อื วา่ myshops เพยี งตวั เดียว มขี ้ันตอนดังน้ี 1. ทีห่ น้าจอเรม่ิ ต้นของโปรแกรม Robo 3T ให้เลือกคำ�สั่ง Create เพ่ือสรา้ งการเชือ่ ม ตอ่ กบั ฐานข้อมูล Mongo ภายในเครอ่ื งของเราเอง ในกรณนี เ้ี ป็นการติดตัง้ Robo 3T คร้ังแรก จงึ ไม่มีการเชอ่ื มต่อใดๆ ทงั้ ส้นิ 146
CHAPTER 8 การทำ�งานกับระบบฐานข้อมลู Mongo รูปที ่ 8-3 แสดงการเรมิ่ ตน้ เชอ่ื มตอ่ Robo 3T เขา้ กับฐานขอ้ มลู Mongo 2. ต่อมา ให้ต้ังช่ือการเช่ือมต่อ ในกรณีน้ีตื้งชื่อว่า “MyConnection” ช่ือท่ีตั้งในข้ัน ตอนนี้เป็นของโปรแกรม Robo 3T ใช้กับฐานข้อมูล Mongo ไม่มีความเก่ียวข้อง ใดๆ กับโปรเจก็ ต์ Express ทงั้ สิ้น เราต้องการเชอ่ื มต่อกบั ฐานขอ้ มลู Mongo ทีอ่ ยู่ ภายในเคร่อื งของเราเอง จึงระบุว่า “localhost” ทำ�งานทพี่ อร์ต 27017 คลกิ ที่ปุ่ม เพื่อบนั ทกึ การเชอื่ มต่อนเ้ี อาไว้ รปู ท่ ี 8-4 ตง้ั ชอ่ื การเชอื่ มตอ่ นว้ี า่ “MyConnection” 3. ตอ่ มา หลังจากท่ีสรา้ งการเช่อื มตอ่ Robo 3T เข้ากับระบบฐานข้อมูล Mongo แลว้ ให้คลิกท่ีปุ่ม ถ้าการเช่ือมต่อสมบูรณ์ เราจะเห็นรายการฐานข้อมูล Mongo ทม่ี อี ยู่ ในกรณีน้คี ือฐานขอ้ มูลที่ชือ่ ว่า myshops ภายในมีเพยี งคอลเล็กชนั เดยี ว ชอ่ื ว่า books ตามทเ่ี ราสร้างไวใ้ นบททแ่ี ลว้ ดงั รูปที่ 8-5 รูปที่ 8-5 แสดงโครงสร้าง ฐานข้อมลู myshops ใน Robo 3T ScJraivpat 147
การกำ�หนดรปู แบบแสดงผลใน Robo 3T โครงสรา้ งการจดั เกบ็ ขอ้ มลู ในฐานขอ้ มลู Mongo อยใู่ นรปู แบบJSON ทเี่ ราเปน็ ผกู้ �ำ หนด โครงสรา้ งขอ้ มลู ข้ึนมาเกบ็ ข้อมูลเอง เรยี กไดใ้ นอกี ฐานะหน่งึ ว่า Documents เม่ือเชื่อมต่อ Robo 3T เข้ากับฐานข้อมูล Mongo แสดงผลในรูปแบบ GUI ท่ีเราคุ้น เคยมากกว่าในรูปแบบ Command Prompt เราสามารถกำ�หนดรูปแบบแสดงผลข้อมูลได้ 3 แบบ ดงั นี้ 1. รูปแบบ List โดยการคลกิ ท่ปี ุ่ม เพอื่ แสดงคอลเลก็ ชัน books แบบรายการ List ดงั รปู ท่ี 8-6 รปู ที ่ 8-6 แสดงคอลเลก็ ชนั books แบบ List จากรปู ที่ 8-6 Colection ทช่ี ือ่ ว่า books ในปัจจบุ ัน มขี อ้ มลู หนังสอื 3 รายการ แยก ตาม ObjectId 2. รูปแบบตาราง โดยการคลิกที่ปุม่ การแสดงข้อมูลในรปู แบบตาราง เราค้นุ เคย กันเป็นอย่างดีในฐานข้อมูล RDBMS สิ่งที่เห็นเป็นเพียงแค่รูปแบบแสดงผลวิธีหน่ึง เท่านน้ั แตโ่ ครงสร้างการจดั เกบ็ ข้อมูลเป็นแบบ JSON รปู ท่ ี 8-7 แสดงคอลเล็กชัน books แบบตาราง จากรปู ท่ี 8-7 ผ้อู ่านทเ่ี คยใชร้ ะบบฐานขอ้ มูลแบบ RDBMS เช่น Access, SQL Server จะ ค้นุ เคยกบั การแสดงข้อมลู ในรูปแบบตาราง 148
CHAPTER 8 การทำ�งานกบั ระบบฐานข้อมลู Mongo 3. รูปแบบ Documents โดยการคลิกที่ปุ่ม เป็นการแสดงผลที่มีรูป แบบเหมือนกับวิธีการจัด เกบ็ ข้อมูลมากท่สี ุด รูปที ่ 8-8 แสดงคอลเล็กชัน books แบบ Documents การแสดงข้อมูลหนังสือท้ัง 3 รูปแบบ เกิดมาจากคำ�ส่ังเรียกดูข้อมูลแบบไม่มีเง่ือนไข ดงั ตอ่ ไปน้ี Mongo Command 1 db.getCollection(‘books’).find({}) การเพม่ิ ข้อมลู (Insert Document) ในคอลเลก็ ชัน ในกรณีท่ีต้องการเพิ่มข้อมูลชุดใหม่ (Document) เข้าไปไปคอลเล็กชันท่ีเรามีอยู่ สามารถทำ�ไดเ้ ช่นกนั มีขัน้ ตอนดังน้ี 1. ผู้เขียนมคี อลเล็กชันเดียว ชื่อว่า books ตอ้ งการเพิ่มข้อมลู หนังสือเลม่ ใหม่ ใหค้ ลิก ขวาเลือกค�ำ สงั่ Insert Document… จากน้นั ป้อนขอ้ มลู ทมี่ โี ครงสร้าง JSON ตรง กบั โครงสร้างขอ้ มลู เดิมทมี่ ีอยู่ ในกรณนี ้ี คอื hh ฟิลด์ isbn ก�ำ หนดค่า 4444 hh ฟลิ ด์ title กำ�หนดค่า “พ้นื ฐานการเขยี นโปรแกรมดว้ ย C# 7” hh ฟิลด์ price ก�ำ หนดคา่ 275 JSON 1{ 2 isbn : ‘4444’, 3 title: ‘พนื้ ฐานการเขียนโปรแกรมดว้ ย C# 7’, 4 price: 275 5} ScJraivpat 149
รูปที ่ 8-9 แสดงการเพมิ่ Document ใหม่ จากรูปท่ี 8-9 สามารถคลกิ ท่ีปมุ่ เพอ่ื ตรวจสอบก่อนวา่ โครงสร้าง JSON ที่ เราป้อนเข้ามา ถกู ตอ้ งตามหลักหรอื ไม่ 2. ต่อมา ให้คลิกทป่ี ุ่ม เพือ่ เพ่มิ ข้อมูลหนังสือปัจจุบัน เข้าไปเก็บไว้ใน คอลเลก็ ชัน books ดงั รูปที่ 8-10 รูปที ่ 8-10 กรณีบันทึกข้อมูลหนังสือใหม่ เสร็จ สมบูรณ์แล้ว จากรูปที่ 8-10 ใหล้ องดูข้อมูลหนังสอื ใหมอ่ ีกคร้ัง พบวา่ เรามีข้อมลู หนังสือ 4 รายการ แลว้ ผเู้ ขยี นเพ่มิ ข้อมลู หนังสือใหม่เขา้ มาอกี 2 รายการ รวมท้ังสิน้ มี 6 รายการ ดังรูปท่ี 8-11 รปู ท ี่ 8-11 แสดงข้อมูลหนังสือเท่าที่มีอยู่ใน คอลเลก็ ชนั books การลบขอ้ มูล (Remove Document) ออกจากคอลเล็กชนั ในกรณที ตี่ อ้ งการลบขอ้ มูล Document ออกจากคอลเลก็ ชนั มขี ัน้ ตอนดงั นี้ 1. ท่ีคอลเล็กชนั books ให้คลกิ ขวาเลือกค�ำ ส่งั Remove Documents… ในกรณีนีผ้ ู้ เขยี นตอ้ งการลบขอ้ มูลหนังสือทีม่ ีรหสั isbn เทา่ กับ 6666 ให้ป้อนคำ�ส่ังตอ่ ไปนี้ Mongo Command Prompt 1 db.getCollection(‘books’).remove({ ‘isbn’ : ‘6666’ }); 150
CHAPTER 8 การท�ำ งานกับระบบฐานข้อมลู Mongo รปู ท ่ี 8-12 กรณลี บขอ้ มลู หนงั สอื รหสั isbn เทา่ กบั 6666 2. ทา้ ยทีส่ ุด ใหค้ ลกิ ที่ปุ่ม เพือ่ รันค�ำ สง่ั ลบขอ้ มลู หนงั สอื 1 รายการ ผลการท�ำ งาน แสดงดงั รูปที่ 8-13 รปู ท ่ี 8-13 หนังสือรหัส isbn 6666 ถูกลบออกไป จากคอลเล็กชนั books แลว้ การอพั เดตหรือแก้ไข Document (Update Document) ในคอลเล็กชัน การอัพเดตหรือแกไ้ ขข้อมลู ทถ่ี กู เก็บอยู่ในรูปแบบ JSON มีสิ่งที่ต้องให้ความส�ำ คัญก็คือ “ขอ้ มลู ทจี่ ะแกไ้ ข ตอ้ งมขี อ้ มลู เดมิ อยดู่ ว้ ย” เราตอ้ งไมล่ มื วา่ รปู แบบการจดั เกบ็ ขอ้ มลู ของJSON มีความยดื หยนุ่ มอี ิสระเป็นอยา่ งมาก เพราะว่าโครงสร้างข้อมลู ทจ่ี ัดเก็บเปน็ ไปตามท่ีเราเป็นผู้ ออกแบบเองก�ำ หนดเองทั้งสิน้ มีขน้ั ตอนดงั นี้ 1. ใหค้ ลกิ ขวาทค่ี อลเลก็ ชนั books เลอื กค�ำ สง่ั UpdateDocuments… แกไ้ ขขอ้ มลู หนงั สอื รหสั isbn 1111 จากราคาเดมิ (ฟลิ ด์ price) ใหเ้ ปน็ ราคาใหม่ 299 ดงั สครปิ ตต์ อ่ ไปน้ี Mongo Command Prompt 1 db.{getCollection(‘books’).update( 2 “isbn” : “1111” }, 3 { 4 $set: {“price” : 299} 5 }, 6 { 7 “multi” : false, 8 “upsert” : false 9 } 10 11 ); 12 ScJraivpat 151
รปู ที่ 8-14 แสดงการแกไ้ ขขอ้ มลู หนงั สอื รหสั isbn 1111 จากรูปท่ี 8-14 ให้คลิกที่ปุ่ม เพือ่ แกไ้ ขราคาหนังสือ (ฟิลด์ price) ใหเ้ ปน็ ราคา 299 2. ต่อมา ถ้าสคริปต์ที่เราป้อนถูกต้อง ตรงตามโครงสรา้ งท่ีจดั เกบ็ ก็จะได้ ราคาหนังสือใหม่ตามที่กำ�หนดไว้ ดงั รูปที่ 8-15 รปู ท่ี 8-15 แสดงราคาทถ่ี กู แกไ้ ขแลว้ 3. ตอ่ มา มกี ารแกไ้ ขข้อมลู อีกวิธหี นึ่ง คือ หากต้องการแก้ไขข้อมลู Document ใด ให้ คลิกขวาที่ Document น้ันๆ แล้วเลือกคำ�สั่ง Edit Document... โดยตรงได้เลย ดังรูปที่ 8-16 รปู ที่ 8-16 แสดงการแกไ้ ขขอ้ มลู เฉพาะ Document ทสี่ นใจ 152
CHAPTER 8 การท�ำ งานกบั ระบบฐานขอ้ มูล Mongo รูปที ่ 8-17 แสดงขอ้ มลู หลงั แกไ้ ข อธิบายการทำ�งานของสคริปต์ 1. ให้ใชเ้ มธอด update() เขา้ มาท�ำ หน้าทอี่ พั เดตขอ้ มูล โดยการระบกุ ่อนเลยวา่ เรา ตอ้ งแกไ้ ขขอ้ มูลหนงั สอื ท่ีมรี หัส isbn เทา่ กับ 1111 เทา่ นั้น Mongo Command Prompt 1 db.getCollection(‘books’).update( 2{ 3 “isbn” : “1111” 4 }, 2. ตอ่ มา ใช้ค�ำ ส่ัง $set เขา้ มาท�ำ หน้าท่กี ำ�หนดว่า เราต้องแก้ไขขอ้ มูลฟิลดใ์ ด ในกรณี นคี้ ือ ฟลิ ด์ price กำ�หนดค่าใหมเ่ ปน็ 299 Mongo Command Prompt 1{ 2 $set: {“price” : 299} 3 }, 3. ทา้ ยทส่ี ดุ ก�ำ หนดเงอ่ื นไขของคำ�สั่งชุดนไี้ วว้ า่ ÂÂ multi กำ�หนดคา่ false หมายถึง แกไ้ ขเฉพาะ Document ปัจจุบนั เพียง 1 รายการ เทา่ น้ัน ÂÂ upsert ก�ำ หนดคา่ false หมายถึง ให้แกไ้ ขข้อมูลเฉพาะท่ีมโี ครงสร้างข้อมูลเหมอื น กับค�ำ สั่งแก้ไขเท่าน้ัน Mongo Command Prompt 1{ 2 “multi” : false, 3 “upsert” : false 4} 5 ); ScJraivpat 153
การเพ่มิ ขอ้ มูล กรณีโครงสรา้ งขอ้ มูลแตกตา่ งกนั จากท่ีผู้เขียนกล่าวไว้ในตอนต้น โครงสร้างการจัดเก็บข้อมูลในฐานข้อมูล Mongo ใช้ รูปแบบ JSON เรยี กว่า Document มโี ครงสรา้ งข้อมูลเป็นไปตามทีเ่ ราก�ำ หนดไว้ สง่ ผลใหก้ ารเพม่ิ ขอ้ มลู ในแตล่ ะครงั้ (รวมไปถงึ การแกไ้ ขขอ้ มลู ดว้ ย) สามารถมโี ครงสรา้ ง ข้อมลู เหมือนเดิม หรอื แตกต่างจากของเดิมไดอ้ กี ด้วย OTE การจัดเก็บข้อมูลในรูปแบบ Document ของฐานข้อมูล Mongo แตกต่างจากรูปแบบตารางของ ฐานขอ้ มูล RDBMS อย่างส้นิ เชิง กล่าวคือ ในระบบฐานข้อมูล RDBMS ข้อมูลทุกเรค็ คอรด์ ตอ้ งมโี ครงสร้าง เหมอื นกนั หมด แสดงผลในรปู แบบตาราง เชน่ ตารางสนิ คา้ กำ�หนดใหจ้ ดั เกบ็ ProductID, ProductName และ ProductPrice น่ีคือขอ้ บังคับอยา่ งชดั เจนวา่ ข้อมลู สนิ ค้าทกุ เร็คคอรด์ ทกุ รายการ “ต้องมี” โครงสร้างไม่ เกนิ 3 ฟิลดน์ ้ีเท่านนั้ เกนิ ขอบเขตจากน้ีไมไ่ ด้ โครงสรา้ งจัดเก็บข้อมูลหนังสือเดมิ ของคอลเล็กชัน books ประกอบด้วยฟิลด์ isbn, title และ price แตก่ ารเพมิ่ ข้อมลู หนงั สือคร้ังน้ี มีโครงสร้างข้อมลู แตกต่างจากเดิมท่มี อี ยู่ โดยการ เพ่มิ ฟลิ ด์ description ขน้ึ มาใหม่ ดังสคริปต์ต่อไปน้ี JSON 1{ 2 isbn : ‘6666’, 3 title: ‘พัฒนา WEP API รว่ มกบั ASP.NET Core’, 4 price: 425, 5 description : “เรียนรู้พัฒนาโปรเจก็ ต์ตั้งแต่เรมิ่ ตน้ จนถึง Workshop” 6} หมายความว่าข้อมลู หนังสือรหัส isbn 6666 มีโครงสรา้ งจดั เก็บแตกต่างไปจาก 5 เลม่ กอ่ นหนา้ น้ี ถา้ เราตรวจสอบรูปแบบ ถอื เป็นโครงสรา้ ง JSON ที่ถกู ต้อง และสามารถเพ่มิ ข้อมูล เขา้ ไปในคอลเลก็ ชนั books ไดอ้ กี ด้วย ดงั รปู ที่ 8-18 รูปที ่ 8-18 กรณเี พมิ่ ขอ้ มลู ทม่ี โี ครงสรา้ งแตกตา่ งกนั 154
CHAPTER 8 การทำ�งานกับระบบฐานข้อมูล Mongo ผู้เขียนลองดูคอลเล็กชันในมุม มองแบบ list พบว่าหนังสือรหัส isbn 6666 แตกต่างจากหนังสือรายการอืน่ รปู ที ่ 8-19 หนังสือรหัส 6666 แตกต่าง จากหนังสอื 5 รายการเดมิ การอพั เตดขอ้ มูล กรณีโครงสรา้ งข้อมลู แตกตา่ งกัน ส�ำ หรบั การอพั เดตขอ้ มลู ในกรณที มี่ โี ครงสรา้ งขอ้ มลู แตกตา่ งกนั ผเู้ ขยี นขอแยกกรณี ให้ เห็นผลการทำ�งานอย่างชัดเจน ดงั น้ี 1. กรณที ี่ 1 เราตอ้ งการอพั เดตขอ้ มลู หนงั สอื รหสั isbn 7777 (“isbn” : “7777”) เปน็ การ อัพเดตข้อมูลท่ีมีเง่อื นไขว่า hh ไมม่ อี ยใู่ นคอลเลก็ ชนั books เดมิ และ hh โครงสรา้ งข้อมูลของหนงั สือรหสั 7777 น้ี แตกตา่ งจากข้อมลู เดมิ อกี ด้วย เพราะ ว่า มีฟิลด์ description เพ่มิ ขึ้นมา จากนั้นให้กำ�หนดเงือ่ นไข “upsert” : true ดังสครปิ ตต์ ่อไปนี้ Mongo Command Prompt ScJraivpat 155 1 db.getCollection(‘books’).update( 2{ 3 “isbn” : 7777 4 }, 5{ 6 $set: { 7 “isbn” : 7777, 8 “title” : “พฒั นา Android Apps ร่วมกับ Firebase”, 9 “price” : 345, 10 “description” : “ศกึ ษาเรยี นร้แู บบ Step By Step” 11 } 12 }, 13 { 14 “multi” : false, 15 “upsert” : true 16 } 17 );
รปู ท่ ี 8-20 ผลการท�ำ งานของกรณแี รก จากรปู ที่ 8-20 ความหมายของเงื่อนไข “upsert” : true คือ ถ้าขอ้ มลู ท่ีอัพเดตเข้ามา ไม่ตรงกับข้อมูลเดิมที่มีอยู่ ให้กลายเป็นการเพ่ิมข้อมูลแทน ส่งผลให้เราได้หนังสือรหัส 7777 ซงึ่ เกิดจากฟังก์ชนั update() ดังรูปท่ี 8-21 รูปท่ ี 8-21 แสดงขอ้ มลู หนงั สอื รหสั 7777 2. กรณที ี่2 ผเู้ ขยี นตอ้ งการอพั เดตหนงั สอื รหสั isbn3333 เปน็ ขอ้ มลู ทมี่ อี ยเู่ ดมิ แนน่ อน ก�ำ หนดเงอื่ นไข “upsert” : true การอพั เดตครงั้ น้ี มโี ครงสรา้ งขอ้ มลู แตกตา่ งไปจาก เดมิ โดยเพม่ิ ฟลิ ดท์ ชี่ อื่ วา่ pricewithus ท�ำ หนา้ ทเ่ี กบ็ ราคาขายในหนว่ ยเหรยี ญสหรฐั Mongo Command Prompt 1 db.getCollection(‘books’).update( 2{ 3 “isbn” : “3333” 4 }, 5{ 6 $set: { 156
CHAPTER 8 การท�ำ งานกับระบบฐานข้อมูล Mongo Mongo Command Prompt 7 “title” : “Basic Web Apps with Node”, 8 “price” : 99, 9 “pricewithus” : 3.99, 10 “description” : “ส�ำ หรับผเู้ รม่ิ ตน้ ทส่ี นใจ” 11 } 12 }, 13 { 14 “multi” : false, 15 “upsert” : true 16 } 17 ); รปู ท่ ี 8-22 ผลการท�ำ งานกรณที ่ี 2 จากรปู ท่ี 8-22 หนงั สอื รหสั 3333 เดิม ไมม่ ฟี ิลด์ pricewithus การอพั เดตครั้งน้ีเปน็ การ ท�ำ งานทงั้ อพั เดตขอ้ มลู เดมิ ใหก้ ลายเปน็ ขอ้ มลู ใหมล่ า่ สดุ และเพมิ่ ฟลิ ดใ์ หมท่ ช่ี อื่ วา่ pricewithus เพิ่มเข้ามาใหมใ่ นการท�ำ งานเดยี วกนั ดว้ ย การเลอื กดูข้อมูลแบบมเี ง่ือนไข การท�ำ งานกบั ขอ้ มูลทเ่ี ก็บอยูใ่ นระบบฐานขอ้ มูลในความเป็นจรงิ เมอ่ื เราเก็บขอ้ มลู เพิม่ มากขน้ึ เรอื่ ยๆ ในชว่ งเวลาหนง่ึ ๆ เราไมไ่ ดต้ อ้ งการขอ้ มลู ทง้ั หมดในเวลาเดยี วกนั ในแตล่ ะชว่ ง เวลาต่างก็มเี งอื่ นไข มคี วามตอ้ งการข้อมูลท่ีแตกตา่ งกนั เรากำ�ลงั จะกลา่ วถึงหัวข้อการเรียกดู ขอ้ มูลแบบมีเง่อื นไขนั่นเอง ScJraivpat 157
เนือ่ งจากโครงสร้างจดั เก็บข้อมูลในระบบฐานขอ้ มลู Mongo มคี วามยดื หย่นุ สงู มาก ผู้ เขยี นไมส่ ามารถน�ำ เสนอเนอื้ หาครอบคลมุ ทง้ั หมดไดอ้ ยา่ งแนน่ อน แตจ่ ะเลอื กน�ำ เสนอประเดน็ ทตี่ อ้ งรแู้ ละเนื้อหามีขอบเขตเพยี งพอทีจ่ ะน�ำ ไปใช้งานต่อได้ โดยปกติแลว้ เมื่อเปิด Robo 3T ข้ึนมา จะถกู ก�ำ หนดใหเ้ รียกดขู อ้ มลู ในคอลเลก็ ชนั ทเี่ รา สนใจอยูแ่ บบไม่มเี งือ่ นไขผ่านทางฟงั กช์ นั ทชี่ ่ือวา่ find() ในกรณีนี้ คือ คอลเล็กชนั books ดงั สครปิ ต์ต่อไปนี้ Mongo Command Prompt 1 db.getCollection(‘books’).find({}) การระบุเงื่อนไขกับขอ้ มลู ประเภทตวั เลข ขอ้ มลู ประเภทตัวเลขเราสามารถน�ำ มาเปรียบเทียบ เช่น เทา่ กับ, ไมเ่ ท่ากบั , มากกว่า, นอ้ ยกว่า, มากกว่าหรอื เท่ากบั , นอ้ ยกว่าหรอื เทา่ กบั , อย่ใู นชว่ ง เป็นตน้ 1. ผเู้ ขยี นตอ้ งการข้อมลู หนงั สือทม่ี ีรหสั isbn เท่ากับ 5555 ใหเ้ ขียนสครปิ ตด์ ังต่อไปนี้ Mongo Command Prompt 1 db.getCollection(‘books’).find({isbn : ‘5555’}) รปู ที ่ 8-23 แสดงข้อมูลหนังสือ รหัส isbn 5555 2. ตอ่ มา ต้องการหนังสอื ทม่ี ีราคามากกวา่ 300 (ฟิลด์ price เก็บค่าตัง้ แต่ 301 ขึ้นไป) โดยอาศัยค�ำ สง่ั $gt: 300 Mongo Command Prompt 1 db.getCollection(‘books’).find( { price: { $gt: 300 } } ) 158
CHAPTER 8 การท�ำ งานกบั ระบบฐานข้อมูล Mongo รปู ท ี่ 8-24 แสดงข้อมูลหนังสือ ที่มรี าคามากกว่า 300 3. ในทางกลับกัน ถา้ ต้องการราคาหนงั สือนอ้ ยกวา่ 300 (ฟลิ ด์ price เกบ็ คา่ ต้ังแต่ 299 ลงมา) ใหใ้ ช้ค�ำ สั่ง $lt: 300 Mongo Command Prompt 1 db.getCollection(‘books’).find( { price: { $lt: 300 } } ) รปู ที ่ 8-25 แสดงข้อมูลหนังสือ ที่มีราคาต�่ำกว่า 300 4. สามารถระบุค่าเจาะจงไปเลยกไ็ ด้ เชน่ ตอ้ งการหนงั สือท่ีมรี าคา 299 บาท โดยการ ระบุเง่ือนไข {price: 299 } ดงั สคริปต์ต่อไปนี้ Mongo Command Prompt 1 db.getCollection(‘books’).find( { price: 299 } ) รปู ท ี่ 8-26 แสดงข้อมูลหนังสือ ทีม่ รี าคา 299 ScJraivpat 159
5. ในกรณีท่ตี อ้ งการระบุช่วงราคา เช่น ตอ้ งการหนังสอื ราคาตงั้ แต่ 80 ถึง 350 ก็ให้ ระบขุ อบเขตบนและขอบเขตลา่ ง ดังตอ่ ไปน้ี hh ขอบเขตลา่ ง มากกว่า 80 โดยอาศัยค�ำ สงั่ $gt:80 hh ขอบเขตบน น้อยกวา่ 350 โดยอาศัยค�ำ สั่ง $lt:350 Mongo Command Prompt 1 db.getCollection(‘books’).find({price: {$gt: 80, $lt: 350}}) รูปที ่ 8-27 แสดงข้อมูลหนังสือ ทีม่ รี าคาในช่วง 80-350 6. ในกรณที ่ีตอ้ งการระบุเฉพาะฟิลดก์ ็สามารถทำ�ไดเ้ ชน่ กัน กลา่ วคอื hh ต้องการหนังสอื ทีม่ ีราคามากกว่า 200 โดยการระบุคำ�สง่ั {price: { $gt:200}} hh ต้องการขอ้ มูลเฉพาะฟิลด์ isbn กับ title โดยการระบุคำ�สง่ั {isbn:1, title:1} Mongo Command Prompt 1 db.getCollection(‘books’).find({price: { $gt:200}}, {isbn:1, title:1}) รูปท ่ี 8-28 แสดงข้อมูลหนังสือ เฉพาะฟลิ ด์ isbn และฟิลด์ title 7. ในกรณที ไ่ี มต่ อ้ งการข้อมลู ใด ให้ใชค้ ำ�สัง่ $ne เช่น ไมต่ อ้ งการหนังสือทม่ี รี าคา 299 อาศยั คำ�สัง่ {“price”:{$ne:299}} 160
CHAPTER 8 การทำ�งานกับระบบฐานข้อมลู Mongo Mongo Command Prompt 1 db.getCollection(‘books’).find({“price”:{$ne:299}}) รปู ท่ ี 8-29 แสดงข้อมูลหนังสือ ที่มรี าคาไมเ่ ทา่ กบั 299 8. ท้ายที่สุด การเปรยี บเทยี บประเภทเอาหวั -ท้ายดว้ ย แยกเปน็ 2 กรณี ดงั นี้ hh มากกว่าหรือเทา่ กับ ให้ใช้ค�ำ ส่งั $gte hh น้อยกว่าหรือเท่ากับ ใหใ้ ช้ค�ำ สง่ั $lte เชน่ ตอ้ งการหนังสอื ทมี่ รี าคามากกว่าหรอื เทา่ กบั 299 ให้ใชค้ ำ�สง่ั {price: {$gte: 299}} Mongo Command Prompt 1 db.getCollection(‘books’).find({price: {$gte: 299}}) รูปที ่ 8-30 กรณีหนังสือราคา มากกวา่ หรอื เทา่ กับ 299 จากรูปที่ 8-30 พบวา่ หนังสอื ราคา 299 ไดม้ าด้วย การระบุเงอ่ื นไขกับขอ้ มลู ประเภทข้อความ สำ�หรับการระบุเง่ือนไขกับฟิลด์ประเภทข้อความ อยู่ในรูปแบบ “มีข้อความท่ีเราสนใจ อยหู่ รือไม่” ScJraivpat 161
1. ผู้เขียนต้องการหนังสือที่มีคำ�ว่า Basic อยู่ในช่ือหนังสือ (ฟิลด์ที่ชื่อว่า title) โดย อาศัยค�ำ สง่ั {‘title’:{$regex:’.*Basic*’}} Mongo Command Prompt 1 db.getCollection(‘books’).find({‘title’:{$regex:’.*Basic*’}}) รปู ที่ 8-31 แสดงรายชอื่ หนงั สอื ท่ีมคี ำ�ว่า Basic 2. การระบุเง่ือนไขกับข้อความ สามารถใช้เครื่องหมาย / ได้อีกด้วย เช่น ต้องการ หนงั สอื ที่มีคำ�ว่า ร่วมกับ โดยอาศัยค�ำ สง่ั {title:/รว่ มกับ/} Mongo Command Prompt 1 db.getCollection(‘books’).find({title:/รว่ มกับ/}) รปู ท่ ี 8-32 แสดงรายชอื่ หนงั สอื ที่มคี ำ�ว่า ร่วมกบั การกำ�หนดจ�ำ นวนข้อมลู ทต่ี ้องการ (limit()) และขอ้ มูลท่ียกเว้น (skip()) ฟังกช์ ัน skip() ท�ำ หน้าท่ีระบวุ ่า เราตอ้ งการยกเวน้ ข้อมูลกชี่ ุด เชน่ skip(5) หมายถงึ เรา ตอ้ งการยกเวน้ ขอ้ มลู 5 ชุดแรก ส่งผลใหเ้ ราจะไดข้ ้อมูลชดุ ท่ี 6 เปน็ ตน้ ไป ส่วนฟังก์ชัน limit() ทำ�หน้าท่ีจำ�กัดจำ�นวนข้อมูลที่เราต้องการ เช่น limit(3) หมายถึง เราต้องการข้อมูล 3 ชุดแรก ทั้ง 2 ฟงั กช์ ันข้างตน้ สามารถใชง้ านรว่ มกันได้ ดงั ตัวอย่างต่อไปนี้ 1. ผู้เขียนต้องการข้อมูลหนังสือ 4 รายการแรกเท่าน้ัน จึงระบุฟังก์ชัน limit(4) ดัง สครปิ ต์ต่อไปน้ี 162
CHAPTER 8 การทำ�งานกับระบบฐานข้อมลู Mongo Mongo Command Prompt 1 db.getCollection(‘books’).find({}).limit(4) รูปที ่ 8-33 ผลการท�ำ งาน ฟงั กช์ ัน limit(4) 2. ตอ่ มา ต้องการยกเว้นขอ้ มลู หนังสือ 2 รายการแรกกอ่ น โดยอาศยั ฟงั กช์ ัน skip(2) ส่งผลใหเ้ ราไดข้ ้อมูลตง้ั แตช่ ุดที่ 3 เป็นต้นไป Mongo Command Prompt 1 db.getCollection(‘books’).find({}).skip(2) รูปท่ ี 8-34 ผลการท�ำ งาน ฟงั กช์ นั skip(2) 3. ท้ายท่ีสุด เราสามารถใช้ฟังก์ชัน skip() ร่วมกับฟังก์ชัน limit() ได้อีกด้วย เช่น ต้องการให้ข้ามข้อมูล 2 ชุดแรกก่อน (skip(2)) จากน้ันกำ�หนดข้อมูลท่ีต้องการ 3 ชุดเท่านั้น (limit(3)) Mongo Command Prompt 1 db.getCollection(‘books’).find({}).skip(2).limit(3) ScJraivpat 163
รูปที่ 8-35 ผลการท�ำ งาน ฟังก์ชัน skip() รว่ มกับฟังก์ชนั limit() การสรา้ งคอลเล็กชนั ใหม่ ในกรณีที่ต้องการสร้างคอลเล็กชันใหม่ เพื่อทำ�หน้าที่เก็บข้อมูล เช่น ผู้เขียนต้องการ สร้างคอลเล็กชันท่ีชื่อว่า Customers ข้ึนมาทำ�หน้าท่ีเก็บข้อมูลลูกค้า ก็ให้คลิกขวาที่ฐาน ขอ้ มูล myshops เลือกคำ�ส่งั Create Colection… ตง้ั ชอื่ คอลเล็กชันนีว้ ่า Customers คลิกที่ ปมุ่ เพือ่ สร้างคอลเลก็ ชันใหม่ ดังรปู ที่ 8-36 รปู ท ่ี 8-36 แสดงการสร้าง คอลเล็กชันที่ชือ่ วา่ Customers รูปท ่ี 8-37 แสดงคอลเลก็ ชนั Customers ทีเ่ พมิ่ เข้า มาใหมใ่ นฐานข้อมลู myshops การลบคอลเล็กชนั ที่มีอยู่ ในกรณีที่ต้องการลบคอลเล็กชันออกจากฐานข้อมูล สามารถทำ�ได้โดยการคลิกขวาท่ี ชื่อคอลเลก็ ชันท่ีตอ้ งการลบ จากน้ันเลือกเมนู Drop Colection… เพื่อลบคอลเลก็ ชัน 164
CHAPTER 8 การท�ำ งานกบั ระบบฐานขอ้ มูล Mongo ในกรณีนี้ต้องการลบคอลเล็กชัน Customers ดังรูป ท่ี 8-38 รปู ท่ี 8-38 กรณตี อ้ งการลบ คอลเล็กชัน Customers การ Backup และ Restore ฐานข้อมูล Mongo ในการท�ำ งานกับระบบฐานขอ้ มูลไมว่ ่าจะเปน็ ของบริษัทใดกต็ าม จะมงี านอยู่ 2 อยา่ งท่ี ผูด้ ูแลระบบฐานขอ้ มลู ต้องท�ำ อยู่เสมอ น่ันคือ 1. การส�ำ รองระบบฐานข้อมลู (Backup) 2. การกขู้ ้อมลู จากไฟล์สำ�รอง (Restore) ขน้ั ตอนการ Backup และ Restore ฐานข้อมลู Mongo มขี ้นั ตอนดงั น้ี 1. ใหเ้ ปดิ หนา้ ตา่ ง Command Prompt ขนึ้ มาดว้ ยสทิ ธข์ิ อง Admin เทา่ นน้ั จากนนั้ ไป ทพ่ี าธของฐานขอ้ มลู Mongo ในกรณนี ี้ คือ พาธ C:\\Program Files\\MongoDB\\ Server\\3.4\\bin ใหป้ ้อนค�ำ สง่ั ตอ่ ไปน้ี แล้วกดปุ่ม Enter ที่คียบ์ อรด์ เพ่ือสำ�รองฐาน ข้อมลู myshops ดงั รปู ท่ี 8-39 Mongo Command Prompt 1 mongodump --db myshops รปู ท่ี 8-39 แสดงการ Backup ฐานข้อมลู myshops จากรูปที่ 8-39 Command Prompt ข้นึ บรรทดั ใหม่ แสดงว่าขน้ั ตอนการ Backup ฐาน ข้อมูล myshops เสร็จสมบรู ณ์แล้ว ScJraivpat 165
2. ไฟลส์ ำ�รองขอ้ มูลของฐานข้อมลู myshops ถูกเกบ็ อยใู่ นโฟลเดอร์ทีช่ ่อื วา่ dump ใน โฟลเดอร์ของโปรแกรมฐานข้อมูล Mongo ดงั รปู ท่ี 8-40 รปู ท่ ี 8-40 แสดงรายการ ไฟล์ Backup ของฐานขอ้ มลู myshops จากรปู ท่ี 8-40 ผ้เู ขยี นกำ�หนดให้ส�ำ รองฐานข้อมูลทช่ี ื่อวา่ myshops ส่งผลใหร้ ายการไฟล์ สำ�รองขอ้ มูลที่ได้ถูกเกบ็ อยู่ในโฟลเดอรย์ ่อย myshops อกี ชนั้ หน่ึง 3. ส่วนวธิ กี าร Restore ฐานข้อมลู ใหพ้ มิ พค์ �ำ สง่ั ต่อไปน้ี กล่าวคอื hh mongorestore --db myshops หมายถงึ ให้ Restore ฐานขอ้ มลู ทช่ี อ่ื วา่ myshops hh dump/shops หมายถงึ ใหอ้ า่ นขอ้ มลู จากรายการไฟลท์ เ่ี กบ็ อยใู่ นโฟลเดอร์dump/ myshops Mongo Command Prompt 1 mongorestore --db myshops dump/myshops รปู ที่ 8-41 กรณี Restore ฐานข้อมูล myshops 4. ทา้ ยทสี่ ดุ ผเู้ ขยี นลองเปดิ ฐานขอ้ มลู myshops ดว้ ย Robo 3T กจ็ ะได้ฐานข้อมูล myshops ดังรปู ที่ 8-42 รูปท ่ี 8-42 แสดงฐานข้อมลู myshops สรปุ ท้ายบท การทำ�งานกับระบบฐานข้อมลู Mongo โดยอาศัย Robo 3T เปน็ เคร่ืองมอื ที่ ช่วยอำ�นวยความสะดวกได้ดีในระดับหนึ่งเลยทีเดียว ส่วนแสดงผลแบบ GUI สร้าง ความค้นุ เคยมากกว่าการป้อนคำ�ส่ังแบบ Command Line 166
9Java script CHAPTER พน้ื ฐานการใชง้ าน Express รว่ มกบั ฐาน ขอ้ มลู Mongo การพฒั นาWebApps โดยอาศยั Express รว่ มกบั ระบบฐานขอ้ มลู Mongo ถอื เปน็ หวั ขอ้ ที่มีรายละเอยี ดมากท่สี ุด เพราะวา่ ตอ้ งมีการใช้งานท้ังฝ่งั Express และฝงั่ ฐานข้อมูล Mongo ในคราวเดียวกัน ถือเป็นเนื้อหาบทแรกท่ีมีนำ� Node + Express เข้ามาเชื่อมต่อกับระบบฐาน ขอ้ มลู Mongo แบ่งแยกตามหน้าท่ดี งั ต่อไปนี้ 1. เก็บข้อมูล เป็นหน้าที่ของระบบฐานข้อมูล Mongo ทำ�หน้าท่ีจัดเก็บข้อมูล ถือ เปน็ การทำ�งานฝัง่ หลังบา้ น (Server) 2. แสดงขอ้ มลู เปน็ หนา้ ทข่ี องNode+Express สง่ ผลให้Express อยใู่ นฐานะ2 บทบาท กลา่ วคือ hh ฝง่ั หลงั บา้ น(Server) อาศยั ชน้ิ สว่ นทชี่ อ่ื วา่ Mongoose ท�ำ หนา้ ทตี่ ดิ ตอ่ กบั ระบบ ฐานข้อมูล Mongo hh ฝั่งหน้าบ้าน (Client) อาศัยช้ินส่วนที่ชื่อว่า Pug ทำ�หน้าที่สร้างส่วนแสดงผล ปรากฎในบราวเซอร์ใหผ้ ู้ใช้งานเหน็ เนอื้ หาของบทนี้เปน็ การพฒั นา Web Apps บน MEAN Stack ครอบคลุม 3 สว่ น คอื M, E และ N ในกรณนี ้ีผู้เขยี นเลอื กใชช้ น้ิ ส่วนท่ชี ือ่ วา่ Mongoose เขา้ มาท�ำ หนา้ ทีเ่ ป็นตัวกลาง เชื่อมตอ่ Node + Express เข้ากับระบบฐานขอ้ มลู Mongo การเชือ่ มต่อกบั ฐานข้อมลู Mongo ด้วย Mongoose การกำ�หนดให้โปรเจ็กต์ของ Express เช่ือมต่อเข้ากับระบบฐานข้อมูลของ Mongo มี หลายวิธี ในข้ันตน้ น้ีผเู้ ขยี นขอเลือกใช้ Mongoose ก่อน .Net HTML HTML
โดยผู้เขียนเลอื กใช้ฐานข้อมลู ทีช่ ่อื ว่า myshops ตอ้ งการแสดงข้อมูลหนงั สอื ที่เกบ็ อยู่ใน คอลเล็กชันทช่ี ่อื ว่า books แสดงผลในบราวเซอร์ ผ่านทางโปรเจก็ ต์ทีเ่ ราสร้างข้นึ มา ตัวอย่างท่ี 9-1 การเชอ่ื มตอ่ กบั ฐานขอ้ มลู Mongo ดว้ ย Mongoose มีข้ันตอนดงั น้ี 1. สร้างโปรเจ็กต์ Express ใน Visual Studio (หรือ express-generator ก็ได้) ใหม่ ชอื่ ว่า UsingExpressWithMongoByMongoose ดังรูปที่ 9-1 รูปท ี่ 9-1 แสดงการสร้างโปรเจ็กต์ ที่ชื่อว่า UsingExpressWithMongoBy Mongoose 2. ต่อมา โครงสร้างโปรเจ็กต์ท่ีเราได้มาในข้ันต้น ใช้ส่วนแสดงผลของ Pug เวอร์ชัน ลา่ สุดเท่าทมี่ ีอยู่ ดังรูปที่ 9-2 รปู ที่ 9-2 โปรเจก็ ตป์ จั จบุ นั ก�ำ หนดให้ใชส้ ว่ นแสดงผลดว้ ย Pug 3. ในไฟล์ package.json มีการก�ำ หนดใหใ้ ช้ชิน้ ส่วนในขนั้ ตน้ ดังต่อไปน้ี package.json 1{ 2 “name”: “using-express-with-mongo-by-Mongoose”, 3 “version”: “0.0.0”, 4 “private”: true, 5 “scripts”: { 6 “start”: “node app” 168
CHAPTER 9 พ้ืนฐานการใช้งาน Express ร่วมกบั ฐานขอ้ มูล Mongo package.json 7 }, 8 “description”: “UsingExpressWithMongoByMongoose”, 9 “author”: { 10 “name”: “thaivb” 11 }, 12 “dependencies”: { 13 “body-parser”: “^1.15.0”, 14 “cookie-parser”: “^1.4.0”, 15 “debug”: “^2.2.0”, 16 “express”: “^4.14.0”, 17 “morgan”: “^1.7.0”, 18 “pug”: “^2.0.0-beta6”, 19 “serve-favicon”: “^2.3.0” 20 } 21 } รูปท ี่ 9-3 แสดงรายการตดิ ตง้ั dependencies ทอี่ ยใู่ นไฟล์ package.json การเพม่ิ Mongoose เพอื่ เช่อื มต่อกับฐานข้อมลู Mongo ใน Visual Studio มีขน้ั ตอนดงั น้ี 1. การเชอ่ื มต่อกบั ฐานขอ้ มูล Mongo ผู้เขียนเลือกใช้ชนิ้ ส่วนท่ีชื่อวา่ mongoose โดย การกำ�หนดทไ่ี ฟล์ package.json ดงั รูปที่ 9-4 ScJraivpat 169
รปู ท่ี 9-4 แสดงการเพิ่มรายการ mongoose ในไฟล์ package.json จากรูปท่ี 9-4 เมื่อมีการแกไ้ ขไฟล์ package.json ก็ตอ้ ง Save ไฟลน์ ีเ้ สมอ 2. ต่อมา ใหค้ ลิกขวาที่ npm เลือกคำ�สั่ง Update npm Packages เพอื่ ดาวน์โหลด และติดต้ังรายการอัพเดตชิ้นส่วนต่างๆ ตามที่ระบุอยู่ในไฟล์ package.json ให้ ครบถ้วน ส่งผลให้โปรเจ็กต์ปัจจุบันสามารถใช้ช้ินส่วน Mongoose เพ่ือเช่ือมต่อ กบั ระบบฐานขอ้ มลู Mongo ได้แลว้ ดงั รปู ท่ี 9-5 รูปท่ ี 9-5 แสดงการดาวนโ์ หลดและตดิ ตงั้ Mongoose 3. ใหเ้ ขยี นสครปิ ตต์ อ่ ไปน้ีในไฟล์app.js เพอ่ื เชอ่ื มตอ่ โปรเจก็ ตป์ จั จบุ นั เขา้ กบั ฐานขอ้ มลู myshops ทเ่ี รามอี ยู่แล้ว มีหน้าทีเ่ พยี งอยา่ งเดยี ว นั่นคอื แสดงรายการหนงั สอื ออก มาจากคอลเล็กชนั ทีช่ ื่อว่า books สคริปต์ Express ท่ี 9-1 การเชื่อมต่อกับฐานข้อมูล Mongo ดว้ ย Mongoose (app.js) 1 use strict’; 2 var debug = require(‘debug’); 3 var express = require(‘express’); 170
CHAPTER 9 พ้นื ฐานการใชง้ าน Express รว่ มกบั ฐานขอ้ มลู Mongo สครปิ ต์ Express ท่ี 9-1 การเชื่อมตอ่ กับฐานขอ้ มลู Mongo ดว้ ย Mongoose (app.js) (ตอ่ ) 4 var path = require(‘path’); 5 var favicon = require(‘serve-favicon’); 6 var logger = require(‘morgan’); 7 var cookieParser = require(‘cookie-parser’); 8 var bodyParser = require(‘body-parser’); 9 var pug = require(‘pug’); 10 11 var mongoose = require(‘mongoose’); 12 var Schema = mongoose.Schema; 13 14 var BooksSchema = new Schema({ 15 isbn: String, 16 title: String, 17 price: Number 18 }); 19 20 mongoose.model(‘books’, BooksSchema); 21 mongoose.connect(‘mongodb://localhost/myshops’); 22 23 var routes = require(‘./routes/index’); 24 var users = require(‘./routes/users’); 25 var books = require(‘./routes/books’); 26 var app = express(); 27 28 app.set(‘views’, path.join(__dirname, ‘views’)); 29 app.set(‘view engine’, ‘pug’); 30 31 app.use(logger(‘dev’)); 32 app.use(bodyParser.json()); 33 app.use(bodyParser.urlencoded({ extended: false })); 34 app.use(cookieParser()); 35 app.use(express.static(path.join(__dirname, ‘public’))); 36 37 app.use(‘/’, routes); 38 app.use(‘/users’, users); 39 app.use(‘/books’, books); 40 ScJraivpat 171
สคริปต์ Express ที่ 9-1 การเช่ือมต่อกบั ฐานข้อมลู Mongo ดว้ ย Mongoose (app.js) (ต่อ) 41 app.use(function (req, res, next) { 42 var err = new Error(‘Not Found’); 43 err.status = 404; 44 next(err); 45 }); 46 47 if (app.get(‘env’) === ‘development’) { 48 app.use(function (err, req, res, next) { 49 res.status(err.status || 500); 50 res.render(‘error’, { 51 message: err.message, 52 error: err 53 }); 54 }); 55 } 56 57 app.use(function (err, req, res, next) { 58 res.status(err.status || 500); 59 res.render(‘error’, { 60 message: err.message, 61 error: {} 62 }); 63 }); 64 65 app.set(‘port’, process.env.PORT || 3000); 66 67 var server = app.listen(app.get(‘port’), function () { 68 debug(‘Express server listening on port ‘ + server.address().port); 69 }); 4. ต่อมา ให้เพิ่มไฟล์ที่ช่ือว่า books.js ในโฟลเดอร์ routes รองรับพาธ /books ทำ� หนา้ ทเี่ รียกดูข้อมลู หนงั สอื จากคอลเล็กชัน books แบบไมม่ ีเงอ่ื นไข และน�ำ ขอ้ มลู หนงั สือดงั กลา่ วไปแสดงในสว่ นแสดงผลทช่ี ่ือว่า books.pug ดังสคริปตต์ ่อไปนี้ รปู ท่ ี 9-6 แสดงสคริปต์ใน ไฟล์ books.js 172
CHAPTER 9 พ้นื ฐานการใช้งาน Express ร่วมกบั ฐานข้อมูล Mongo สครปิ ต์ Express ท่ี 9-1 การเชอ่ื มต่อกบั ฐานขอ้ มลู Mongo ดว้ ย Mongoose (\\routes\\books.js) 1 var express = require(‘express’); 2 var router = express.Router(); 3 4 var mongoose = require(‘mongoose’); 5 var books = mongoose.model(‘books’); 6 7 router.get(‘/’, function (req, res) { 8 books.find(function (err, dbBooks) { 9 res.render( 10 ‘books’, 11 { title: ‘รายการหนงั สือ’, data: dbBooks} 12 ); 13 }); 14 }); 15 16 module.exports = router; 5. ตอ่ มา สว่ นแสดงผลทท่ี �ำ หนา้ ทแ่ี สดงขอ้ มลู หนงั สอื ชอื่ วา่ books.pug อยใู่ นโฟลเดอร์ views ดงั สคริปตต์ อ่ ไปนี้ สคริปต์ Pug ท่ี 9-1 การเช่อื มตอ่ กบั ฐานขอ้ มูล Mongo ด้วย Mongoose (\\views\\books.pug) 1 extends layout 2 3 block content 4 block content 5 h1 #{title} 6 table(border = 1) 7 th รหัส 8 th ชื่อหนงั สอื 9 th ราคา 10 for item in data 11 tr 12 td #{item.isbn} 13 td #{item.title} 14 td #{item.price} ScJraivpat 173
รูปท่ ี 9-7 แสดงสครปิ ต์ Pug ของไฟล์ books.pug 6. ตัวอย่างโปรเจ็กต์น้ีเราต้องการเรียกดูข้อมูลจากฐานข้อมูล Mongo จึงต้องส่ังให้ ระบบฐานข้อมลู Mongo ท�ำ งานก่อน ให้เปิดหน้าต่าง Command Prompt ขนึ้ มา ท่พี าธของฐานข้อมูล Mongo (ในกรณีน้ี คอื พาธ C:\\Program Files\\MongoDB\\ Server\\3.4\\bin) ให้ทำ�ดงั นี้ hh เปิดบริการฐานข้อมลู Mongo โดยใช้ค�ำ ส่งั mongo hh กำ�หนดให้ใชฐ้ านขอ้ มูลทช่ี ่ือวา่ myshops โดยใชค้ �ำ สง่ั use myshops รปู ท ี่ 9-8 แสดงการเปิดบริการฐาน ข้อมลู Mongo และรันโปรเจก็ ต์ปจั จุบัน 7. ท้ายทีส่ ดุ ให้รนั โปรเจก็ ต์ ไปทพ่ี าธ /books ก็จะไดข้ ้อมูลหนงั สือเท่าท่ีเรามีอยู่จาก คอลเลก็ ชนั ทช่ี อ่ื วา่ books จ�ำ นวน7 รายการ ถอื เปน็ การเรยี กดขู อ้ มลู หนงั สอื ทงั้ หมด แบบไมม่ เี งือ่ นไข ดังรูปท่ี 9-6 รูปท ่ี 9-9 ผลการรนั ตัวอยา่ งที ่ 9-1 174
CHAPTER 9 พนื้ ฐานการใช้งาน Express รว่ มกับฐานขอ้ มลู Mongo จากรูปที่ 9-9 ข้อมูลหนังสือท่ีได้มาจากพาธ /books อธิบายการท�ำ งานของสคริปต์ 1. เริ่มตน้ ทไี่ ฟล์ app.js สร้างตัวแปรทีช่ อื่ วา่ mongoose (var mongoose) ทำ�หน้าท่ี แทน mongoose (require(‘Mongoose’)) จากนนั้ ก�ำ หนดใหต้ วั แปรmongoose เชอื่ มตอ่ กบั ฐานขอ้ มลู ทชี่ อื่ วา่ myshops โดยอาศยั เมธอด connect() ให้กำ�หนดข้อความเช่อื มต่อกบั ฐานข้อมลู Mongo ด้วยข้อความเชอื่ มตอ่ ‘mongodb://localhost/myshops’ ในกรณีท่ีเกิดปัญหา (พารามิเตอร์ err) กำ�หนดให้แสดงข้อผิดพลาดที่เกิดขึ้นด้วย (console.log(err)) app.js 1 var mongoose = require(‘mongoose’); 2 var Schema = mongoose.Schema; 3 4 var BooksSchema = new Schema({ 5 isbn: String, 6 title: String, 7 price: Number 8 }); 9 10 mongoose.model(‘books’, BooksSchema); 11 mongoose.connect(‘mongodb://localhost/myshops’); 2. รปู แบบการตดิ ตอ่ ระหวา่ งสว่ นแสดงผลกบั ฐานขอ้ มลู ตอ้ งมตี วั กลาง เรยี กวา่ Schema ท�ำ หนา้ ที่กำ�หนดโครงสร้างขอ้ มูลใหต้ รงกบั ข้อมลู ท่ตี ้องการดงึ ออกมา ในกรณีนี้คือ ข้อมูลหนังสอื ท่อี ย่ใู นคอลเล็กชนั books รปู ท ่ี 9-10 แสดงโครงสร้างข้อมูล ของคอลเล็กชนั books ScJraivpat 175
ในกรณีนี้ข้อมูลท่ีเราสนใจคือ คอลเล็กชันท่ีช่ือว่า books ให้กำ�หนดโครงสร้างตัวแปร Schema ให้ตรงกับที่เราสร้างในฐานข้อมูล myshops ด้วย แม้ว่ารูปแบบการจัดเก็บข้อมูล หนังสือในแต่ละ Document มีโครงสร้างแตกต่างกัน ไม่ถือเป็นปัญหาแต่อย่างใด ผู้เขียน สนใจข้อมูล 3 ส่วนหลัก ดงั น้ี ÂÂ isbn ก�ำ หนดให้มีชนิดขอ้ มูลเปน็ ข้อความ String ÂÂ title กำ�หนดให้มีชนิดข้อมลู เป็นข้อความ String ÂÂ price กำ�หนดให้มีชนดิ ข้อมูลเปน็ ตัวเลข Number โครงสร้างท่ีกำ�หนดขึ้นมาเป็นของ Colection ที่ช่ือว่า books จึงตั้งชื่อโครงสร้างน้ีว่า BooksSchema app.js 1 var BooksSchema = new Schema({ 2 isbn: String, 3 title: String, 4 price: Number 5 }); 3. ตอ่ มา เมือ่ ได้โครงสร้างของ books มาแลว้ (เกบ็ อยใู่ นตวั แปร BooksSchema) ก็ จะดึงขอ้ มูลหนงั สือเทา่ ทมี่ อี ยู่ออกมา ถอื ว่าข้ันตอนการดงึ ข้อมูลเสร็จสมบรู ณแ์ ลว้ app.js 1 mongoose.model(‘books’, BooksSchema); 2 mongoose.connect(‘mongodb://localhost/myshops’); 4. ต่อมา ก�ำ หนดเสน้ ทาง /books สงั่ ใหไ้ ฟล์ books.js ทีอ่ ยใู่ นโฟลเดอร์ routes ท�ำ งาน app.js 1 var books = require(‘./routes/books’); 2… 3… 4… 5 app.use(‘/books’, books); 5. ที่ไฟล์ books.js ทอี่ ยู่ในโฟลเดอร์ routes รับผิดชอบเรอ่ื งการดึงขอ้ มลู หนังสือออก มาจากคอลเล็กชนั books แบบไมม่ ีเงอื่ นไข โดยอาศยั เมธอดทชี่ อ่ื ว่า find() ขอ้ มลู หนงั สือทีไ่ ด้มาเก็บไวใ้ นพารามเิ ตอร์ทชี่ ือ่ ว่า dbBooks 176
CHAPTER 9 พืน้ ฐานการใช้งาน Express ร่วมกับฐานข้อมูล Mongo \\routes\\books.js 1 var express = require(‘express’); 2 var router = express.Router(); 3 4 var mongoose = require(‘mongoose’); 5 var books = mongoose.model(‘books’); 6 7 router.get(‘/’, function (req, res) { 8 books.find(function (err, dbBooks) { 6. ต่อมา ส่ังให้แสดงข้อมูลหนังสือที่ได้มา ผ่านทางเมธอด render()ต้องกำ�หนด 2 อยา่ ง คือ ÂÂ พารามิเตอร์ books หมายถึง ใช้สว่ นแสดงผลท่ชี ่ือว่า books.pug ท่อี ยใู่ นโฟลเดอร์ views ÂÂ พารามิเตอร์ title ส่งข้อความ “รายการหนงั สือ” ÂÂ พารามิเตอร์ data หมายถงึ ข้อมลู หนงั สือที่จะส่งให้กับส่วนแสดงผล books.pug เราสามารถอา่ นขอ้ มลู หนังสอื ไดจ้ ากพารามเิ ตอร์ dbBooks นน่ั เอง การแสดงข้อมูลด้วย Pug ต้องอาศัยองค์ประกอบท้ัง 2 อย่างทำ�งานร่วมกัน กล่าวคือ ส่วนแสดงผลท่ีไดจ้ ากไฟล์ books.pug รวมกบั ข้อมูลทอ่ี ยู่ในพารามเิ ตอร์ data \\routes\\books.js 1 res.render( 2 ‘books’, 3 { title: ‘รายการหนังสอื ’, data: dbBooks} 4 ); 5 }); 6 }); 7 8 module.exports = router; 7. ตอ่ มา ทไ่ี ฟลส์ ว่ นแสดงผล books.pug ทอ่ี ยใู่ นโฟลเดอร์ views ท�ำ หนา้ ทแ่ี สดงขอ้ มลู หนงั สอื ก�ำ หนดใหใ้ ชโ้ ครงสรา้ งไฟล์ layout (.pug) กอ่ นดว้ ยค�ำ สง่ั extends layout จากน้นั สร้างตวั แปรท่ชี ่ือวา่ title ก�ำ หนดใหแ้ สดงข้อความดว้ ยอิลีเมนต์ h1 (h1 #{title}) เป็นตัวแปรทร่ี ับขอ้ ความ “รายการหนังสอื ” นน่ั เอง ScJraivpat 177
\\views\\books.pug 1 extends layout 2 3 block content 4 block content 5 h1 #{title} 8. ตอ่ มา ผูเ้ ขียนเลอื กใช้รปู แบบตารางแบบมเี สน้ ก�ำ กับ (table(border = 1)) ในกรณี นีส้ ร้างตารางทีม่ ี 3 คอลมั น์ ก�ำ หนดสว่ นหวั ของแตล่ ะคอลมั นโ์ ดยอาศยั อิลีเมนต์ th \\views\\books.pug 1 table(border = 1) 2 th รหสั 3 th ช่อื หนังสอื 4 th ราคา 9. ท้ายท่ีสุด ส่ังให้วนลูปอา่ นข้อมลู หนงั สือทลี ะรายการ ออกมาจากพารามิเตอร์ data เกบ็ ไว้ในตัวแปรที่ชื่อว่า item กอ่ น การแสดงขอ้ มูลแต่ละแถวเป็นหนา้ ทขี่ องอิลีเมน ต์ tr ในแต่ละรอบของการวนลปู ให้ท�ำ ดังนี้ ÂÂ รหัส isbn อา่ นคา่ ออกมาจากฟิลด์ isbn ÂÂ ช่อื หนงั สอื title อ่านคา่ ออกมาจากฟลิ ด์ title ÂÂ ราคาหนงั สอื price อ่านคา่ ออกมาจากฟลิ ด์ price การแสดงข้อมูลในแต่ละคอลมั น์ เปน็ หน้าทข่ี องอลิ ีเมนต์ td \\views\\books.pug 1 for item in data 2 tr 3 td #{item.isbn} 4 td #{item.title} 5 td #{item.price} การตกแต่งส่วนแสดงผล Pug ดว้ ย CSS ส่วนแสดงผลที่เกดิ จาก Pug เกิดจากการทำ�งานรว่ มกนั 2 ไฟลค์ อื 1. ไฟล์ layout.pug ทำ�หน้าทเ่ี กบ็ โครงสร้างตามมาตรฐาน HTML5 พบวา่ มกี ารอ้างองิ ให้ใช้งานไฟล์ CSS ท่ีชอื่ ว่า main.css ท่ีเกบ็ อยใู่ นโฟลเดอร์ \\public\\stylesheets 178
CHAPTER 9 พ้ืนฐานการใชง้ าน Express รว่ มกับฐานข้อมลู Mongo รปู ที ่ 9-11 แสดงการอ้างอิงไฟล์ main.css เหตุผลท่ีมีการอ้างอิงไฟล์ main.css ในไฟล์ layout.pug ก็เพื่อให้เราสามารถใช้ CSS ตกแต่งส่วนแสดงผลไดใ้ นทกุ หนา้ ของ Pug น่นั เอง 2. ไฟล์ books.pug รบั ผดิ ชอบแสดงขอ้ มลู หนงั สอื ทงั้ หมดแบบไมม่ เี งอ่ื นไข เมอ่ื ผกู เขา้ กบั ไฟล์ layout.pug ก็จะไดร้ บั ผลการทำ�งานจากไฟล์ main.css ดว้ ยเชน่ กนั และ ยังรวมไปถงึ ไฟล์ index.pug และ error.pug อกี ดว้ ย รปู ท ี่ 9-12 แสดงสคริปต์ CSS ใน ไฟล์ main.css ตวั อยา่ งท่ี 9-2 การตกแต่งสว่ นแสดงผล Pug ด้วย CSS หน้าท่ีของตัวอย่างน้ีก็คือ ตกแต่งข้อมูลหนังสือที่เกิดจากไฟล์ layout.pug + books. pug ด้วย CSS มขี น้ั ตอนดงั น้ี 1. ท่ีไฟล์ main.css ให้เขียนสคริปต์ต่อไปนี้เพื่อตกแต่งตารางใหม่ ย่อหน้าท่ีเห็นเกิด จากการกดปุม่ Tab ท่คี ียบ์ อร์ด เช่นเดียวกับทใี่ ชใ้ นไฟล์ .pug สครปิ ต์ CSS ที่ 9-2 การตกแต่งสว่ นแสดงผล Pug ดว้ ย CSS (\\public\\stylesheets\\main.css) 1 body { 2 padding: 50px; 3 font: 14px “Lucida Grande”, Helvetica, Arial, sans-serif; 4} 5 a{ 6 color: #00b7ff; 7} ScJraivpat 179
สครปิ ต์ CSS ท่ี 9-2 การตกแต่งสว่ นแสดงผล Pug ดว้ ย CSS (\\public\\stylesheets\\main.css) 8 table { 9 border-collapse: collapse; 10 width: 100%; 11 } 12 table, th, td { 13 border: 1px solid #00f; 14 } 15 th { 16 color: #fff; 17 background-color: #00f; 18 text-align: left; 19 } รูปที ่ 9-13 แสดงสคริปต์ CSS ใน ไฟล์ main.css 2. ท้ายทสี่ ุด ให้ทดสอบรนั โปรเจ็กต์ ไปที่พาธ /books กจ็ ะไดร้ ูปแบบตารางที่เกิดจาก การตกแต่งด้วย CSS แล้ว รปู ท ่ี 9-14 ผลการรันตัวอย่าง ท่ี 9-2 180
CHAPTER 9 พืน้ ฐานการใชง้ าน Express รว่ มกบั ฐานข้อมูล Mongo อธิบายการทำ�งานของสครปิ ต์ 1. การตกแต่งตาราง เราสนใจไฟล์นามสกลุ .css เปน็ หลกั เพราะว่าเป็นไฟลท์ ่ใี ช้งาน จริงในส่วนแสดงผล โฟกัสไปท่ีอิลีเมนต์ table กำ�หนดให้แสดงผลเต็มพ้ืนท่ีความ กวา้ งของหนา้ จอเทา่ ทม่ี ีอยู่ (width: 100%;) \\stylesheets\\main.css 1 table { 2 border-collapse: collapse; 3 width: 100%; 4} 2. ตอ่ มา ก�ำหนดใหเ้ สน้ ขอบตารางมีความหนา 1 พิกเซล สีนำ�้ เงนิ (border: 1px solid #00f;) \\stylesheets\\main.css 1 table, th, td { 2 border: 1px solid #00f; 3} 3. ท้ายท่สี ดุ ท่สี ว่ นหัวตารางอย่ใู นความรบั ผิดชอบของอิลีเมนต์ th ใหท้ ำ�ดงั น้ี ÂÂ ขอ้ ความเป็นสีขาว (color: #fff;) ÂÂ พื้นหลังเป็นสนี ้�ำเงนิ (background-color: #00f;) ÂÂ อยชู่ ิดซ้ายเสมอ (text-align: left;) \\stylesheets\\main.css 1 th { 2 color: #fff; 3 background-color: #00f; 4 text-align: left; 5} พนื้ ฐานการสรา้ งเมนูในสว่ นแสดงผล Pug องค์ประกอบพ้ืนฐานอย่างหน่งึ ท่ตี ้องมใี นเว็บไซต์ น่นั กค็ อื เมนู เพือ่ นำ�ทางผูใ้ ชง้ านไป ยังหน้าเว็บเพจต่างๆ น่ันเอง ในกรณีนี้เรากำ�ลังพูดถึงการสร้างเมนูในส่วนแสดงผลที่เกิดจาก ชนิ้ ส่วน Pug ScJraivpat 181
ตัวอยา่ งท่ี 9-3 พน้ื ฐานการสร้างเมนูในสว่ นแสดงผล Pug ผ้เู ขยี นน�ำ ตวั อย่างท่ีแลว้ มาทำ�ตอ่ มขี น้ั ตอนดังนี้ 1. ท่ไี ฟล์ app.js มีการกำ�หนดพาธรองรับการร้องขอ 3 พาธ ดังน้ี hh พาธ / กำ�หนดให้แสดงผลด้วยหน้าเพจท่ีชื่อว่า index.pug ท่ีอยู่ในโฟลเดอร์ views(อยใู่ นฐานะเปน็ หนา้ แรก) โดยอาศยั ไฟล์index.js ทอี่ ยใู่ นโฟลเดอร์routes hh พาธ /users ก�ำ หนดใหแ้ สดงผลด้วยข้อความธรรมดา โดยอาศัยไฟล์ users.js ท่ี อยู่ในโฟลเดอร์ routes hh พาธ /books กำ�หนดให้แสดงผลด้วยหน้าเพจท่ีช่ือว่า books.pug ที่อยู่ใน โฟลเดอร์ views โดยอาศยั ไฟล์ books.js ท่อี ยู่ในโฟลเดอร์ routes สครปิ ต์ Express ที่ 9-3 พ้นื ฐานการสร้างเมนูในส่วนแสดงผล Pug (app.js) 1 var routes = require(‘./routes/index’); 2 var users = require(‘./routes/users’); 3 var books = require(‘./routes/books’); 4 var app = express(); 5… 6… 7… 8 app.use(‘/’, routes); 9 app.use(‘/users’, users); 10 app.use(‘/books’, books); 2. ตอ่ มา ผเู้ ขียนตอ้ งการสรา้ งเมนใู หส้ ามารถเข้าถงึ ได้ท้งั 3 พาธข้างตน้ โดยการเขียน สครปิ ตด์ ังตอ่ ไปน้ี ในไฟล์ layout.pug เหตผุ ลทต่ี อ้ งสรา้ งเมนใู นไฟลน์ กี้ ค็ อื เมนทู เี่ ราสรา้ งขนึ้ มาตอ้ งปรากฎในบราวเซอรเ์ สมอ ไม่วา่ จะเปล่ยี นไปแสดงผลในหน้าใดก็ตาม สครปิ ต์ Pug ที่ 9-3 พนื้ ฐานการสรา้ งเมนูในส่วนแสดงผล Pug (\\views\\layout.pug) 1 doctype html 2 html 3 head 4 title= title 5 link(rel=’stylesheet’, href=’/stylesheets/main.css’) 6 body 7 section 8 img(src=’/images/logo.jpg’) 9 section 10 nav 182
CHAPTER 9 พืน้ ฐานการใช้งาน Express ร่วมกบั ฐานข้อมลู Mongo สครปิ ต์ Pug ท่ี 9-3 พืน้ ฐานการสรา้ งเมนใู นส่วนแสดงผล Pug (\\views\\layout.pug) (ตอ่ ) 11 a(href=’/’) หน้าแรก | 12 a(href=’/books’) หนงั สอื | 13 a(href=’/users’) สมาชิก 14 block content จากสคริปต์ Pug ข้างต้น พบว่ามีการสั่งให้แสดงไฟล์โลโก้ท่ีชื่อว่า logo.jpg ที่เก็บอยู่ ในโฟลเดอร์ images อกี ด้วย รูปท่ ี 9-15 แสดงสคริปต์ในไฟล์ layout.pug 3. ต่อมา ในไฟล์ main.css กจ็ ะมกี ารตกแตง่ เมนทู สี่ ร้างข้นึ มาด้วย ดงั สคริปตต์ ่อไปน้ี สคริปต์ CSS ท่ี 9-3 พน้ื ฐานการสรา้ งเมนูในสว่ นแสดงผล Pug (\\public\\stylesheets\\main.css) 183 1 body { 2 font: 16px “Lucida Grande”, Helvetica, Arial, sans-serif; 3} 4 5 a{ 6 font-size : larger; 7 color: #0d06ac; 8 text-decoration: none; 9} 10 11 a:hover { 12 color : white; 13 background-color: #0d06ac; 14 } 15 16 table { 17 border-collapse: collapse; 18 width: 100%; 19 } ScJraivpat
สครปิ ต์ CSS ท่ี 9-3 พื้นฐานการสรา้ งเมนูในส่วนแสดงผล Pug (\\public\\stylesheets\\main.css) 20 21 table, th, td { 22 border: 1px solid #00f; 23 } 24 25 th { 26 color: #fff; 27 background-color: #00f; 28 text-align: left; 29 } รูปท่ี 9-16 แสดงสคริปต์ในไฟล์ main.css 4. ท้ายท่ีสุด ให้ทดสอบรันโปรเจ็กต์ พบว่ามีรูปโลโก้และเมนูเข้าถึง 3 พาธข้างต้น ดงั รูปที่ 9-17 รปู ที ่ 9-17 ผลการรนั ตวั อยา่ งที่ 9-3 184
CHAPTER 9 พน้ื ฐานการใช้งาน Express ร่วมกับฐานขอ้ มลู Mongo อธิบายการท�ำ งานของสคริปต์ 1. เรม่ิ ตน้ สงั่ ใหแ้ สดงไฟลร์ ปู โลโกท้ ช่ี อื่ วา่ logo.jpg (ไฟลร์ ปู เกบ็ อยใู่ นโฟลเดอร์images) กอ่ นเป็นลำ�ดับแรก โดยอาศัยอลิ ีเมนต์ img รว่ มกบั แอ็ตทรบิ ิวต์ src \\views\\layout.pug 1 body 2 section 3 img(src=’/images/logo.jpg’) 2. ต่อมา เป็นพน้ื ทขี่ องเมนู ก�ำ หนดใหอ้ ยใู่ นความรับผดิ ชอบของอิลีเมนต์ nav สรา้ ง ลิงก์เข้าถึงทัง้ 3 พาธขา้ งตน้ โดยอาศยั อิลเี มนต์ a ร่วมกบั แอ็ตทรบิ ิวต์ href \\views\\layout.pug 1 section 2 nav 3 a(href=’/’) หนา้ แรก | 4 a(href=’/books’) หนังสือ | 5 a(href=’/users’) สมาชกิ 3. ลำ�ดับสุดท้าย คือการสร้างพ้ืนที่ท่ีชื่อว่า content สำ�หรับแสดงหน้าเว็บเพจต่างๆ นัน่ เอง \\views\\layout.pug 1 block content 4. ส่วนการตกแตง่ ลิงก์ อย่ใู นไฟล์ main.css ประกอบไปด้วย ÂÂ แอ็ตทรบิ ิวต์ font-size หมายถงึ ปรบั ขนาดข้อความลิงก์ ÂÂ แอต็ ทริบวิ ต์ color หมายถงึ สขี ้อความลงิ ก์ ÂÂ แอ็ตทริบิวต์ text-decoration: none หมายถึง กำ�หนดให้ข้อความลิงก์ ไม่ต้อง แสดงแบบตัวอักษรขีดเส้นใต้ \\public\\stylesheets\\main.css 1 a{ 2 font-size : larger; 3 color: #0d06ac; 4 text-decoration: none; 5} ScJraivpat 185
5. ท้ายท่ีสุด ดักจบั เหตุการณเ์ มาสไ์ ปลอยอยูเ่ หนือลงิ ก์ (a:hover) ให้ท�ำ ดงั นี้ ÂÂ แอ็ตทรบิ ิวต์ color หมายถึง สีข้อความลิงก์ ÂÂ แอ็ตทรบิ วิ ต์ background-color หมายถงึ สพี ื้นหลงั ของข้อความ \\public\\stylesheets\\main.css 1 a:hover { 2 color : white; 3 background-color: #0d06ac; 4} การแยกส่วนแสดงผลย่อย (Partial View) ใน Pug เพื่อให้ส่วนแสดงผลท่ีเกิดมาจาก Pug มรี ะเบียบมากยิง่ ข้นึ ยงั สามารถใชห้ ลักการแยก สว่ นแสดงผลยอ่ ย (เรียกว่า Partial View) ออกเป็นไฟล์ตา่ งหากไดอ้ กี ดว้ ย ตวั อย่างที่ 9-4 การแยกสว่ นแสดงผลยอ่ ย (Partial View) ใน Pug ผเู้ ขียนนำ�ตวั อย่างทีแ่ ล้ว มาปรับปรุงใหม่ มีขัน้ ตอนดังนี้ 1. ทไี่ ฟล์ layout.pug เหลอื เพียงแคโ่ ครงสร้างหนา้ เวบ็ เพจตามมาตรฐานของ HTML5 เทา่ น้ัน กล่าวคอื hh ระบบเมนู แยกออกไปเกบ็ ไวใ้ นไฟลท์ ช่ี อ่ื วา่ mainmenu.pug อา้ งองิ พนื้ ทน่ี ้ี ผา่ น ทางคำ�สงั่ include (include mainmenu) hh พ้ืนท่ีแสดงเนื้อหาของเพจต่างๆ ยังคงเดิมคือ พ้ืนที่ที่ชื่อว่า content (block content) hh สว่ นfooter แสดงผลล�ำ ดบั สดุ ทา้ ย แยกออกไปเกบ็ ไวใ้ นไฟลท์ ชี่ อ่ื วา่ mainfooter. pug อา้ งองิ พ้ืนท่ีน้ี ผา่ นทางค�ำ สง่ั include (include mainfooter) \\views\\layout.pug 1 doctype html 2 html 3 head 4 title= title 5 link(rel=’stylesheet’, href=’/stylesheets/main.css’) 6 body 7 section 8 img(src=’/images/logo.jpg’) 9 include mainmenu 10 block content 11 include mainfooter 186
CHAPTER 9 พืน้ ฐานการใช้งาน Express รว่ มกับฐานข้อมลู Mongo 2. ต่อมา เพมิ่ ไฟล์ทีช่ อ่ื วา่ mainmenu.pug ในโฟลเดอร์ views ท�ำ หนา้ ท่ีแสดงระบบ เมนูหลกั ในหนา้ เว็บเพจเรา ดงั สคริปต์ตอ่ ไปนี้ รูปท ่ี 9-18 แสดงสคริปต์ Pug ใน ไฟล์ mainmenu.pug \\views\\mainmenu.pug 1 div#navmain 2 nav 3 a(href=’/’) หนา้ แรก | 4 a(href=’/books’) หนังสอื | 5 a(href=’/users’) สมาชกิ 3. ตอ่ มา เพมิ่ ไฟล์ที่ชื่อว่า mainfooter.pug ในโฟลเดอร์ views ท�ำ หนา้ ทีแ่ สดงสว่ น footer แสดงผลเปน็ ลำ�ดับสุดท้ายในหน้าเว็บเพจ รูปท ี่ 9-19 แสดงสคริปต์ Pug ใน ไฟล์ mainfooter.pug \\views\\mainfooter.pug 1 footer#navfooter 2 nav 3 a(href=’/#’) พฒั นาโดย Thaivb.NET | 4 a(href=’/#’) นโยบายความเปน็ สว่ นตัว | 5 a(href=’/#’) ติดต่อเรา ScJraivpat 187
4. ทา้ ยท่สี ดุ ใหท้ ดสอบรันโปรเจก็ ต์ ส่วนแสดงผลท่ีได้มาเกิดมาจาก การจดั ระเบียบไฟล์ Pug ดังรูปท่ี 9-20 รปู ท่ี 9-20 ผลการรนั ตวั อยา่ งที่ 9-4 สรุปทา้ ยบท เนื้อหาที่นำ�เสนอในบทน้ี เร่ิมเห็นรูปร่างหน้าตา Web Apps ของเราทเ่ี กิดมา จากการท�ำ งานรว่ มกันทั้ง 3 สว่ น คือ Node + Express + Mongo 188
Java script 10CHAPTER การเพมิ่ , แก้ไข, ลบ, คน้ หาและแสดง ขอ้ มลู (CRUD) เนื้อหาทผ่ี า่ นมาท้ังหมดล้วนแล้วแต่เป็นขัน้ ตอนการเรยี กดขู อ้ มูล และนำ�ขอ้ มูลดงั กล่าว มาแสดงในบราวเซอร์ ในบทนีเ้ ป็นการนำ�เสนอเนื้อหาเก่ียวกับ ÂÂ การเพิม่ ขอ้ มูล (Create – C) ÂÂ การอา่ นขอ้ มลู (Read – R) ÂÂ การแก้ไขข้อมลู (Update – U) ÂÂ การลบขอ้ มลู (Delete – D) วิธีการนำ�เสนอเน้ือหาทั้ง 4 ส่วนข้างต้น เพ่ือให้เกิดความชัดเจนและง่ายต่อการศึกษา สคริปต์ของโปรเจ็กต์น้ีไม่มีการตกแต่งส่วนแสดงผลใดๆ ท้ังสิ้น เป็นการนำ�เสนอสคริปต์การ ทำ�งานแท้ๆ เพยี งอย่างเดยี วเทา่ น้นั โดยการน�ำ ตวั อยา่ งทแ่ี ลว้ (มีขัน้ ตอนการทำ�งานเพียงอย่าง เดยี ว คอื การแสดงข้อมลู แบบไม่มีเง่ือนไข) มาปรับปรุงใหม่ ผเู้ ขยี นจะแสดงโปรเจก็ ตท์ เ่ี สรจ็ สมบรู ณแ์ ลว้ ใหเ้ หน็ กอ่ นวา่ เราก�ำ ลงั จะท�ำ อะไร ประกอบ ไปด้วยอะไรบ้าง มีการทำ�งานอย่างไร ส่ิงที่ได้คืออะไร ก่อนเข้าสู่ขั้นตอนการสร้างท้ังหมดว่า มีท่ีมาอยา่ งไร การแสดงขอ้ มลู การแสดงข้อมูลหนังสอื มี 3 รูปแบบ ดังนี้ 1. แสดงข้อมูลทั้งหมดแบบไม่มีเงื่อนไข ก็คือ การเลือกเมนูหนังสือเพ่ือแสดงรายการ หนังสือทงั้ หมดนั่นเอง ดงั รูปท่ี 10-1 HTML .Net HTML
รูปท่ี 10-1 แสดงรายการหนงั สอื ทง้ั หมด 2. แสดงข้อมูลเฉพาะรายการที่ถูกเลือก เกิดจากการคลิกเลือกดูรายละเอียดหนังสือ เลม่ ท่ีสนใจ เช่น ตอ้ งการดูขอ้ มูลหนังสอื รหัส 2222 ดังรปู ที่ 10-2 รูปที่ 10-2 แสดงข้อมูลหนังสอื รหสั 2222 3. แสดงข้อมูลตามเง่ือนไขท่ีระบุ หรือการ คน้ หาขอ้ มลู น่นั เอง ในกรณีนีผ้ ูเ้ ขยี นเลอื ก ใช้ช่ือหนังสือ (ฟิลด์ title) เป็นเงื่อนไขใน การค้นหา เช่น ต้องการหนังสือที่มีคำ�ว่า “พ้ืนฐาน” ในชื่อหนังสือ ผลการค้นหา แสดงดงั รูปที่ 10-3 รูปท่ ี 10-3 ผลการค้นหาหนังสือที่มีคำ�ว่า “พ้นื ฐาน” ในช่ือหนงั สอื 190
CHAPTER 10 การเพม่ิ , แกไ้ ข, ลบ, ค้นหาและแสดงข้อมูล (CRUD) การเพิม่ ขอ้ มลู สำ�หรับขั้นตอนการเพ่ิมข้อมูลหนังสือใหม่ มดี ังน้ี 1. ให้คลิกท่ีลิงก์ “เพ่ิมข้อมูล” ด้านขวามือ ดังรปู ที่ 10-4 รปู ท่ี 10-4 แสดงแบบฟอร์มเพ่ิมขอ้ มูลหนังสือใหม่ จากรูปที่ 10-4 ผู้เขียนกำ�หนดให้แสดงแบบฟอร์มเพ่ิมข้อมูลหนังสือเพียง 3 ส่วน คือ รหสั ISBN ช่ือหนังสอื และราคาหนังสือเท่าน้ัน 2. ท้ายที่สุด ให้ป้อนข้อมูลหนังสือเข้าไป แล้วคลิกที่ปุ่มบันทึก ก็จะได้ข้อมูลหนังสือ ใหม่ ดังรปู ท่ี 10-5 รปู ท่ี 10-4 แสดงขอ้ มลู หนงั สอื รหสั 0000 ทถี่ กู เพมิ่ เขา้ มาใหม่ การแก้ไขข้อมูล ในกรณีที่ต้องการแก้ไขข้อมูลหนังสือเล่มใดก็ตาม จะอยู่ในหน้าจอแสดงข้อมูลหนังสือ แต่ละเล่ม มขี น้ั ตอนดงั น้ี ScJraivpat 191
1. ท่หี นา้ จอแสดงขอ้ มูลหนงั สือแตล่ ะเล่ม ใหเ้ ลือกแก้ไข เพื่อเขา้ ส่หู นา้ จอแก้ไขขอ้ มลู ดงั รูปที่ 10-6 รปู ท่ ี 10-6 แสดงการแกไ้ ขราคาหนงั สอื รหสั 3333 จากรปู ที่10-6 ผเู้ ขยี นแกไ้ ขราคาหนงั สอื ใหมเ่ ปน็ 399 จากนนั้ คลกิ ทปี่ มุ่ แกไ้ ข เพอื่ บนั ทกึ การแกไ้ ขข้อมูลหนังสอื รหสั 3333 2. ทา้ ยทีส่ ุด หนังสือทถี่ กู แกไ้ ขข้อมลู กจ็ ะแสดงในรายการทันที ดงั รูปที่ 10-7 รูปท่ี 10-7 แสดงราคาหนงั สอื รหสั 3333 ใหม่ การลบข้อมลู ในสว่ นของการลบขอ้ มลู หนงั สอื อยใู่ นหนา้ จอแสดงขอ้ มลู หนงั สอื แตล่ ะเลม่ เชน่ กนั โดย การคลกิ ทปี่ ่มุ ลบข้อมลู เชน่ ตอ้ งการลบข้อมูลหนงั สือรหัส 0000 ดงั รปู ท่ี 10-8 รูปท่ี 10-8 แสดงการลบหนงั สอื รหสั 0000 192
CHAPTER 10 การเพ่ิม, แก้ไข, ลบ, ค้นหาและแสดงขอ้ มลู (CRUD) เทคนิคการจัดสครปิ ต์ในไฟล์ Pug ดว้ ย Visual Studio กอ่ นทจ่ี ะเขา้ สขู่ น้ั ตอนการสรา้ งโปรเจก็ ต์ ผเู้ ขยี นขอแนะน�ำ เทคนคิ การจดั สครปิ ตใ์ นไฟล์ Pug ดว้ ย Visual Studio กอ่ น เพราะวา่ การสร้างสว่ นแสดงผลดว้ ย Pug มเี งือ่ นไขการยอ่ หน้า 2 ประการ ดงั น้ี 1. ย่อหนา้ ด้วยการกดปุม่ Space บนคยี ์บอร์ด 2. ย่อหนา้ ดว้ ยการกดป่มุ Tab บนคยี ์บอร์ด ทัง้ 2 วธิ ีขา้ งต้น เราตอ้ งเลอื กใช้อย่างใดอยา่ งหน่งึ เท่านนั้ ในระหวา่ งการสร้างหน้าจอ ท่ีมีความซับซ้อน อาจจะเกิดภาวะความไม่ตั้งใจ ใช้ทั้ง 2 อย่างในหน้าจอเดียวกัน ส่งผลให้ เกิดขอ้ ผดิ พลาดขนึ้ มา มีขัน้ ตอนดังน้ี 1. สมมติว่า เราเขียนส่วนแสดง ผล books.pug เสรจ็ แล้ว และ ตอ้ งการจดั ยอ่ หนา้ ใหม่ ใหล้ าก เมาสเ์ ลอื กสครปิ ต์Pug ทงั้ หมด กอ่ น ดังรปู ที่ 10-9 รูปท ่ี 10-9 แสดงการเลอื กสครปิ ต์ Pug ท้งั หมด 2. ต่อมา ให้เลือกเมนู Edit > Advanced > Tabify Selected Lines เพอ่ื ส่งั ให้ Visual Studio จัดย่อหน้าในไฟล์ Pug ให้ถูก ต้อง ดังรปู ที่ 10-10 รูปท่ี 10-10 แสดงการจัดการย่อหน้า ใหม่ใน Visual Studio จากรูปที่ 10-10 หลงั จากทจี่ ัดยอ่ หน้าในไฟล์ Pug ถอื ว่าเสร็จสมบรู ณแ์ ลว้ ScJraivpat 193
โครงสร้างโปรเจก็ ต์ CRUD โครงสรา้ งโปรเจ็กต์ CRUD แสดงดงั รูปท่ี 10-11 รปู ท ี่ 10-11 แสดงรายการไฟลท์ งั้ หมด 1. ไฟล์ app.js ทำ�หน้าที่เพียงแค่ระบุเส้นทาง /books เข้าสู่ขั้นตอนการเพิ่ม, แก้ไข, ลบและแสดงขอ้ มูลหนงั สือ (CRUD) ดังสคริปตต์ ่อไปน้ี สครปิ ต์ JavaScript ที่ 10-1 การเพมิ่ , แกไ้ ข, ลบและแสดงข้อมลู หนังสอื (CRUD) (app.js) 1 ‘use strict’; 2 var debug = require(‘debug’); 3 var express = require(‘express’); 4 var path = require(‘path’); 5 var favicon = require(‘serve-favicon’); 6 var logger = require(‘morgan’); 7 var cookieParser = require(‘cookie-parser’); 8 var bodyParser = require(‘body-parser’); 9 var pug = require(‘pug’); 10 11 var mongoose = require(‘mongoose’); 12 var Schema = mongoose.Schema; 13 14 var BooksSchema = new Schema({ 15 isbn: String, 16 title: String, 194
Search
Read the Text Version
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296