JPA สนับสนุนสองวิธีในการแสดงการสืบค้นเพื่อดึงข้อมูลและข้อมูลถาวรอื่น ๆ จากฐานข้อมูล: คำสั่งค้นหา (ภาษาคิวรีการคงอยู่ของ Java, JPQL) และเกณฑ์ API (Criteria API) JPQL เป็นคำสั่งแบบสอบถามที่ไม่ขึ้นกับฐานข้อมูลที่ใช้ในการใช้งานแบบจำลองเอนทิตีตรรกะมากกว่าแบบจำลองข้อมูลทางกายภาพ API แบบมีเงื่อนไขคือการสร้างเงื่อนไขการสืบค้นตามโมเดลเอนทิตี
1. การเริ่มต้นใช้งานคำสั่งแบบสอบถามแบบถาวรของ Java
การคัดลอกรหัสมีดังนี้: รายการ <person> person = entityManager.createquery ("เลือก p จากบุคคล p"). getResultList ();
1. คำสั่งค้นหานี้คล้ายกับ SQL แต่ความแตกต่างระหว่างมันกับ SQL ที่แท้จริงคือแทนที่จะทำการสืบค้นการเลือกจากตารางมันจะระบุเอนทิตีจากโมเดลโดเมนแอปพลิเคชัน
2. ประโยคที่เลือกแบบสอบถามแสดงรายการนามแฝงของเอนทิตีแบบสอบถามเท่านั้น หากคุณสอบถามคอลัมน์ที่แน่นอนเท่านั้นคุณสามารถใช้ตัวดำเนินการ DOT (.) เพื่อนำทางคุณสมบัติเอนทิตี ดังที่แสดงด้านล่าง:
การคัดลอกรหัสมีดังนี้: รายการ <string> persons = entityManager.createquery ("เลือก p.firstname จากบุคคล p"). getResultlist ();
1.1. เกณฑ์ตัวกรอง
เช่นเดียวกับ SQL, JPQL ยังรองรับตำแหน่งที่ใช้ซึ่งใช้ในการกรองเกณฑ์การค้นหา รวมถึงตัวดำเนินการส่วนใหญ่เช่น: in, ระหว่าง, like, function expression substring, ความยาว ฯลฯ
การคัดลอกรหัสมีดังนี้: รายการ <person> person = entityManager.createquery ("เลือก p จากบุคคล P ที่ p.age> 23"). getResultList ();
1.2. ผลการฉายภาพ
หากจำนวนการสอบถามข้อมูลมีขนาดค่อนข้างใหญ่คุณสามารถใช้การฉายภาพเพื่อสืบค้นคอลัมน์ที่มีประโยชน์เท่านั้น
การคัดลอกรหัสมีดังนี้:/รายการโครงการ <jobch> บุคคล = entityManager.createquery ("เลือก p.firstname, p.age จากบุคคล p"). getResultlist ();
1.3. แบบสอบถามการรวม
ไวยากรณ์การค้นหารวมของ JPQL นั้นคล้ายกับ SQL ตัวอย่างเช่นนับ
การคัดลอกรหัสมีดังนี้: รายการ <จำนวนเต็ม> count = entityManager.createquery ("เลือกนับ (p) จากบุคคล p"). getResultList ();
1.4. พารามิเตอร์การสืบค้น
JPQL รองรับไวยากรณ์การเชื่อมโยงพารามิเตอร์สองประเภท
1. การแสดงพารามิเตอร์ตำแหน่ง
ที่ระบุพารามิเตอร์ในสตริงการสืบค้นซึ่งเป็นหมายเลขที่ตามพารามิเตอร์ทันทีหลังจากเครื่องหมายคำถาม (?) เมื่อดำเนินการสืบค้นนักพัฒนาจะระบุพารามิเตอร์ที่ควรเปลี่ยน
Query Query = EntityManager.Createquery ("เลือก P จากบุคคล P โดยที่ p.age =? 1 และ p.firstname =? 2"); query.setParameter (1,21); query.setParameter (2, "Jack"); 2. ชื่อพารามิเตอร์ชื่อ
โดยการติดตามลำไส้ใหญ่ (:) และระบุไว้ในสตริงการสืบค้นผู้พัฒนาระบุชื่อพารามิเตอร์ที่ควรเปลี่ยนเมื่อดำเนินการแบบสอบถาม
Query Query = EntityManager.Createquery ("เลือก P จากบุคคล P โดยที่ p.age =: อายุและ p.firstname =: name"); query.setParameter ("อายุ", 21); query.setParameter ("ชื่อ", "แจ็ค");2. กำหนดคิวรี
JPA จัดเตรียมการสืบค้นและการพิมพ์ (แนะนำโดย JPA 2.0) อินเทอร์เฟซเพื่อกำหนดค่าและดำเนินการค้นหา แบบสอบถามส่งคืนประเภทวัตถุในขณะที่ TypEdQuery ส่งคืนประเภทคลาสที่ระบุ
// ไม่ระบุประเภท, return ประเภทวัตถุแบบสอบถาม q = entityManager.createquery ("เลือก p จากบุคคล p"); // ระบุประเภทการส่งคืนเป็นประเภทบุคคล typedQuery <person> q1 = entityManager.createquery ("เลือก p จากบุคคล P", person.class);2.1. คำจำกัดความแบบสอบถามแบบไดนามิก
เครื่องยนต์คิวรี JPA สามารถแยกวิเคราะห์สตริง JPQL ลงในต้นไวยากรณ์ได้รับข้อมูลเมตาของแผนที่วัตถุที่สัมพันธ์กันในนิพจน์แล้วสร้าง SQL ที่เทียบเท่า ดังนั้นจึงมีสองวิธีในการดำเนินการค้นหาแบบไดนามิก
1. วิธีการสตริง
เคล็ดลับ: จะทำให้เกิดปัญหาการฉีด SQL
/** * เงื่อนไขการสืบค้นสตริงการสร้างแบบไดนามิก * * @param ชื่อ * @param Age * @return */String String สาธารณะ querypersonjpql (ชื่อสตริงอายุ int) {string queryql = "เลือก p จากบุคคล P ที่ p.firstname = '" + ชื่อ + "และ p.age =" + อายุ; return queryQl;} // การค้นหาการค้นหาการค้นหา = entityManager.Createquery (querypersonjpql ("แจ็ค", 21)); 2. การสร้างพารามิเตอร์แบบไดนามิกของเงื่อนไขการสืบค้น (แนะนำ)
/** * เงื่อนไขการสืบค้นการก่อสร้างแบบไดนามิกแบบไดนามิก * * @return */String String สาธารณะ querypersonjpqlbyparams () {string queryql = "เลือก p จากบุคคล P โดยที่ p.firstname =: ชื่อและ p.age =: อายุ"; return queryql;} query query = entityManager.createquery (querypersonjpqlbyparams ()); query.setParameter ("ชื่อ", "jack"); query.setParameter ("อายุ", 21);2.2. คำนิยามการสืบค้นชื่อ
ชื่อ Query เป็นเครื่องมือที่ทรงพลัง ใช้คำอธิบายประกอบ @NamedQuery เพื่อกำหนดแบบสอบถามที่มีชื่อซึ่งสามารถวางไว้ด้านบนของคำจำกัดความคลาสของเอนทิตีใด ๆ คำอธิบายประกอบนี้กำหนดชื่อของคำถามและข้อความ
เคล็ดลับ: การสืบค้นชื่อถูกวางไว้ในคลาสเอนทิตีที่สอดคล้องกับผลลัพธ์การสืบค้น
@entity@namedQuery (name = "findByage", query = "เลือก p จากบุคคล p โดยที่ p.age =: อายุ") บุคคลชั้นเรียนสาธารณะ {// ละเว้น} ชื่อที่กำหนดไว้ในเคล็ดลับ: NamedQuery จะต้องไม่ซ้ำกันในหน่วยการคงอยู่ทั้งหมดมิฉะนั้นจะมีข้อผิดพลาดในการดำเนินการ
เช่น:
การคัดลอกรหัสมีดังนี้:
ข้อยกเว้นในเธรด "Main" org.hibernate.duplicateMappingException: การทำแผนที่การสอบถามซ้ำ findByage ที่ org.hibernate.boot.internal.inflightmetadatacollectorimpl.checkqueryname
เรียก
การคัดลอกรหัสมีดังนี้:
รายการ <person> people = entityManager.createnamedQuery ("findByage", person.class) .setParameter ("อายุ", 21) .getResultList ();
หากชั้นเรียนกำหนดสองรายการขึ้นไปจะต้องวางไว้ใน @Namedqueries ()
2.3. พารามิเตอร์การผูกมัด
ผ่านตัวอย่างก่อนหน้านี้เราจะเห็นว่ามีสองวิธีในการผูกพารามิเตอร์: 1. การผูกพารามิเตอร์ตำแหน่ง 2. การผูกพารามิเตอร์ชื่อ ทั้งหมดจะถูกผูกไว้ด้วยวิธีการ setparameter ของอินเตอร์เฟสแบบสอบถาม
1. การกำหนดพารามิเตอร์ตำแหน่ง
TypedQuery <x> setParameter (ตำแหน่ง int, ค่าวัตถุ);
2. การกำหนดพารามิเตอร์ชื่อ
TypedQuery <x> setParameter (ชื่อสตริงค่าวัตถุ);
ครั้งแรกคือการผูกพารามิเตอร์ตำแหน่ง หากตำแหน่งเปลี่ยนแปลงรหัสที่ถูกผูกไว้จะต้องมีการเปลี่ยนแปลง แนะนำประเภทที่สอง
2.4. ดำเนินการค้นหา
อินเทอร์เฟซแบบสอบถามและอินเทอร์เฟซ TypEdQuery มีวิธีการค้นหาสามวิธี
1. executeUpdate
ใช้เพื่อทำการอัปเดตหรือลบแบบแบทช์
2. Getsingleresult
รับชุดผลลัพธ์เดียว หากไม่ได้รับข้อมูลจะมีการโยน noresultexception หากได้รับข้อมูลหลายชิ้นจะมีการโยน nonuniqueresultexception
3. GetResultlist
รับชุดผลลัพธ์ที่สอดคล้องกันและระบุลำดับของชุด รายการจะต้องใช้เป็นประเภทค่าส่งคืน หากไม่ได้รับข้อมูลชุดว่างจะถูกส่งคืนและไม่มีข้อยกเว้นถูกโยนทิ้งไป
2.5. การปนเปื้อน
การสืบค้น pagination สามารถทำได้ผ่านวิธีการ setFirstResult () และ setMaxResults ()
หมายเลขหน้าเคียวรีคือ 0 และข้อมูล 2 ชิ้นจะปรากฏขึ้นในแต่ละหน้า
การคัดลอกรหัสมีดังนี้:
รายการ <person> people = entityManager.createquery ("เลือก p จากบุคคล p", person.class) .setFirstResult (0) .setMaxResults (2) .getResultList ();
เคล็ดลับ: ไม่สามารถใช้สำหรับการสืบค้นที่เชื่อมต่อโดยความสัมพันธ์การรวบรวมเนื่องจากการสืบค้นเหล่านี้อาจส่งคืนค่าที่ซ้ำกัน
2.6. การสืบค้นหมดเวลา
หากแอปพลิเคชันจำเป็นต้องกำหนดขีด จำกัด เกี่ยวกับเวลาตอบสนองแบบสอบถามคุณสามารถตั้งค่าคุณสมบัติ javax.persistence.query.timeout ในแบบสอบถาม (แนะนำโดย JPA 2.0) หรือใช้เป็นส่วนหนึ่งของคุณสมบัติการคงอยู่ คุณสมบัตินี้กำหนดจำนวน == มิลลิวินาทีที่ได้รับอนุญาตให้ทำงานก่อนที่แบบสอบถามจะถูกยกเลิก หากการหมดเวลาแบบสอบถามจะมีการโยน QueryTimeException
TypedQuery <person> query = entityManager.createquery ("เลือก p จากบุคคล p", person.class); // หน่วยเป็นมิลลิวินาที javax.persistence.query.timeoutquery.sethint ("javax.persistence.pers.timeout", 5000);2.7. การอัปเดตและลบแบทช์
เอนทิตีการอัปเดตแบทช์เสร็จสมบูรณ์ผ่านคำสั่ง UPDATE การลบชุดของเอนทิตีจะทำผ่านการลบงบ ทั้งสองระบุคุณสมบัติของเอนทิตีและชั้นเรียน
EntityManager.getTransaction (). เริ่มต้น (); Query Query = EntityManager.Createquery ("Update Person P Set P.FirstName =: ชื่อที่ P.ID =: ID"); query.setParameter ("ชื่อ", "xiaobai"); query.setParameter ("id", 2); EntityManager.Createquery ("ลบบุคคล P โดยที่ p.id =: id"); query1.setParameter ("id", 9); query1.executeUpdate (); entityManager.getTransaction (). commit ();3. คำแนะนำสำหรับการใช้แบบสอบถาม JPQL
ในระบบแอปพลิเคชันจำนวนการสืบค้นมักจะใช้มากกว่าการเพิ่มการแก้ไขและการลบ ดังนั้นจึงเป็นเรื่องสำคัญอย่างยิ่งที่จะต้องใช้การสืบค้นและแสดงอย่างสมเหตุสมผล
1. ขอแนะนำให้ใช้ชื่อ Query (NamedQuery)
โปรแกรมที่ให้การคงอยู่มักจะใช้วิธีการที่รวบรวมไว้ล่วงหน้าเพื่อใช้การสืบค้นชื่อเป็นส่วนหนึ่งของขั้นตอนการเริ่มต้นโปรแกรม สิ่งนี้จะหลีกเลี่ยงระบบค่าใช้จ่ายของการแยกวิเคราะห์ JPQL อย่างต่อเนื่องและสร้าง SQL
2. ใช้การฉายเพื่อดึงคอลัมน์จำนวนน้อยก่อน
คิวรี JPA มักจะส่งคืนคอลัมน์ทั้งหมดของเอนทิตีทั้งหมด แต่สำหรับข้อมูลจำนวนมากไม่จำเป็นต้องใช้คอลัมน์เอนทิตีทั้งหมด จากนั้นเราสามารถใช้การฉายเพื่อจัดการกับมัน
รายการ <list <object [] >> person = entityManager.createquery ("เลือกรายการใหม่ (ชื่อแรก, อายุ) จากบุคคล p"). getResultlist (); สำหรับ (วัตถุ o: บุคคล) {system.out.println (o);} // ผลการส่งออกข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น