บทคัดย่อ
บทความนี้ใช้ฐานข้อมูล Oracle เป็นตัวอย่างเพื่อแนะนำวิธีจัดเก็บข้อมูลและวิธีการประมวลผลในรูปแบบที่เรียบง่ายและเป็นสากล เมื่อพัฒนาแอปพลิเคชันเว็บโดยใช้เทคโนโลยี JSP เพื่อลดภาระงานในการพัฒนาและจัดเตรียมโค้ดโปรแกรมหลัก
บทนำ
เทคโนโลยี J2EE (Java 2 Enterprise Edition) ถูกนำมาใช้กันอย่างแพร่หลายในการพัฒนาแอปพลิเคชันเว็บ เทคโนโลยี JavaBean และ Servlet ช่วยให้นักพัฒนามีสภาพแวดล้อมการพัฒนาที่ชัดเจนยิ่งขึ้น กระบวนการทางธุรกิจโดยใช้ Beans เพื่อจัดเก็บข้อมูลและการประมวลผลทางธุรกิจบางอย่าง ในแอปพลิเคชันเว็บ งานประมวลผลการจัดเก็บข้อมูลธุรกิจในฐานข้อมูลมักจะลำบากมาก หนึ่งในรูปแบบหลักคือการจัดเก็บข้อมูลแบบฟอร์มในฐานข้อมูล กระบวนการประมวลผลแอปพลิเคชันทั้งหมดเกี่ยวข้องกับการดำเนินการจัดเก็บข้อมูลดังกล่าวจำนวนมากและแต่ละกระบวนการ จำเป็นต้องประมวลผลแบบฟอร์ม นักพัฒนาต้องใช้เวลาและพลังงานมากในการเขียนโปรแกรมจัดเก็บข้อมูลที่เกี่ยวข้องแยกกัน วิธีใดที่จะใช้เพื่อลดภาระงานในการพัฒนาการจัดเก็บข้อมูลในแบบฟอร์มเป็นคำถามที่ควรค่าแก่การศึกษา
วิธีจัดเก็บและประมวลผลข้อมูลแบบฟอร์มทั่วไปสองวิธี:
1. เขียนโค้ดโปรแกรมที่เกี่ยวข้องสำหรับแต่ละแบบฟอร์ม
ในหน้า JSP หรือ JavaBean หรือ Servlet ใช้ฟังก์ชัน request.getparameter() เพื่อแยกข้อมูลที่ส่งโดยแบบฟอร์มทีละรายการ หรือเขียน JavaBean ที่สอดคล้องกัน ใช้เมธอด setProperty เพื่อดึงข้อมูลลงใน JavaBean โดยอัตโนมัติ จากนั้นสร้างคำสั่ง SQL (แทรก อัปเดต ลบ) และสุดท้ายดำเนินการฟังก์ชันExecuteupdate() เพื่อให้การจัดเก็บข้อมูลตารางข้อมูลเสร็จสมบูรณ์
2. สร้างโค้ดโปรแกรม JavaBean สำหรับแต่ละตารางข้อมูลโดยอัตโนมัติ
ระบบฐานข้อมูลจะต้องสนับสนุนผู้ใช้ในการอ่านโครงสร้างตารางและระบุฟิลด์สำคัญ ใช้เครื่องมือการพัฒนาอย่างรวดเร็วเชิงวัตถุ เช่น PowerBuilder, Delphi ฯลฯ เพื่อพัฒนาโปรแกรมสร้างโค้ด Java อัตโนมัติ ในโปรแกรมนี้ โครงสร้างตารางฐานข้อมูลจะถูกอ่าน: ชื่อฟิลด์ ชนิดข้อมูล ความยาวข้อมูล และโค้ด JavaBean จะถูกสร้างขึ้นโดยอัตโนมัติ ในโค้ดนี้ ให้กำหนดตัวแปรที่มีชื่อเหมือนกันซึ่งสอดคล้องกับฟิลด์ในตาราง สร้างเมธอด setValue และ getValue สำหรับตัวแปรทั้งหมด และสร้างฟังก์ชันแทรก อัปเดต และลบ เพื่อจัดการการสร้างและการดำเนินการของคำสั่ง SQL สำหรับการแทรก อัปเดต และลบตามลำดับ
ในหน้าการประมวลผลข้อมูลที่ส่งโดยแบบฟอร์ม ให้เขียนโค้ดต่อไปนี้เพื่อจัดเก็บข้อมูลแบบฟอร์มใน JavaBean:
<jsp: useBean id="table" class="table1_bean" />
<jsp:setProperty name="table" property="*" />
(หมายเหตุ: table1_bean เป็น JavaBean ที่สร้างขึ้นโดยอัตโนมัติซึ่งสอดคล้องกับตารางบางตารางที่กล่าวถึงข้างต้น)
จากนั้นเรียกใช้ฟังก์ชันแทรก อัปเดต และลบใน table1_bean เพื่อจัดเก็บข้อมูลตารางข้อมูลให้เสร็จสมบูรณ์และส่งคืนผลลัพธ์การดำเนินการ ชอบ:
<%boolean Success =table.insert(); %>
วิธีแรกนั้นง่ายและใช้งานง่าย แต่คุณต้องเขียนโปรแกรมประมวลผลข้อมูลที่เกี่ยวข้องสำหรับแต่ละแบบฟอร์ม สำหรับการใช้งานที่มีขนาดใหญ่กว่าเล็กน้อย จำนวนแบบฟอร์มอาจมีขนาดใหญ่ ส่งผลให้มีภาระงานในการพัฒนาที่หนักหน่วงและประสิทธิภาพในการพัฒนาต่ำ เมื่อโครงสร้างตารางเปลี่ยนแปลง เช่น การเพิ่มหรือการลบฟิลด์ จำเป็นต้องแก้ไขโปรแกรมประมวลผลข้อมูลที่เกี่ยวข้อง
วิธีที่สองนั้นง่ายกว่าวิธีแรกมาก การประมวลผลข้อมูลของแต่ละตารางข้อมูลจะถูกนำไปใช้โดย JavaBean ที่เกี่ยวข้อง JavaBean จะถูกสร้างขึ้นโดยอัตโนมัติและไม่จำเป็นต้องเขียนเมื่อโครงสร้างตารางเปลี่ยนไป JavaBean และเขียนทับหลังจากคอมไพล์ด้วย Java คลาสดั้งเดิมสามารถใช้ได้ อย่างไรก็ตาม วิธีการนี้จำเป็นต้องมีการพัฒนาโปรแกรมสร้าง JavaBean อัตโนมัติ และ JavaBeans จำเป็นต้องได้รับการสร้างใหม่และคอมไพล์เมื่อโครงสร้างตารางเปลี่ยนแปลง
ขอแนะนำวิธีที่ง่ายและเป็นสากลในการจัดเก็บข้อมูลแบบฟอร์ม
ในการพัฒนาแอปพลิเคชันเว็บ แบบฟอร์มจำนวนมากจะถูกส่งไปยังเซิร์ฟเวอร์แบ็กเอนด์หลังจากการตรวจสอบข้อมูลอย่างง่ายบนเบราว์เซอร์ส่วนหน้า เซิร์ฟเวอร์ไม่ดำเนินการประมวลผลข้อมูลใด ๆ และจัดเก็บข้อมูลโดยตรง ตารางฐานข้อมูล ในกรณีนี้ เราสามารถเขียนโปรแกรมเพื่อประมวลผลแบบฟอร์มเหล่านี้อย่างสม่ำเสมอและจัดเก็บข้อมูลไว้ในตารางข้อมูลที่สอดคล้องกัน วิธีนี้ยังต้องใช้ระบบฐานข้อมูลเพื่อรองรับการอ่านโครงสร้างตารางและการระบุฟิลด์คีย์ เราใช้เทคโนโลยี JSP ในการเขียนโปรแกรมนี้ และไฟล์โปรแกรมชื่อ DbdataStore.jsp
1. รูปแบบการเรียก
วิธีการเรียก Action ของแบบฟอร์มในเว็บเพจเป็นดังนี้:
<Form Name=Frm1 Method=Post Action="DBdataStore.jsp? tablename=table1&OperType=…">
table1 เป็นชื่อตารางของตารางฐานข้อมูล ตำแหน่งที่ข้อมูลจะถูกจัดเก็บ และการดำเนินการ OperType มีสามประเภท: แทรก อัปเดต และลบ
ค่าชื่อใน <input type=text name=…>, <textarea name=…><select name=…> ในแบบฟอร์มควรเหมือนกับชื่อฟิลด์ของตารางข้อมูล แบบฟอร์มจะถูกแยกทีละรายการใน DBdataStore.jsp หากไม่มีอินพุตที่กำหนดไว้ในแบบฟอร์มและค่าผลลัพธ์เป็นค่า null ฟิลด์จะไม่ถูกประมวลผล
2. ดูคำจำกัดความโดยใช้ Oracle เป็นตัวอย่าง
1) สร้างมุมมองประเภทข้อมูลสำหรับแต่ละคอลัมน์ของตาราง
สร้างหรือแทนที่มุมมอง v_dbstru AS SELECT table_name, column_name, data_type, data_length, data_precision, data_scale, column_id
จาก all_tab_columns โดยที่ Owner='user1'; //user1 เป็นเจ้าของตารางข้อมูล
2) สร้างมุมมองคอลัมน์หลักของตาราง
CREATE OR REPLACE VIEW v_pkey_column AS
เลือก b.table_name, b.column_name, b.position
จาก all_constraints a, all_cons_columns b
โดยที่ a.owner=b.owner AND a.constraint_name=b.constraint_name AND a.owner='user1' AND a.constraint_type='P';
3. รหัสโปรแกรมหลัก
1) สตริงการเริ่มต้นโปรแกรม
tablename=request.getParameter(" tablename"); //แยกชื่อตาราง
String OperType=request.getParameter("OperType"); // แยกประเภทการดำเนินการ
สตริง sFieldValue="";//จัดเก็บค่าข้อมูลฟิลด์ที่ส่งโดยแบบฟอร์ม
String fieldname="", Datatype="" //ชื่อฟิลด์ที่เก็บข้อมูล, ชนิดข้อมูลของฟิลด์
int iFieldvalue = 0;
สตริง updateSql="", โดยที่Sql=" โดยที่ ", insSql1="", insSql2="", opSql="", strSql="";
ชุดผลลัพธ์ rs1=null, rs2=null;
insSql1="ใส่ลงใน "+ชื่อตาราง+" (";
insSql2="values(";
2) สร้างส่วนฟิลด์คีย์ของคำสั่ง sql
และสร้างส่วนฟิลด์คีย์ของคำสั่ง insert เช่น: insert into table1(id andvalues(100));
ใช้เฉพาะฟิลด์คีย์เท่านั้น สร้างคำสั่งอัปเดตและลบโดยที่ parts เช่น: โดยที่ id=100;
เมื่อมีการอัปเดตประเภทการดำเนินการ ข้อมูลของฟิลด์คีย์จะไม่ได้รับการแก้ไขในเว็บฟอร์ม
rs1=Stmt.executeQuery("SELECT column_name FROM v_pkey_column WHERE table_name='"+tablename+"'"); //รับชื่อฟิลด์คีย์
ในขณะที่(rs1.next()){
fieldname=rs1.getString("คอลัมน์_ชื่อ");
rs2=Stmt.executeQuery("SELECT data_type FROM v_dbstru WHERE table_name='"+tablename+"' AND column_name='"+fieldname+"'"); // รับประเภทข้อมูลฟิลด์คีย์ if(rs2.next()){
ประเภทข้อมูล=rs2.getString("data_type");
sFieldValue=request.getParameter(fieldname.toLowerCase());
//สร้างส่วนฟิลด์คีย์ของคำสั่ง insert if(OperType.equals("insert")){
insSql1+=ชื่อฟิลด์+",";
ถ้า((sFieldValue==null) ){
//เมื่อไม่ได้ส่งข้อมูลฟิลด์คีย์ในแบบฟอร์ม บทความนี้จะประมวลผลเป็นประเภทตัวเลขเท่านั้น และค่าข้อมูลจะถูกคำนวณตามหมายเลขซีเรียล
rs2= Stmt.executeQuery("SELECT max("+fieldname+")+1 FROM "+tablename(); rs2. ถัดไป (); iFieldvalue=rs2.getInt(1); ; }else if(Datatype.equals("DATE")){
insSql2+= "To_Date('" + sFieldValue + "','YYYY-MM-DD'),";
}else if(Datatype.equals("VARCHAR2") || Datatype.equals("CHAR")){
insSql2+="'" + sFieldValue+"',";}
อย่างอื่น /*NUMBER, FLOAT */ insSql2+=sFieldValue+","}
//สร้างคำสั่งอัพเดตและลบ โดยที่ part: โดยที่ fieldname=... AND
if(OperType.equals("อัพเดต") || OperType.equals("ลบ")){
ถ้า(Datatype.equals("DATE")){
โดยที่Sql+=fieldname+"=To_Date('" + sFieldValue + "','YYYY-MM-DD') AND ";
}else if(Datatype.equals("VARCHAR2") || Datatype.equals("CHAR")){
โดยที่Sql+=ชื่อฟิลด์+"='" + sFieldValue+"' และ ";}
อื่น /*NUMBER, FLOAT */ โดยที่Sql+=fieldname+"="+ sFieldValue+" AND ";}
-
-
โดยที่Sql=whereSql.substring(0,whereSql.length()-4);
3) คำสั่ง sql ของส่วนฟิลด์ที่ไม่ใช่คีย์จะสร้าง
คำสั่ง update เช่น: update table1 set column1=value1,... โดยที่ id=
คำสั่งแทรก100
รายการ เช่น: แทรกลงใน table1(id, column1,…)values(100, value1,…)
updateSql="update "+tablename+" set ";
strSql="SELECT column_name, data_type, data_length, data_precision, data_scale จาก v_dbstru a "+"where table_name='"+tablename+"' และ a.column_name ไม่ได้อยู่ใน (SELECT b.column_name จาก v_pkey_column b โดยที่ b.table_name=a.table_name )";
rs1=Stmt.executeQuery(strSql); // รับชื่อฟิลด์และประเภทข้อมูลของฟิลด์ที่ไม่ใช่คีย์
ในขณะที่(rs1.next()){
fieldname=rs1.getString("column_name"); Datatype=rs1.getString("data_type"); sFieldValue=request.getParameter(fieldname.toLowerCase()); //หากแบบฟอร์มไม่ส่งค่าของฟิลด์ ฟิลด์กำลังประมวลผล if((sFieldValue!=null)){
//สร้างคำสั่ง insert =insSql1+insSql2 นั่นคือ แทรกลงในชื่อตาราง(… และค่า(…)
if(OperType.equals("insert")){ insSql1+=fieldname+",";
ถ้า(Datatype.equals("DATE")){
insSql2+= "To_Date('" + sFieldValue + "','YYYY-MM-DD'),";
} else if(Datatype.equals("VARCHAR2") || Datatype.equals("CHAR")){
insSql2+="'" + sFieldValue+"',";}else /*NUMBER,FLOAT*/ insSql2+= sFieldValue+";}
//สร้างคำสั่งอัปเดต=updateSql+whereSql นั่นคือ อัปเดตชุดชื่อตาราง... โดยที่ชื่อฟิลด์=... if(OperType.equals("update")){
ถ้า(Datatype.equals("DATE")){
updateSql+=fieldname+"=To_Date('" + sFieldValue + "','YYYY-MM-DD'),";
}else if(Datatype.equals("VARCHAR2") || Datatype.equals("CHAR")){
updateSql+=fieldname+"='" + sFieldValue,1}+"',";}else /*NUMBER,FLOAT*/ updateSql+=fieldname+"="+sFieldValue+",";}))
rs1.close();
4) สร้างคำสั่ง sql ที่สมบูรณ์และดำเนินการ
if(OperType.equals("insert"))
opSql=insSql1.substring(0, insSql1.length()-1)+")"+insSql2.substring(0, insSql2.length()-1)+"";
ถ้า(OperType.equals("อัพเดต"))
opSql=updateSql.substring(0, updateSql.length()-1)+" "+whereSql; if(OperType.equals("ลบ")
opSql="ลบจาก "+ชื่อตาราง+" "+whereSql;
//สร้างคำสั่ง sql ที่สมบูรณ์แล้ว opSql แล้ว
ลอง {sqlnrows=Stmt.executeUpdate(opSql);}
catch(SQLException e){out.println("SQLException:"+opSql);}
4. คุณลักษณะ
วิธีการนี้ใช้โปรแกรมนี้อย่างสม่ำเสมอสำหรับรูปแบบที่จัดเก็บโดยตรงทั้งหมด เป็นสากล และไม่จำเป็นต้องใช้กับทุกรูปแบบหรือทุกรูปแบบ โปรแกรมที่เกี่ยวข้องได้รับการพัฒนาอย่างอิสระสำหรับตารางข้อมูล ในเวลาเดียวกัน เมื่อโครงสร้างตารางเปลี่ยนแปลง ก็ไม่จำเป็นต้องแก้ไขโปรแกรม DBdataStore.jsp โปรแกรมนี้ยังสามารถเขียนใหม่เป็น Servelet และรูปแบบการเรียกคือ <Form Name=Frm1 Method=Post Action="DBdataStoreServelet?tablename=table1&OperType=…">
ในเว็บแอปพลิเคชัน
หากข้อมูลในแบบฟอร์มจำเป็นต้องมีการตรวจสอบข้อมูลเพิ่มเติมหรือการประมวลผลในพื้นหลังของเซิร์ฟเวอร์หลังจากส่งแล้ว จะต้องใช้วิธีที่สอง แต่ในหลายกรณี ผู้ใช้ป้อนหรือแก้ไขข้อมูลในแบบฟอร์ม ใช้ JavaScript เพื่อตรวจสอบหรือประมวลผลข้อมูลบนเบราว์เซอร์ส่วนหน้า จากนั้นจึงส่ง ไม่มีการประมวลผลบนเซิร์ฟเวอร์ส่วนหลัง และข้อมูลที่ส่งมา โดยแบบฟอร์มจะถูกจัดเก็บโดยตรงในฐานข้อมูลในตาราง ในเวลานี้ การใช้วิธีที่ 3 นั้นง่ายมาก และสามารถลดภาระงานของนักพัฒนาได้อย่างมาก