ฉันเรียนรู้ JDBC เมื่อไม่นานมานี้และเชื่อมต่อกับ MySQL เพื่อรับข้อมูล จากข้อมูลตัวอย่างของครูฉันต้องบันทึกข้อมูลบางอย่างเช่นชื่อและพวกเขาทั้งหมดเป็นภาษาอังกฤษ ฉันไม่ต้องการใช้ภาษาอังกฤษในเวลานั้นดังนั้นฉันจึงบันทึกชื่อเพื่อนร่วมห้องของฉัน ฮิฮิเป็นผลให้มีบางอย่างผิดปกติ
เชื่อมต่อกับคำสั่งฐานข้อมูล:
สตริงสุดท้ายคงที่ db_url = "jdbc: mysql: // localhost/filemanagement";
คำสั่งค้นหา:
สตริงสุดท้ายคงที่ส่วนตัว TheUserQuery = "เลือกชื่อรหัสผ่านบทบาทจาก userInfo ที่ชื่อ =?";
ฉันใช้ชื่อของฉันในการสืบค้น nullpointerexception เป็นที่ชัดเจนว่าไม่พบข้อมูลที่เกี่ยวข้องกับชื่อของฉันและมีอยู่ในฐานข้อมูล ทำไมถึงเป็นเช่นนี้?
คำตอบจาก Baidu คือรหัสที่อ่านไม่ออกภาษาจีน โซลูชันคือการแก้ไขคำสั่งฐานข้อมูลการเชื่อมต่อเป็น:
สตริงสุดท้ายคงที่ db_url = "jdbc: mysql: // localhost/filemangagement? useunicode = true & catreatencoding = gbk";
ลองอีกครั้ง
ไม่เป็นไร! แต่ทำไมถึงเป็นเช่นนี้? พารามิเตอร์สองตัวนั้นคืออะไร? เหตุใดปัญหาจึงได้รับการแก้ไขหลังจากเพิ่ม
พารามิเตอร์ทั้งสองนี้มีการอธิบายดังนี้:
ค่าเริ่มต้นสำหรับพารามิเตอร์ทั้งสองเป็นเท็จ กล่าวอีกนัยหนึ่งเมื่อเราระบุชุดอักขระที่ใช้สำหรับการเชื่อมต่อเมื่อเชื่อมต่อ MySQL ทุกอย่างเป็นเรื่องปกติ แต่ฉันยังไม่รู้เกี่ยวกับกลไกมากนักดังนั้นฉันจึงตรวจสอบต่อไป
ปรากฎว่ามีกระบวนการแปลงชุดอักขระเมื่อการเชื่อมต่อ MySQL ดำเนินการค้นหาและการดำเนินการอื่น ๆ :
1. เมื่อเซิร์ฟเวอร์ MySQL ได้รับคำขอแปลงข้อมูลคำขอจาก character_set_client เป็น character_set_connection;
2. ก่อนที่จะดำเนินการภายในให้แปลงข้อมูลที่ร้องขอจากตัวอักษร _set_connection เป็นชุดอักขระการทำงานภายใน วิธีการกำหนดมีดังนี้:
•ใช้ค่าการตั้งค่าการตั้งค่าอักขระสำหรับแต่ละฟิลด์ข้อมูล
•หากไม่มีค่าข้างต้นใช้ค่าการตั้งค่าการตั้งค่าอักขระเริ่มต้น (ส่วนขยาย MySQL, มาตรฐานที่ไม่ใช่ SQL) ของตารางข้อมูลที่เกี่ยวข้อง
•หากไม่มีค่าข้างต้นอยู่จะใช้ค่าการตั้งค่าการตั้งค่าอักขระเริ่มต้นของฐานข้อมูลที่เกี่ยวข้อง
•หากไม่มีค่าข้างต้นให้ใช้ character_set_server เพื่อตั้งค่า
3. แปลงผลการดำเนินการจากการตั้งค่าอักขระภายในเป็นตัวละคร character_set_results
ชุดตัวละครเหล่านี้แสดงถึงอะไร?
ตัวละคร _set_server: ชุดอักขระการทำงานภายในเริ่มต้น
character_set_client: ชุดอักขระที่ใช้โดยแหล่งข้อมูลไคลเอนต์
ตัวละคร _set_connection: ชุดเลเยอร์การเชื่อมต่อชุดอักขระ
ตัวละคร _set_results: ชุดผลลัพธ์แบบสอบถาม
ตัวอักษร _set_database: ชุดอักขระเริ่มต้นของฐานข้อมูลที่เลือกในปัจจุบัน
ตัวละคร _set_system: เมตาดาต้าระบบ (ชื่อฟิลด์ ฯลฯ ) ชุดอักขระ
ฉันยังพบคำถามทั่วไป แม้ว่าพวกเขาจะแตกต่างจากของฉัน แต่ก็มีค่าอ้างอิงที่ดี
•ก่อนที่จะแทรกข้อมูลที่เข้ารหัส UTF8 ลงในตารางข้อมูลที่มีชุดอักขระเริ่มต้นคือ UTF8 ชุดอักขระการเชื่อมต่อคือ UTF8
เมื่อแทรกตามการตั้งค่าเริ่มต้นของเซิร์ฟเวอร์ mysql, character_set_client, character_set_connection และ character_set_results เป็น latin1;
ข้อมูลของการดำเนินการแทรกจะผ่านกระบวนการแปลงตัวอักษรของ LATIN1 => LATIN1 => UTF8 ในระหว่างกระบวนการนี้อักขระจีนที่แทรกแต่ละตัวจะถูกบันทึกจาก 3 ไบต์ดั้งเดิมถึง 6 ไบต์;
ผลลัพธ์ในระหว่างการสืบค้นจะผ่านกระบวนการแปลงตัวอักษรของ UTF8 => UTF8 และที่บันทึกไว้ 6 ไบต์จะถูกส่งคืนเหมือนเดิมส่งผลให้รหัสที่อ่านไม่ออก ...
•ตั้งค่าอักขระการเชื่อมต่อที่ตั้งค่าเป็น UTF8 ก่อนที่จะแทรกข้อมูลที่เข้ารหัส UTF8 ลงในตารางข้อมูลด้วยชุดอักขระเริ่มต้นคือละติน 1
เมื่อแทรก character_set_client, character_set_connection และ character_set_results คือ utf8 ทั้งหมด;
ข้อมูลการแทรกจะถูกแปลงผ่านชุดอักขระของ utf8 => utf8 => latin1 หากข้อมูลต้นฉบับมีอักขระ Unicode ที่ไม่ใช่ช่วง /U0000 ~ /U00FF มันจะถูกแปลงเป็น "?" (0x3f) สัญลักษณ์เพราะไม่สามารถแสดงในชุดอักขระของละติน 1 ในอนาคตไม่ว่าชุดอักขระการเชื่อมต่อจะถูกตั้งค่าอะไรเนื้อหาไม่สามารถกู้คืนได้
(ส่วนนี้ถูกตัดตอนมาจากบล็อกของ Brother Bird และลิงก์จะแนบมาในภายหลัง)
ตารางในฐานข้อมูลของฉันถูกตั้งค่าทั้งหมดด้วยการเข้ารหัส UTF8 แต่เมื่อฉันเชื่อมต่อครั้งแรกฉันไม่ได้ตั้งค่าอักขระการเชื่อมต่อดังนั้นค่าเริ่มต้นคือละติน 1 หลังจากการแปลงจาก UTF8 => LATIN1 จะสร้างรหัสที่อ่านไม่ออก การเข้ารหัส GBK ที่ฉันใช้เป็นครั้งที่สองและฉันไม่ได้ใช้การเข้ารหัส UTF8 ทำไมมันโอเค? จริงๆแล้วมันเป็นสิ่งเดียวกัน ภาษาจีนไม่ได้อยู่ในการเข้ารหัส Latin1 แต่ใน GBK และ UTF8 ดังนั้นจะไม่มีปัญหา
ด้านบนเป็นวิธีแก้ปัญหาที่อ่านไม่ออกของการเชื่อมต่อ JDBC กับ MySQL หากคุณยังมีคำถามใด ๆ คุณสามารถพูดคุยในพื้นที่แสดงความคิดเห็นด้านล่าง