1. ก่อนอื่นอธิบายว่า JDBC คืออะไร
ก่อนที่ฉันจะเห็นคำนามนี้ได้อย่างรวดเร็วก่อนฉันรู้สึกว่าจำเป็นต้องรู้ว่าชื่อภาษาอังกฤษเต็มรูปแบบคืออะไร การเชื่อมต่อฐานข้อมูล Java ซึ่งแปลเป็นฐานข้อมูล Java ที่เชื่อมต่อได้อย่างแท้จริง ในการกล่าวอย่างตรงไปตรงมาฉันต้องการจัดเตรียมชุดของลิงก์ระดับกลางเพื่อเชื่อมต่อรหัส Java และฐานข้อมูลเพื่อให้สามารถควบคุมฐานข้อมูลได้โดยตรงโดยใช้รหัส Java
2. สาระสำคัญของ JDBC
มันเป็นโซลูชัน Java ในการเข้าถึงฐานข้อมูล หวังว่าจะเข้าถึงฐานข้อมูลที่แตกต่างกันในลักษณะเดียวกันเพื่อให้ได้อินเทอร์เฟซการทำงานของ Java ที่ไม่เกี่ยวข้องกับฐานข้อมูลเฉพาะ
JDBC เป็นชุดของอินเทอร์เฟซที่ได้มาตรฐานเป็นหลัก ผู้ผลิตฐานข้อมูลที่แตกต่างกันใช้อินเทอร์เฟซนี้ตามลักษณะฐานข้อมูลของตนเองและเราไม่จำเป็นต้องใส่ใจเกี่ยวกับวิธีการใช้งานเฉพาะ
อินเทอร์เฟซหลักที่ดำเนินการโดยผู้ผลิตฐานข้อมูลใน JDBC มีดังนี้:
DriverManager: การจัดการคนขับ
การเชื่อมต่อ,
DatabaseMetadata: เชื่อมต่อกับอินเทอร์เฟซ
คำแถลง,
การเตรียมความพร้อม
callablestatement: คำสั่งวัตถุอินเทอร์เฟซ
ชุดผลลัพธ์
ResultsEtMetAdata: อินเทอร์เฟซ Resultset
3. JDBC ทำงานอย่างไร
โปรแกรมเมอร์เรียกชิ้นส่วนที่ดำเนินการโดยผู้ผลิตฐานข้อมูลพื้นฐาน
นั่นคือ: 1) ใช้ขั้นตอนแรกของการเชื่อมต่อผ่านส่วนต่อประสานการเชื่อมต่อ
2) ถ่ายโอนคำสั่ง SQL ผ่านผลการแถลง
3) กระบวนการหลักของการบันทึกผลลัพธ์การส่งคืนฐานข้อมูลไปยังอินเตอร์เฟสชุดผลลัพธ์ชุดผลลัพธ์สามารถสรุปได้เป็น:
1) โหลดไดรเวอร์และสร้างการเชื่อมต่อ
2) สร้างวัตถุคำสั่ง
3) เรียกใช้คำสั่ง SQL
4) ส่งชุดผลลัพธ์กลับ
5) ปิดการเชื่อมต่อ
ด้านล่างฉันจะใช้ฐานข้อมูล Oracle ที่ฉันเรียนรู้และร่วมมือกับ Eclips เป็นตัวอย่างในการอธิบายวิธีการใช้ JDBC
1) การโหลดไดรเวอร์
วิธีที่ใช้คือ: class.forName ("ไดรเวอร์");
สิ่งที่ฉันรู้เกี่ยวกับวิธีรับไดรเวอร์นี้คือ: ขยายแพ็คเกจ JDBC JAR ถ้าฉันใช้ ojdbc6.jar, ค้นหา oracle.jdbc.driver, ค้นหา oracledriver แล้วคลิกขวาคุณภาพและวางไว้ในคำพูดเช่น: class.forname ("oracle.jdbc.driver
2) สร้างการเชื่อมต่อ
วิธีที่ใช้คือ: conn = drivermanager.getConnection ("JDBC: Oracle: Thin: @IP ที่อยู่: 1521: ORCL", "บัญชีฐานข้อมูล", "รหัสผ่านฐานข้อมูล");
ตัวอย่างเช่น: conn = drivermanager.getConnection ("JDBC: Oracle: Thin:@172.16.3.8: 1521: ORCL", "JSD1601", "JSD1601");
3) สร้างวัตถุคำสั่ง
วิธีที่ใช้คือ: คำสั่ง stmt = conn.createstatement ();
ควรสังเกตว่าการเชื่อมต่อที่สร้างขึ้นในขั้นตอนที่สองใช้เรียกวิธีการ
เรียกใช้วิธีการ ExecuteUpdate และส่งคำสั่ง SQL ไปยังเพื่อเรียกใช้คำสั่ง SQL ที่เป็นลายลักษณ์อักษร ควรสังเกตที่นี่ว่าประเภทของ SQL ที่วิธีการ ExecuteUpdate สามารถดำเนินการได้คือแทรกอัปเดตลบ
ตัวอย่างเช่น: คำสั่ง stmt = conn.createstatement ();
String SQL = "แทรกลงใน EMP_JIAWENZHE (empno, ename, sal, deptno) ค่า (1,000, 'Jia Wenzhe', 1500,10)";
int i = stmt.executeUpdate (SQL);
ค่าส่งคืนฉันนี่คือจำนวนแถวที่ได้รับผลกระทบ เราสามารถตัดสินได้ว่าการดำเนินการประสบความสำเร็จตามจำนวนแถวที่ได้รับผลกระทบหรือไม่
4) ชุดผลลัพธ์ที่ส่งคืนส่วนใหญ่หมายถึงการดำเนินการเลือก (ไม่ได้กล่าวถึงที่นี่)
5) ในที่สุดปิดการเชื่อมต่อ
ตัวอย่างเช่น: conn.close ();
แสดงรายการรหัสทั้งหมดรวมถึงความคิดเห็น:
แพ็คเกจ jdbc_day01; นำเข้า java.sql.*;/*** แสดงขั้นตอนการดำเนินการของ jdbc* 1. โหลดไดรเวอร์* 2. สร้างการเชื่อมต่อ* 3. สร้างวัตถุคำสั่ง* 4 ส่งคำสั่ง SQL* 5 หากการส่งคำสั่ง SELECT หลัก (สตริง [] args) พ่น Sqlexception {// ข้อกำหนด: สร้างพนักงานหมายเลขพนักงานชื่อพนักงานเงินเดือนหมายเลขแผนก // 1 การเชื่อมต่อ conn = null; ลอง {class.forname ("oracle.jdbc.driver.oracledriver"); System.out.println ("การโหลดไดรเวอร์สำเร็จ"); // 2. conn = drivermanager.getConnection ("JDBC: Oracle: Thin:@172.16.3.8: 1521: ORCL", "JSD1601", "JSD1601"); System.out.println (conn.getClass (). getName ()); // 3. // วัตถุคำสั่งสถิติ ส่งและเรียกใช้คำสั่ง SQL/ * * int exclupdate (String SQL); * ส่งแทรกอัปเดตคำสั่งลบ* ค่าส่งคืน int แสดงจำนวนแถวที่มีผลต่อตารางฐานข้อมูล*/ คำสั่ง stmt = conn.createstatement (); String SQL = "แทรกลงใน EMP_JIAWENZHE (empno, ename, sal, deptno)" + "ค่า (1,000, 'Wang Xiaoer', 1500,10)"; int i = stmt.executeUpdate (SQL); if (i> 0) {system.out.println ("บันทึกสำเร็จ!"); }} catch (classnotFoundException e) {e.printStackTrace (); // 1. บันทึกบันทึก // 2 แจ้งผู้โทรให้โยน runtimeException ใหม่ ("ข้อผิดพลาดของไดรเวอร์โหลด", e); } ในที่สุด {// ปิดการเชื่อมต่อถ้า (conn! = null) {ลอง {conn.close (); } catch (sqlexception e) {e.printstacktrace (); - หมายเหตุ: แพ็คเกจ JAR ที่สามารถใช้ในฐานข้อมูล Oracle: OJDBC14.JAR/OJDBC6.JAR (Oracle12C ใช้สิ่งนี้)
แพ็คเกจ JAR ที่สามารถใช้งานได้โดยฐานข้อมูล MySQL: mysql-connector-java-5.0.4-bin.jar
การโหลดคลาสไดรเวอร์:
class.forName ("com.mysql.jdbc.driver"); 1. การแนะนำวิธีบรรจุภัณฑ์
สิ่งที่ทำให้ฉันประทับใจมากที่สุดคือเมื่อฉันเขียนรหัสชุดหนึ่งหากมีการใช้รหัสซ้ำฉันจะเลือกวิธีการห่อหุ้มรหัสในระดับหนึ่งจากการห่อหุ้มวิธีการห่อหุ้มคลาส การใช้ JDBC ที่กล่าวถึงก่อนหน้านี้สำหรับการดำเนินการฐานข้อมูล (การเพิ่มการลบและการปรับเปลี่ยนเนื่องจากการสืบค้นเกี่ยวข้องกับการดำเนินการของชุดผลลัพธ์และประกาศแยกกัน) แบ่งออกเป็นสี่กระบวนการ:
1) การโหลดไดรเวอร์
2) สร้างการเชื่อมต่อ
3) สร้างวัตถุคำสั่งและส่ง SQL
4) ปิดการเชื่อมต่อ
กล่าวอีกนัยหนึ่งเมื่อเราดำเนินการฐานข้อมูลใด ๆ เราต้องทำตามขั้นตอนข้างต้นซึ่งนำไปสู่การซ้ำซ้อนของรหัส ดังนั้นเราจึงเสนอให้ห่อหุ้มขั้นตอนทั่วไปเหล่านี้ลงในชั้นเรียนเพื่อให้สามารถกลายเป็นคลาสเครื่องมือสำหรับการใช้งานของฉัน
2. การห่อหุ้มสามเวอร์ชัน
เวอร์ชัน 1
เมื่อฉันเรียนรู้ฉันค่อยๆห่อหุ้มชั้นเรียนเหล่านี้อย่างค่อยเป็นค่อยไปและปรับปรุงให้ดีขึ้นเรื่อย ๆ เพราะหากมีการเสนอการห่อหุ้มรุ่นสุดท้ายโดยตรงมันเป็นเรื่องยากสำหรับผู้เริ่มต้นที่จะยอมรับ ฉันจะอธิบายสิ่งแรกนั่นคือวิธีการห่อหุ้มที่ง่ายที่สุด:
คุณจะพบก่อนหน้านี้ว่าไม่ว่าคุณต้องการใช้งานฐานข้อมูลการโหลดไดรเวอร์เป็นสิ่งจำเป็นและไดรเวอร์โหลดส่วนใหญ่จะรวมถึงการประกาศชื่อไดรเวอร์ที่อยู่ IP หมายเลขพอร์ตชื่อบัญชีฐานข้อมูลรหัสผ่าน ฯลฯ
String String ส่วนตัว Driverclass = "Oracle.jdbc.driver.oracledriver"; url สตริงแบบคงที่ส่วนตัว = "JDBC: Oracle: Thin: Losthost: 1521: ORCL"; ผู้ใช้สตริงคงที่ส่วนตัว = "ระบบ"; รหัสผ่านสตริงคงที่ส่วนตัว = "123";
ด้วยวิธีนี้เมื่อสร้างการเชื่อมต่อฉันสามารถรับชื่อของตัวแปรโดยตรงเพื่อแทนที่สตริงยาว เมื่อโหลดไดรเวอร์ Method Class.forName จะถูกประกาศในบล็อกแบบคงที่เนื่องจากในขณะที่โหลดข้อมูลไดรเวอร์จะถูกโหลด
ดังที่แสดงด้านล่าง:
คงที่ {ลอง {class.forName (DriverClass); } catch (classnotFoundException e) {e.printStackTrace (); โยน runtimeException ใหม่ ("ข้อผิดพลาดของไดรเวอร์โหลด", e); -สำหรับการสร้างการเชื่อมต่อเราเรียกวิธีการ getConnection ของ DriverManager และใส่ชื่อผู้ใช้และรหัสผ่านที่สอดคล้องกันลงไป เราใส่วิธีนี้ลงในวิธีที่ฉันกำหนดโดยตรงจากนั้นเรียกใช้วิธีการของฉันโดยตรงเพื่อสร้างการเชื่อมต่อ ควรสังเกตว่าค่าส่งคืนของวิธีการคือวัตถุการเชื่อมต่อซึ่งเข้าใจง่ายเพราะเราต้องการรับวัตถุประเภทการเชื่อมต่อนี้ดังที่แสดงด้านล่าง:
การเชื่อมต่อแบบคงที่สาธารณะ getConnection () พ่น sqlexception {Connection Conn = driverManager.getConnection (URL, ผู้ใช้, รหัสผ่าน); กลับ Conn; -จากนั้นสร้างวัตถุคำสั่งและส่ง SQL แน่นอน SQL เป็นสถานที่พิเศษเพียงแห่งเดียวที่นี่เพราะสิ่งที่ SQL ต้องทำนั้นแตกต่างกันมากดังนั้นขั้นตอนนี้ไม่จำเป็นต้องถูกห่อหุ้ม
ในที่สุดปิดการเชื่อมต่อซึ่งเรียกว่าวิธีปิด () ดังที่แสดงด้านล่าง
โมฆะคงที่สาธารณะปิด (Connection Conn) {if (conn! = null) {ลอง {conn.close (); } catch (sqlexception e) {e.printstacktrace (); โยน runtimeException ใหม่ ("ข้อผิดพลาดการเชื่อมต่อปิด", e); -แพคเกจเวอร์ชันแรกโดยรวมมีดังนี้:
แพ็คเกจ jbbc_day01; นำเข้า java.sql.connection; นำเข้า java.sql.drivermanager; นำเข้า java.sql.sqlexception;/** * ใช้ในการจัดการการเชื่อมต่อ * @author jiawenzhe * */คลาสสาธารณะ url สตริงแบบคงที่ส่วนตัว = "JDBC: Oracle: Thin: Losthost: 1521: ORCL"; ผู้ใช้สตริงคงที่ส่วนตัว = "ระบบ"; รหัสผ่านสตริงคงที่ส่วนตัว = "123"; // 1. การโหลดไดรเวอร์คงที่ {ลอง {class.forName (DriverClass); } catch (classnotFoundException e) {e.printStackTrace (); โยน runtimeException ใหม่ ("การโหลดข้อผิดพลาดไดรเวอร์", e); }}} // 2 สร้างการเชื่อมต่อ/** วิธีการกำหนดวิธีที่สามารถสร้างการเชื่อมต่อ* ประเภทค่าคืนค่า: ไม่ว่าจะมีผลการดำเนินการหากมีประเภทของผลลัพธ์คือประเภทค่าคืนค่า* รายการพารามิเตอร์:* ไม่ว่าจะมีข้อมูลที่ไม่แน่นอนในฟังก์ชันวิธีการเข้าร่วมในการดำเนินการหากมีการเชื่อมต่อกับผู้ใช้ กลับ Conn; } // 3 ปิดโมฆะคงที่การเชื่อมต่อสาธารณะปิด (Connection Conn) {if (conn! = null) {ลอง {conn.close (); } catch (sqlexception e) {e.printstacktrace (); โยน runtimeException ใหม่ ("ข้อผิดพลาดการเชื่อมต่อปิด", e); -เพียงแค่ห่อหุ้มด้วยวิธีนี้จากนั้นเรียกคลาส Encapsulation โดยตรงเมื่อดำเนินการ SQL สิ่งที่คุณต้องเขียนคือการสร้างวัตถุคำสั่งของคุณและส่งคำสั่ง SQL ของคุณ
เวอร์ชัน 2
ในความเป็นจริงเวอร์ชัน 2 นั้นคล้ายกับเวอร์ชัน 1 มากเพื่อสร้างข้อบกพร่องอย่างใดอย่างหนึ่งของเวอร์ชัน 1 นั่นคือเมื่อคุณเปลี่ยนฐานข้อมูลรหัสผ่านบัญชีของฐานข้อมูลต่าง ๆ จะแตกต่างกันดังนั้นคุณต้องแก้ไขรหัสผ่านบัญชีและที่อยู่ IP ก่อนหน้านี้ฉันได้ห่อหุ้มสิ่งเหล่านี้ไว้ในคลาสเครื่องมือในรูปแบบของสตริงซึ่งหมายความว่าเราต้องแก้ไขคลาสเครื่องมือทุกครั้งที่เราเปลี่ยนฐานข้อมูลซึ่งไม่เหมาะสมมาก ดังนั้นเราจึงเสนอวิธีการปรับปรุงเพื่อนำข้อมูลการเชื่อมต่อเหล่านี้ลงในไฟล์การกำหนดค่าและคลาสเครื่องมือจะอ่านไฟล์การกำหนดค่านี้ เราสามารถแก้ไขไฟล์การกำหนดค่าได้โดยตรงเมื่อแก้ไข
ก่อนที่จะแนะนำรุ่นนี้ฉันแนะนำคลาสใหม่คุณสมบัติซึ่งเป็นไฟล์ที่สามารถอ่านและอ่านเนื้อหาไฟล์การกำหนดค่าในรูปแบบของสตรีมแล้วกลับไปที่คลาสเครื่องมือ
ก่อนอื่นฉันจะยกตัวอย่างของไฟล์การกำหนดค่า ในความเป็นจริงไม่จำเป็นต้องอธิบาย เห็นได้ชัดอย่างรวดเร็วดังที่แสดงด้านล่าง:
jdbc.driverclass = oracle.jdbc.driver.oracledriverjdbc.url = jdbc: Oracle: Thin: localhost: orcljdbc.user = systemjdbc.password = 123
ด้านหน้าคือคีย์ต่อไปนี้เป็นค่าและค่าคีย์ก่อนหน้านี้ถูกกำหนดโดยตัวเราเองเช่นเดียวกับการกำหนดชื่อตัวแปรค่าที่ตามมาคือสถานการณ์จริงของฐานข้อมูลของเรา สิ่งที่เราต้องให้ความสนใจเป็นพิเศษที่นี่คือชื่อต่อท้ายของไฟล์กำหนดค่านี้จะต้องจบลงด้วย. properties เพราะด้วยวิธีนี้คลาสคุณสมบัติสามารถอ่านได้
ตัวอย่างของส่วนนี้มีดังนี้:
คงที่ {ลอง {// โหลดคุณสมบัติข้อมูลไฟล์คุณสมบัติ POP = คุณสมบัติใหม่ (); pop.load (dbutil2.class.getClassLoader (). getResourceasstream ("db.properties")); url = pop.getProperty ("jdbc.url"); driverclass = pop.getProperty ("jdbc.driverclass"); user = pop.getProperty ("jdbc.user"); รหัสผ่าน = pop.getProperty ("jdbc.password"); class.forName (DriverClass); } catch (classnotFoundException e) {e.printStackTrace (); โยน runtimeException ใหม่ ("ข้อผิดพลาดของไดรเวอร์โหลด", e); } catch (ioexception e) {// todo บล็อก catch block ที่สร้างอัตโนมัติ e.printstacktrace (); -วิธีการโหลด () คือการอ่านหรือถือได้ว่ากำลังโหลดไฟล์การกำหนดค่า เพียงจำประโยคทั้งหมดนี้โดยไม่เจาะลึกความหมายของมัน getProperty () ได้รับค่าที่สอดคล้องกันผ่านคีย์ซึ่งคล้ายกับรูปแบบของการได้รับค่าสำหรับชุดคู่คีย์-ค่า
รหัสโดยรวมมีดังนี้:
แพ็คเกจ JBBC_DAY01; นำเข้า Java.io.FileInputStream; นำเข้า Java.io.ioException; นำเข้า Java.io.InputStream; นำเข้า Java.sql.Connection; นำเข้า Java.sql.driverManager; นำเข้า Java.sql.sqlexception; บันทึกในไฟล์คุณสมบัติ * @author jiawenzhe * */คลาสสาธารณะ dbutil2 {private string string driverclass; URL สตริงคงที่ส่วนตัว; ผู้ใช้สตริงคงที่ส่วนตัว; รหัสผ่านสตริงแบบคงที่ส่วนตัว // 1. โหลดไดรเวอร์คงที่ {ลอง {// โหลดคุณสมบัติข้อมูลไฟล์คุณสมบัติ pop = new properties (); pop.load (dbutil2.class.getClassLoader (). getResourceasstream ("db.properties")); url = pop.getProperty ("jdbc.url"); driverclass = pop.getProperty ("jdbc.driverclass"); user = pop.getProperty ("jdbc.user"); รหัสผ่าน = pop.getProperty ("jdbc.password"); class.forName (DriverClass); } catch (classnotFoundException e) {e.printStackTrace (); โยน runtimeException ใหม่ ("ข้อผิดพลาดของไดรเวอร์โหลด", e); } catch (ioexception e) {// todo บล็อก catch block ที่สร้างอัตโนมัติ e.printstacktrace (); }} // 2 สร้างการเชื่อมต่อ/** วิธีการกำหนดวิธีที่สามารถสร้างการเชื่อมต่อ* ประเภทค่าคืนค่า: ไม่ว่าจะมีผลการดำเนินการหากมีประเภทของผลลัพธ์คือประเภทค่าคืนค่า* รายการพารามิเตอร์:* ไม่ว่าจะมีข้อมูลที่ไม่แน่นอนในฟังก์ชันวิธีการเข้าร่วมในการดำเนินการหากมีการเชื่อมต่อกับผู้ใช้ กลับ Conn; } // 3 ปิดโมฆะคงที่การเชื่อมต่อสาธารณะปิด (Connection Conn) {if (conn! = null) {ลอง {conn.close (); } catch (sqlexception e) {e.printstacktrace (); โยน runtimeException ใหม่ ("ข้อผิดพลาดการเชื่อมต่อปิด", e); -