Posjsonhelper Library เป็นโครงการโอเพนซอร์ซที่เพิ่มการสนับสนุนของการสืบค้นไฮเบอร์เนตสำหรับฟังก์ชั่น PostgreSQL JSON ห้องสมุดยังมีการสนับสนุนฟังก์ชั่นการค้นหาข้อความ postgreSQL หากต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับวิธีการใช้ส่วนประกอบการค้นหาข้อความตรวจสอบคำแนะนำสำหรับโมดูลข้อความ ห้องสมุดเขียนด้วยภาษาการเขียนโปรแกรม Java โครงการสำหรับช่วงเวลานี้รองรับ Hibernate ด้วยเวอร์ชัน 5 และ 6 รุ่น Java ที่ต้องการอย่างน้อยเวอร์ชัน 8 สำหรับการสนับสนุน Hibernate 5 และเวอร์ชัน 11 สำหรับ Hibernate 6
โครงการมีอยู่ในที่เก็บ Maven Central คุณสามารถใช้มันได้เพียงแค่เพิ่มเป็นการพึ่งพาในไฟล์ Descriptor Project (pom.xml)
สำหรับไฮเบอร์เนต 5:
< dependency >
< groupId >com.github.starnowski.posjsonhelper</ groupId >
< artifactId >hibernate5</ artifactId >
< version >0.4.2</ version >
</ dependency >สำหรับไฮเบอร์เนต 6:
< dependency >
< groupId >com.github.starnowski.posjsonhelper</ groupId >
< artifactId >hibernate6</ artifactId >
< version >0.4.2</ version >
</ dependency >Posjsonhelper Library ไม่ได้มีการพึ่งพาชั่วคราวไปยังห้องสมุดไฮเบอร์เนต ดังนั้นโปรดทราบว่าต้องมีการพึ่งพา Hibernate ที่แยกจากกันในโครงการของคุณเช่นด้านล่าง:
< dependency >
< groupId >org.hibernate</ groupId >
< artifactId >hibernate-core</ artifactId >
< version >????</ version >
</ dependency >โปรดตรวจสอบเมทริกซ์เวอร์ชันความเข้ากันได้ของไฮเบอร์เนตเพื่อตรวจสอบเวอร์ชันที่ถูกต้อง
การใช้งานเริ่มต้นสำหรับฟังก์ชันบางอย่างที่เกี่ยวข้องกับการดำเนินงาน JSON ต้องการ org.json: ไลบรารี JSON อย่างไรก็ตามมีวิธีการใช้อินเทอร์เฟซเฉพาะและห้องสมุดด้านล่างอาจไม่จำเป็นต้องเพิ่ม
< dependency >
< groupId >org.json</ groupId >
< artifactId >json</ artifactId >
< version >20240303</ version >
</ dependency >หากมีคนต้องการสร้างโครงการในพื้นที่จากแหล่งที่มาโปรดดูไฟล์ MD ที่มีส่วนร่วมเพื่อตรวจสอบวิธีการตั้งค่าโครงการในเครื่อง
สำคัญ! ส่วนนี้ใช้ได้เฉพาะสำหรับไฮเบอร์เนต 5. เพื่อให้สามารถใช้ไลบรารี posjsonhelper ในโครงการจะต้องมีการระบุภาษาไฮเบอร์เนตที่ถูกต้อง ห้องสมุดใช้ wrappers น้อยที่ขยายอยู่แล้วมีภาษาไฮเบอร์เนตที่มีอยู่แล้วสำหรับ PostgreSQL:
ภาษาถิ่นจะต้องตั้งค่าในไฟล์กำหนดค่าไฮเบอร์เนตตัวอย่างเช่น:
<? xml version = " 1.0 " encoding = " UTF-8 " ?>
< hibernate-configuration xmlns = " http://www.hibernate.org/xsd/orm/cfg " >
< session-factory >
< property name = " hibernate.dialect " >com.github.starnowski.posjsonhelper.hibernate5.dialects.PostgreSQL95DialectWrapper</ property >
...หรือตัวอย่างในไฟล์คุณสมบัติการกำหนดค่าสปริงเฟรมเวิร์ก:
...
spring.jpa.properties.hibernate.dialect =com.github.starnowski.posjsonhelper.hibernate5.dialects.PostgreSQL95DialectWrapper
...ในกรณีที่คุณมีประเภทที่ขยายประเภทภาษาไฮเบอร์เนตแล้วและจำเป็นสำหรับโครงการของคุณ คุณเพิ่มการปรับเปลี่ยนประเภทของคุณเพื่อที่จะใช้ส่วนประกอบ PostgreSqldialectenricher
import com . github . starnowski . posjsonhelper . hibernate5 . PostgreSQLDialectEnricher ;
import org . hibernate . dialect . PostgreSQL95Dialect ;
public class PostgreSQLDialectWithDifferentSchema extends PostgreSQL95Dialect {
public PostgreSQLDialectWithDifferentSchema () {
PostgreSQLDialectEnricher enricher = new PostgreSQLDialectEnricher ();
enricher . enrich ( this );
}
}สำคัญ! ส่วนนี้ใช้ได้เฉพาะสำหรับไฮเบอร์เนต 6. ในการใช้ไลบรารี posjsonhelper ในโครงการที่ใช้ไฮเบอร์เนต 6 จะต้องมี org.hibernate.boot.model.functioncontributor ห้องสมุดมีการใช้งานอินเทอร์เฟซนี้นั่นคือ com.github.starnowski.posjsonhelper.hibernate6.posjsonhelperfunctioncontributor
ในการใช้การใช้งานนี้จำเป็นต้องสร้างไฟล์ด้วยชื่อ "org.hibernate.boot.model.functionContributor" ภายใต้ไดเรกทอรี "ทรัพยากร/meta-inf/services"
ทางเลือกอื่นคือการใช้ com.github.starnowski.posjsonhelper.hibernate6.sqmfunctionRegistryRicher ในระหว่างการเริ่มต้นแอปพลิเคชัน เช่นเดียวกับในตัวอย่างด้านล่างด้วยการใช้งานกรอบฤดูใบไม้ผลิ
import com . github . starnowski . posjsonhelper . hibernate6 . SqmFunctionRegistryEnricher ;
import jakarta . persistence . EntityManager ;
import org . hibernate . query . sqm . NodeBuilder ;
import org . springframework . beans . factory . annotation . Autowired ;
import org . springframework . context . ApplicationListener ;
import org . springframework . context . annotation . Configuration ;
import org . springframework . context . event . ContextRefreshedEvent ;
@ Configuration
public class FunctionDescriptorConfiguration implements
ApplicationListener < ContextRefreshedEvent > {
@ Autowired
private EntityManager entityManager ;
@ Override
public void onApplicationEvent ( ContextRefreshedEvent event ) {
NodeBuilder nodeBuilder = ( NodeBuilder ) entityManager . getCriteriaBuilder ();
SqmFunctionRegistryEnricher sqmFunctionRegistryEnricher = new SqmFunctionRegistryEnricher ();
sqmFunctionRegistryEnricher . enrich ( nodeBuilder . getQueryEngine (). getSqmFunctionRegistry ());
}
}ในการใช้ไลบรารี Posjsonhelper จำเป็นต้องสร้างฟังก์ชั่น SQL สองสามอย่างที่เรียกใช้งานตัวดำเนินการ JSON ผู้ให้บริการ JSON บางรายไม่สามารถดำเนินการโดยไฮเบอร์เนตได้เพราะต้องหลบหนี สำหรับการกำหนดค่าเริ่มต้นไลบรารีต้องใช้ฟังก์ชันด้านล่างที่จะสร้าง
CREATE OR REPLACE FUNCTION jsonb_all_array_strings_exist (jsonb, text []) RETURNS boolean AS $$
SELECT $ 1 ?& $ 2 ;
$$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION jsonb_any_array_strings_exist (jsonb, text []) RETURNS boolean AS $$
SELECT $ 1 ?| $ 2 ;
$$ LANGUAGE SQL;คำสั่ง DDL ที่สร้างขึ้นสามารถดำเนินการได้ในระหว่างการทดสอบการรวมหรือใช้โดยเครื่องมือที่ใช้การเปลี่ยนแปลงฐานข้อมูลเช่น Liquibase หรือ Flyway สำคัญ! หากมีข้อกำหนดในการใช้ฟังก์ชั่นที่คล้ายกัน แต่มีชื่อที่แตกต่างกันสิ่งนี้จะต้องระบุไว้ในคุณสมบัติแอปพลิเคชัน มันเป็นสิ่งจำเป็นเนื่องจากประเภทขยายประเภทภาษาไฮเบอร์เนตที่กล่าวถึงใน ["วิธีการแนบภาษาถิ่น PostgreSQL"] (#วิธีการใช้งานภาษา-โพสต์-โพสเทิล) อาจไม่สามารถเข้าถึงบริบทของแอปพลิเคชัน (IOC) อย่างไรก็ตามในกรณีที่คุณสมบัติดังกล่าวควรผ่านไปในทางที่แตกต่างกันประเภท PostgreSqldialectenricher มีวิธีการผ่านวัตถุบริบท (โปรดตรวจสอบบริบทหลักและบริบทไฮเบอร์เนต)
คลาสบริบทถือชื่อของฟังก์ชั่นที่ใช้โดยไลบรารี คลาส Dialect ใช้ส่วนประกอบ CoreConTextProperTiessUpplier ที่สร้างวัตถุบริบทตามคุณสมบัติของระบบ
มันสามารถเพิ่ม DDL โดยใช้โปรแกรมโดยใช้ประเภท DatabaseOperationExecutorFacade ด้านล่างนี้มีตัวอย่างเกี่ยวกับวิธีการใช้การเปลี่ยนแปลง DDL ในแอปพลิเคชันกับบริบทสปริงเฟรมเวิร์ก
import com . github . starnowski . posjsonhelper . core . Context ;
import com . github . starnowski . posjsonhelper . core . DatabaseOperationExecutorFacade ;
import com . github . starnowski . posjsonhelper . core . DatabaseOperationType ;
import org . springframework . beans . factory . annotation . Autowired ;
import org . springframework . context . ApplicationListener ;
import org . springframework . context . annotation . Configuration ;
import org . springframework . context . event . ContextRefreshedEvent ;
import javax . sql . DataSource ;
@ Configuration
public class SQLFunctionsConfiguration implements
ApplicationListener < ContextRefreshedEvent > {
@ Autowired
private Context context ;
@ Autowired
private DataSource dataSource ;
@ Override
public void onApplicationEvent ( ContextRefreshedEvent contextRefreshedEvent ) {
DatabaseOperationExecutorFacade facade = new DatabaseOperationExecutorFacade ();
try {
facade . execute ( dataSource , context , DatabaseOperationType . LOG_ALL );
facade . execute ( dataSource , context , DatabaseOperationType . CREATE );
facade . execute ( dataSource , context , DatabaseOperationType . VALIDATE );
} catch ( Exception e ) {
throw new RuntimeException ( "Error during initialization of sql functions for jsonb type operations" , e );
}
}
}มีการดำเนินการบางอย่างที่สามารถดำเนินการได้โดยวัตถุ DatabaseOperationExecutorFacade
| ชื่ออสังหาริมทรัพย์ | คำอธิบาย |
|---|---|
| สร้าง | ใช้การเปลี่ยนแปลงฐานข้อมูล DDL |
| ตรวจสอบความถูกต้อง | ตรวจสอบว่าการเปลี่ยนแปลง DDL ถูกนำไปใช้กับฐานข้อมูล |
| หยด | ลดการเปลี่ยนแปลง DDL ในฐานข้อมูล |
| log_all | แสดงสคริปต์ DDL สำหรับการสร้างตรวจสอบและลดการดำเนินการ |
สำหรับคำอธิบายที่ง่ายขึ้นสมมติว่าเรามีตารางฐานข้อมูลที่มีหนึ่งคอลัมน์ที่เก็บประเภท JSONB
create table item (
id int8 not null ,
jsonb_content jsonb,
primary key (id)
)สำหรับตารางนี้เราสามารถแทรกแถวกับ JSON ใด ๆ เช่นในตัวอย่างด้านล่าง:
INSERT INTO item (id, jsonb_content) VALUES ( 1 , ' {"top_element_with_set_of_values":["TAG1","TAG2","TAG11","TAG12","TAG21","TAG22"]} ' );
INSERT INTO item (id, jsonb_content) VALUES ( 2 , ' {"top_element_with_set_of_values":["TAG3"]} ' );
-- item without any properties, just an empty json
INSERT INTO item (id, jsonb_content) VALUES ( 6 , ' {} ' );
-- int values
INSERT INTO item (id, jsonb_content) VALUES ( 7 , ' {"integer_value": 132} ' );
-- double values
INSERT INTO item (id, jsonb_content) VALUES ( 10 , ' {"double_value": 353.01} ' );
INSERT INTO item (id, jsonb_content) VALUES ( 11 , ' {"double_value": -1137.98} ' );
-- enum values
INSERT INTO item (id, jsonb_content) VALUES ( 13 , ' {"enum_value": "SUPER"} ' );
-- string values
INSERT INTO item (id, jsonb_content) VALUES ( 18 , ' {"string_value": "the end of records"} ' );ส่วนประกอบส่วนใหญ่ใช้วัตถุบริบทไฮเบอร์เนต ส่วนใหญ่ถือชื่อของชื่อฟังก์ชั่นไฮเบอร์เนตที่ใช้ในโครงการ คลาสภาษาถิ่นและประเภท functionContributor ใช้ส่วนประกอบ hibernateContextPropertiessUpplier ที่สร้างวัตถุ hibernateContext ตามคุณสมบัติของระบบ หากไม่จำเป็นต้องเปลี่ยนชื่อฟังก์ชั่น HQL เริ่มต้นสำหรับผู้ให้บริการ PSOJSONHELPER คุณจะต้องใช้ hiberNateContext ที่สร้างขึ้นโดยส่วนประกอบของ Builder เช่นด้านล่าง:
HibernateContext hibernateContext = HibernateContext . builder (). build ();"JSONB_EXTRACT_PATH" เป็นฟังก์ชัน postgreSQL ที่ส่งคืนค่า JSONB ที่ชี้ไปที่องค์ประกอบพา ธ ที่ส่งผ่านเป็น "ข้อความ []" (เทียบเท่ากับตัวดำเนินการ #>) มันมีประโยชน์เพราะฟังก์ชั่นจำนวนมากใช้ประเภท "JSONB" สำหรับการดำเนินการ โปรดตรวจสอบเอกสาร PostgreSQL สำหรับข้อมูลเพิ่มเติม Hibernate 5 ตัวอย่าง : ด้านล่างมีตัวอย่างของวิธีการที่ส่งคืนรายการรายการรายการที่คุณสมบัติเนื้อหา JSON "top_element_with_set_of_values" มีชุดค่าที่แน่นอน ตัวอย่างใช้ jsonballarrayStringSexistPredicate
@ Autowired
private HibernateContext hibernateContext ;
@ Autowired
private EntityManager entityManager ;
public List < Item > findAllByAllMatchingTags ( Set < String > tags ) {
CriteriaBuilder cb = entityManager . getCriteriaBuilder ();
CriteriaQuery < Item > query = cb . createQuery ( Item . class );
Root < Item > root = query . from ( Item . class );
query . select ( root );
query . where ( new JsonbAllArrayStringsExistPredicate ( hibernateContext , ( CriteriaBuilderImpl ) cb , new JsonBExtractPath (( CriteriaBuilderImpl ) cb , singletonList ( "top_element_with_set_of_values" ), root . get ( "jsonbContent" )), tags . toArray ( new String [ 0 ])));
return entityManager . createQuery ( query ). getResultList ();
}สำหรับวิธีการข้างต้น Hibernate จะดำเนินการค้นหา HQL:
select
generatedAlias0
from
Item as generatedAlias0
where
jsonb_all_array_strings_exist( jsonb_extract_path( generatedAlias0 . jsonbContent , :param0 ) , json_function_json_array(:param1)) = TRUESQL ดั้งเดิมจะมีแบบฟอร์มด้านล่าง:
select
item0_ . id as id1_0_,
item0_ . jsonb_content as jsonb_co2_0_
from
item item0_
where
jsonb_all_array_strings_exist(jsonb_extract_path( item0_ . jsonb_content ,?), array[?]) = trueสำหรับรายละเอียดเพิ่มเติมโปรดตรวจสอบ DAO ที่ใช้ในการทดสอบ
ไฮเบอร์เนต 6 ตัวอย่าง :
ด้านล่างมีตัวอย่างเดียวกันกับข้างต้น แต่สำหรับไฮเบอร์เนต 6
import org . hibernate . query . sqm . NodeBuilder ;
....
@ Autowired
private HibernateContext hibernateContext ;
@ Autowired
private EntityManager entityManager ;
public List < Item > findAllByAllMatchingTags ( Set < String > tags ) {
CriteriaBuilder cb = entityManager . getCriteriaBuilder ();
CriteriaQuery < Item > query = cb . createQuery ( Item . class );
Root < Item > root = query . from ( Item . class );
query . select ( root );
query . where ( new JsonbAllArrayStringsExistPredicate ( hibernateContext , ( NodeBuilder ) cb , new JsonBExtractPath ( root . get ( "jsonbContent" ), ( NodeBuilder ) cb , singletonList ( "top_element_with_set_of_values" )), tags . toArray ( new String [ 0 ])));
return entityManager . createQuery ( query ). getResultList ();
}สำหรับรายละเอียดเพิ่มเติมโปรดตรวจสอบ DAO ที่ใช้ในการทดสอบ
"jsonb_extract_path_text" เป็นฟังก์ชัน postgreSql ที่ส่งคืนค่า JSON เป็นข้อความที่ชี้ไปที่องค์ประกอบพา ธ ที่ส่งผ่านเป็น "ข้อความ []" (เทียบเท่ากับตัวดำเนินการ #>>) โปรดตรวจสอบเอกสาร PostgreSQL สำหรับข้อมูลเพิ่มเติม ด้านล่างนี้มีตัวอย่างสำหรับ Hibernate 5 ของวิธีการที่ค้นหารายการที่มีค่าสตริงเฉพาะที่จับคู่โดยตัวดำเนินการ "Like"
public List < Item > findAllByStringValueAndLikeOperator ( String expression ) {
CriteriaBuilder cb = entityManager . getCriteriaBuilder ();
CriteriaQuery < Item > query = cb . createQuery ( Item . class );
Root < Item > root = query . from ( Item . class );
query . select ( root );
query . where ( cb . like ( new JsonBExtractPathText (( CriteriaBuilderImpl ) cb , singletonList ( "string_value" ), root . get ( "jsonbContent" )), expression ));
return entityManager . createQuery ( query ). getResultList ();
}สำหรับวิธีการข้างต้น Hibernate จะดำเนินการค้นหา HQL:
select
generatedAlias0
from
Item as generatedAlias0
where
jsonb_extract_path_text( generatedAlias0 . jsonbContent , :param0 ) like :param1SQL ดั้งเดิมจะมีแบบฟอร์มด้านล่าง:
select
item0_ . id as id1_0_,
item0_ . jsonb_content as jsonb_co2_0_
from
item item0_
where
jsonb_extract_path_text( item0_ . jsonb_content ,?) like ?สำหรับรายละเอียดเพิ่มเติมและตัวอย่างด้วยผู้ให้บริการในหรือวิธีใช้ค่าตัวเลขโปรดตรวจสอบ DAO ที่ใช้ในการทดสอบ
ไฮเบอร์เนต 6 ตัวอย่าง :
ด้านล่างมีตัวอย่างเดียวกันกับข้างต้น แต่สำหรับไฮเบอร์เนต 6
....
public List < Item > findAllByStringValueAndLikeOperator ( String expression ) {
CriteriaBuilder cb = entityManager . getCriteriaBuilder ();
CriteriaQuery < Item > query = cb . createQuery ( Item . class );
Root < Item > root = query . from ( Item . class );
query . select ( root );
query . where ( cb . like ( new JsonBExtractPathText ( root . get ( "jsonbContent" ), singletonList ( "string_value" ), ( NodeBuilder ) cb ), expression ));
return entityManager . createQuery ( query ). getResultList ();
}สำหรับรายละเอียดเพิ่มเติมโปรดตรวจสอบ DAO ที่ใช้ในการทดสอบ
ประเภท jsonballarrayStringSexistPredicate แสดงถึงภาคแสดงที่ตรวจสอบว่ามีการส่งสตริงอาร์เรย์ที่ผ่านมาในคุณสมบัติอาร์เรย์ JSON หรือไม่ ตัวอย่างแรกสำหรับภาคแสดงนี้ได้รับการแนะนำในส่วน "JSONBEXTRACTPATH - ส่วน JSONB_EXTRACT_PATH" ภาคการศึกษาเหล่านี้สันนิษฐานว่าฟังก์ชั่น SQL ที่มีชื่อเริ่มต้น JSONB_ALL_ARRAY_STRINGS_EXIST ที่กล่าวถึงในส่วน "ใช้การเปลี่ยนแปลง DDL" อยู่ ตัวอย่างด้านล่างกับการรวมกันกับผู้ประกอบการไม่ได้นำเสนอรายการที่ไม่มีสตริงค้นหาทั้งหมด ตัวอย่างที่ใช้ได้สำหรับไฮเบอร์เนต 5 เท่านั้น!
public List < Item > findAllThatDoNotMatchByAllMatchingTags ( Set < String > tags ) {
CriteriaBuilder cb = entityManager . getCriteriaBuilder ();
CriteriaQuery < Item > query = cb . createQuery ( Item . class );
Root < Item > root = query . from ( Item . class );
query . select ( root );
Predicate notAllMatchingTags = cb . not ( new JsonbAllArrayStringsExistPredicate ( hibernateContext , ( CriteriaBuilderImpl ) cb , new JsonBExtractPath (( CriteriaBuilderImpl ) cb , singletonList ( "top_element_with_set_of_values" ), root . get ( "jsonbContent" )), tags . toArray ( new String [ 0 ])));
Predicate withoutSetOfValuesProperty = cb . isNull ( new JsonBExtractPath (( CriteriaBuilderImpl ) cb , singletonList ( "top_element_with_set_of_values" ), root . get ( "jsonbContent" )));
query . where ( cb . or ( withoutSetOfValuesProperty , notAllMatchingTags ));
return entityManager . createQuery ( query ). getResultList ();
}สำหรับวิธีการข้างต้น Hibernate จะดำเนินการค้นหา HQL:
select
generatedAlias0
from
Item as generatedAlias0
where
(
jsonb_extract_path( generatedAlias0 . jsonbContent , :param0 ) is null
)
or (
jsonb_all_array_strings_exist( jsonb_extract_path( generatedAlias0 . jsonbContent , :param1 ) , json_function_json_array(:param2, :param3)) = FALSE
)SQL ดั้งเดิมจะมีแบบฟอร์มด้านล่าง:
select
item0_ . id as id1_0_,
item0_ . jsonb_content as jsonb_co2_0_
from
item item0_
where
jsonb_extract_path( item0_ . jsonb_content ,?) is null
or jsonb_all_array_strings_exist(jsonb_extract_path( item0_ . jsonb_content ,?), array[?,?]) = falseไฮเบอร์เนต 6 ตัวอย่าง :
ด้านล่างมีตัวอย่างเดียวกันกับข้างต้น แต่สำหรับไฮเบอร์เนต 6
public List < Item > findAllThatDoNotMatchByAllMatchingTags ( Set < String > tags ) {
CriteriaBuilder cb = entityManager . getCriteriaBuilder ();
CriteriaQuery < Item > query = cb . createQuery ( Item . class );
Root < Item > root = query . from ( Item . class );
query . select ( root );
Predicate notAllMatchingTags = cb . not ( new JsonbAllArrayStringsExistPredicate ( hibernateContext , ( NodeBuilder ) cb , new JsonBExtractPath ( root . get ( "jsonbContent" ), ( NodeBuilder ) cb , singletonList ( "top_element_with_set_of_values" )), tags . toArray ( new String [ 0 ])));
Predicate withoutSetOfValuesProperty = cb . isNull ( new JsonBExtractPath ( root . get ( "jsonbContent" ), ( NodeBuilder ) cb , singletonList ( "top_element_with_set_of_values" )));
query . where ( cb . or ( withoutSetOfValuesProperty , notAllMatchingTags ));
return entityManager . createQuery ( query ). getResultList ();
}สำหรับรายละเอียดเพิ่มเติมโปรดตรวจสอบ DAO ที่ใช้ในการทดสอบ
ประเภท jsonbanyarraysexistexistpredicate แสดงถึงเพรดิเคตที่ตรวจสอบว่ามีการส่งสตริงอาร์เรย์ในคุณสมบัติอาร์เรย์ JSON หรือไม่ ภาคการศึกษาเหล่านี้สันนิษฐานว่าฟังก์ชัน SQL ที่มีชื่อเริ่มต้น JSONB_ANY_ARRAY_STRINGS_EXIST ที่กล่าวถึงในส่วน "ใช้การเปลี่ยนแปลง DDL" อยู่ ด้านล่างมีตัวอย่างของวิธีการที่ค้นหารายการทั้งหมดที่คุณสมบัติที่เก็บอาร์เรย์มีอย่างน้อยหนึ่งสตริงที่ส่งผ่านจากอาร์เรย์ที่ผ่านเป็นอาร์กิวเมนต์วิธี ตัวอย่างที่ใช้ได้สำหรับไฮเบอร์เนต 5 เท่านั้น!
public List < Item > findAllByAnyMatchingTags ( HashSet < String > tags ) {
CriteriaBuilder cb = entityManager . getCriteriaBuilder ();
CriteriaQuery < Item > query = cb . createQuery ( Item . class );
Root < Item > root = query . from ( Item . class );
query . select ( root );
query . where ( new JsonbAnyArrayStringsExistPredicate ( hibernateContext , ( CriteriaBuilderImpl ) cb , new JsonBExtractPath (( CriteriaBuilderImpl ) cb , singletonList ( "top_element_with_set_of_values" ), root . get ( "jsonbContent" )), tags . toArray ( new String [ 0 ])));
return entityManager . createQuery ( query ). getResultList ();
}สำหรับวิธีการข้างต้น Hibernate จะดำเนินการค้นหา HQL:
select
generatedAlias0
from
Item as generatedAlias0
where
jsonb_any_array_strings_exist( jsonb_extract_path( generatedAlias0 . jsonbContent , :param0 ) , json_function_json_array(:param1, :param2)) = TRUESQL ดั้งเดิมจะมีแบบฟอร์มด้านล่าง:
select
item0_ . id as id1_0_,
item0_ . jsonb_content as jsonb_co2_0_
from
item item0_
where
jsonb_any_array_strings_exist(jsonb_extract_path( item0_ . jsonb_content ,?), array[?,?]) = trueไฮเบอร์เนต 6 ตัวอย่าง :
ด้านล่างมีตัวอย่างเดียวกันกับข้างต้น แต่สำหรับไฮเบอร์เนต 6
public List < Item > findAllByAnyMatchingTags ( HashSet < String > tags ) {
CriteriaBuilder cb = entityManager . getCriteriaBuilder ();
CriteriaQuery < Item > query = cb . createQuery ( Item . class );
Root < Item > root = query . from ( Item . class );
query . select ( root );
query . where ( new JsonbAnyArrayStringsExistPredicate ( hibernateContext , ( NodeBuilder ) cb , new JsonBExtractPath ( root . get ( "jsonbContent" ), ( NodeBuilder ) cb , singletonList ( "top_element_with_set_of_values" )), tags . toArray ( new String [ 0 ])));
return entityManager . createQuery ( query ). getResultList ();
}สำหรับรายละเอียดเพิ่มเติมและตัวอย่างด้วยผู้ให้บริการในหรือวิธีใช้ค่าตัวเลขโปรดตรวจสอบ DAO ที่ใช้ในการทดสอบ
ห้องสมุดยังสามารถใช้สำหรับการปรับเปลี่ยน JSON โดยค่าเริ่มต้นใน Hibernate เราสามารถอัปเดตคอลัมน์ด้วยเนื้อหา JSON ได้ตลอดเวลาโดยการตั้งค่าทั้งหมด ไลบรารี PosjsonHelper ยังช่วยให้คุณสามารถแก้ไขเนื้อหา JSON ได้โดยการตั้งค่าเปลี่ยนหรือลบคุณสมบัติ JSON แต่ละตัวโดยไม่ต้องเปลี่ยนเนื้อหาทั้งหมด ไลบรารีมีฟังก์ชั่น JSON และตัวดำเนินการหลายอย่างที่อนุญาตให้ใช้งานประเภทนี้
wrapper สำหรับฟังก์ชัน JSONB_SET ฟังก์ชั่นตั้งค่าหรือแทนที่ค่าของคุณสมบัติ JSON ตามเส้นทาง JSON ตรวจสอบตัวอย่างต่อไปนี้ว่ามันสามารถใช้กับ CriteriaUpdate ได้อย่างไร:
// GIVEN
Long itemId = 19L ;
String property = "birthday" ;
String value = "1970-01-01" ;
String expectedJson = "{ " child " : { " pets " : [ " dog " ], " birthday " : " 1970-01-01 " }}" ;
// when
CriteriaUpdate < Item > criteriaUpdate = entityManager . getCriteriaBuilder (). createCriteriaUpdate ( Item . class );
Root < Item > root = criteriaUpdate . from ( Item . class );
// Set the property you want to update and the new value
criteriaUpdate . set ( "jsonbContent" , new JsonbSetFunction (( NodeBuilder ) entityManager . getCriteriaBuilder (), root . get ( "jsonbContent" ), new JsonTextArrayBuilder (). append ( "child" ). append ( property ). build (). toString (), JSONObject . quote ( value ), hibernateContext ));
// Add any conditions to restrict which entities will be updated
criteriaUpdate . where ( entityManager . getCriteriaBuilder (). equal ( root . get ( "id" ), itemId ));
// Execute the update
entityManager . createQuery ( criteriaUpdate ). executeUpdate ();
// then
Item item = tested . findById ( itemId );
assertThat (( String ) JsonPath . read ( item . getJsonbContent (), "$.child." + property )). isEqualTo ( value );
JSONObject jsonObject = new JSONObject ( expectedJson );
DocumentContext document = JsonPath . parse (( Object ) JsonPath . read ( item . getJsonbContent (), "$" ));
assertThat ( document . jsonString ()). isEqualTo ( jsonObject . toString ());สิ่งนี้จะสร้างคำสั่ง SQL Update ต่อไปนี้:
update
item
set
jsonb_content = jsonb_set(jsonb_content, ?:: text [], ?::jsonb)
where
id = ?
Hibernate:
select
i1_0 . id ,
i1_0 . jsonb_content
from
item i1_0
where
i1_0 . id = ?ฟังก์ชั่นสามารถใช้ในคำสั่ง HQL ได้เช่นในตัวอย่างต่อไปนี้:
@ Transactional
public void updateJsonBySettingPropertyForItemByHQL ( Long itemId , String property , String value ) {
// Execute the update
String hqlUpdate = "UPDATE Item SET jsonbContent = jsonb_set(jsonbContent, %s(:path, 'text[]'), %s(:json, 'jsonb' ) ) WHERE id = :id" . formatted ( hibernateContext . getCastFunctionOperator (), hibernateContext . getCastFunctionOperator ());
int updatedEntities = entityManager . createQuery ( hqlUpdate )
. setParameter ( "id" , itemId )
. setParameter ( "path" , new JsonTextArrayBuilder (). append ( "child" ). append ( property ). build (). toString ())
. setParameter ( "json" , JSONObject . quote ( value ))
. executeUpdate ();
}wrapper สำหรับผู้ให้บริการการเชื่อมต่อ wrapper concatenate ค่า JSONB สองค่าเป็นค่า JSONB ใหม่ ตรวจสอบตัวอย่างต่อไปนี้ว่ามันสามารถใช้กับ CriteriaUpdate ได้อย่างไร:
// GIVEN
Long itemId = 19l ;
String property = "birthday" ;
String value = "1970-01-01" ;
// WHEN
CriteriaUpdate < Item > criteriaUpdate = entityManager . getCriteriaBuilder (). createCriteriaUpdate ( Item . class );
Root < Item > root = criteriaUpdate . from ( Item . class );
JSONObject jsonObject = new JSONObject ();
jsonObject . put ( "child" , new JSONObject ());
jsonObject . getJSONObject ( "child" ). put ( property , value );
criteriaUpdate . set ( "jsonbContent" , new ConcatenateJsonbOperator (( NodeBuilder ) entityManager . getCriteriaBuilder (), root . get ( "jsonbContent" ), jsonObject . toString (), hibernateContext ));
criteriaUpdate . where ( entityManager . getCriteriaBuilder (). equal ( root . get ( "id" ), itemId ));
entityManager . createQuery ( criteriaUpdate ). executeUpdate ();
// THEN
Item item = tested . findById ( itemId );
assertThat (( String ) JsonPath . read ( item . getJsonbContent (), "$.child." + property )). isEqualTo ( value );
JSONObject expectedJsonObject = new JSONObject (). put ( property , value );
DocumentContext document = JsonPath . parse (( Object ) JsonPath . read ( item . getJsonbContent (), "$.child" ));
assertThat ( document . jsonString ()). isEqualTo ( expectedJsonObject . toString ());สิ่งนี้จะสร้างคำสั่ง SQL Update ต่อไปนี้:
update
item
set
jsonb_content = jsonb_content || ?::jsonb
where
id = ?
Hibernate:
select
i1_0 . id ,
i1_0 . jsonb_content
from
item i1_0
where
i1_0 . id = ?ฟังก์ชั่นสามารถใช้ในคำสั่ง HQL ได้เช่นในตัวอย่างต่อไปนี้:
@ Transactional
public void updateJsonPropertyForItemByHQL ( Long itemId , String property , String value ) throws JSONException {
JSONObject jsonObject = new JSONObject ();
jsonObject . put ( "child" , new JSONObject ());
jsonObject . getJSONObject ( "child" ). put ( property , value );
String hqlUpdate = "UPDATE Item SET jsonbContent = %s(jsonbContent, %s(:json, 'jsonb' ) ) WHERE id = :id" . formatted ( hibernateContext . getConcatenateJsonbOperator (), hibernateContext . getCastFunctionOperator ());
int updatedEntities = entityManager . createQuery ( hqlUpdate )
. setParameter ( "id" , itemId )
. setParameter ( "json" , jsonObject . toString ())
. executeUpdate ();
}wrapper สำหรับ deletes operator '#-' wrapper จะลบองค์ประกอบฟิลด์หรืออาร์เรย์ตามดัชนีที่เส้นทางที่ระบุซึ่งองค์ประกอบเส้นทางสามารถเป็นทั้งคีย์ฟิลด์หรือดัชนีอาร์เรย์ ตรวจสอบตัวอย่างต่อไปนี้ว่ามันสามารถใช้กับ CriteriaUpdate ได้อย่างไร:
// GIVEN
Item item = tested . findById ( 19L );
JSONObject jsonObject = new JSONObject ( "{ " child " : { " pets " : [ " dog " ]}}" );
DocumentContext document = JsonPath . parse (( Object ) JsonPath . read ( item . getJsonbContent (), "$" ));
assertThat ( document . jsonString ()). isEqualTo ( jsonObject . toString ());
// WHEN
CriteriaUpdate < Item > criteriaUpdate = entityManager . getCriteriaBuilder (). createCriteriaUpdate ( Item . class );
Root < Item > root = criteriaUpdate . from ( Item . class );
// Set the property you want to update and the new value
criteriaUpdate . set ( "jsonbContent" , new DeleteJsonbBySpecifiedPathOperator (( NodeBuilder ) entityManager . getCriteriaBuilder (), root . get ( "jsonbContent" ), new JsonTextArrayBuilder (). append ( "child" ). append ( "pets" ). build (). toString (), hibernateContext ));
// Add any conditions to restrict which entities will be updated
criteriaUpdate . where ( entityManager . getCriteriaBuilder (). equal ( root . get ( "id" ), 19L ));
// Execute the update
entityManager . createQuery ( criteriaUpdate ). executeUpdate ();
// THEN
entityManager . refresh ( item );
jsonObject = new JSONObject ( "{ " child " : {}}" );
document = JsonPath . parse (( Object ) JsonPath . read ( item . getJsonbContent (), "$" ));
assertThat ( document . jsonString ()). isEqualTo ( jsonObject . toString ());สิ่งนี้จะสร้างคำสั่ง SQL Update ต่อไปนี้:
update
item
set
jsonb_content = (jsonb_content # - ?::text[])
where
id = ?ฟังก์ชั่นสามารถใช้ในคำสั่ง HQL ได้เช่นในตัวอย่างต่อไปนี้:
@ Transactional
public void updateJsonByDeletingSpecificPropertyForItemByHql ( Long itemId , String property ) {
// Execute the update
String hqlUpdate = "UPDATE Item SET jsonbContent = %s(jsonbContent, %s(:path, 'text[]') ) WHERE id = :id" . formatted ( hibernateContext . getDeleteJsonBySpecificPathOperator (), hibernateContext . getCastFunctionOperator ());
int updatedEntities = entityManager . createQuery ( hqlUpdate )
. setParameter ( "id" , itemId )
. setParameter ( "path" , new JsonTextArrayBuilder (). append ( "child" ). append ( property ). build (). toString ())
. executeUpdate ();
}ประเภท removejsonvaluesfromjsonarrayfunction เป็นตัวดำเนินการไฮเบอร์เนตที่เรียกใช้ฟังก์ชั่น SQL ที่สร้างขึ้นโดยไลบรารี Posjsonhelper โดยค่าเริ่มต้นฟังก์ชั่นที่สร้างขึ้นดูเหมือนตัวอย่างด้านล่าง:
CREATE OR REPLACE FUNCTION {{schema}}.remove_values_from_json_array(input_json jsonb, values_to_remove jsonb) RETURNS jsonb AS $$
DECLARE
result jsonb;
BEGIN
IF jsonb_typeof(values_to_remove) <> ' array ' THEN
RAISE EXCEPTION ' values_to_remove must be a JSON array ' ;
END IF;
result : = (
SELECT jsonb_agg(element)
FROM jsonb_array_elements(input_json) AS element
WHERE NOT (element IN ( SELECT jsonb_array_elements(values_to_remove)))
);
RETURN COALESCE(result, ' [] ' ::jsonb);
END;
$$ LANGUAGE plpgsql;ฟังก์ชั่นมีพารามิเตอร์อินพุตสองตัว อันดับแรกคืออาร์เรย์ JSON ซึ่งเป็นอาร์เรย์พื้นฐานสำหรับผลลัพธ์ที่ฟังก์ชั่นจะกลับมา พารามิเตอร์ที่สองยังเป็นอาร์เรย์ JSON ที่แสดงถึงองค์ประกอบที่ควรลบออกจากอาร์เรย์ผลลัพธ์ ด้านล่างเป็นตัวอย่างโค้ดของวิธีการใช้ฟังก์ชันนี้กับตัวดำเนินการอื่นเพื่ออัปเดตคอลัมน์ JSON ด้วยคำสั่ง SQL Update
// GIVEN
Item item = tested . findById ( 24L );
DocumentContext document = JsonPath . parse (( Object ) JsonPath . read ( item . getJsonbContent (), "$" ));
assertThat ( document . jsonString ()). isEqualTo ( "{ " child " :{ " pets " :[ " crab " , " chameleon " ]}, " inventory " :[ " mask " , " fins " , " compass " ]}" );
CriteriaUpdate < Item > criteriaUpdate = entityManager . getCriteriaBuilder (). createCriteriaUpdate ( Item . class );
Root < Item > root = criteriaUpdate . from ( Item . class );
NodeBuilder nodeBuilder = ( NodeBuilder ) entityManager . getCriteriaBuilder ();
JSONArray toRemoveJSONArray = new JSONArray ( Arrays . asList ( "mask" , "compass" ));
RemoveJsonValuesFromJsonArrayFunction deleteOperator = new RemoveJsonValuesFromJsonArrayFunction ( nodeBuilder , new JsonBExtractPath ( root . get ( "jsonbContent" ), nodeBuilder , Arrays . asList ( "inventory" )), toRemoveJSONArray . toString (), hibernateContext );
JsonbSetFunction jsonbSetFunction = new JsonbSetFunction ( nodeBuilder , ( SqmTypedNode ) root . get ( "jsonbContent" ), new JsonTextArrayBuilder (). append ( "inventory" ). build (). toString (), deleteOperator , hibernateContext );
// Set the property you want to update and the new value
criteriaUpdate . set ( "jsonbContent" , jsonbSetFunction );
// Add any conditions to restrict which entities will be updated
criteriaUpdate . where ( entityManager . getCriteriaBuilder (). equal ( root . get ( "id" ), 24L ));
// WHEN
entityManager . createQuery ( criteriaUpdate ). executeUpdate ();
// THEN
entityManager . refresh ( item );
document = JsonPath . parse (( Object ) JsonPath . read ( item . getJsonbContent (), "$" ));
assertThat ( document . jsonString ()). isEqualTo ( "{ " child " :{ " pets " :[ " crab " , " chameleon " ]}, " inventory " :[ " fins " ]}" );ตัวอย่างเดียวกัน แต่ด้วยตัวอย่างการสืบค้น HQL:
// GIVEN
Item item = tested . findById ( 24L );
DocumentContext document = JsonPath . parse (( Object ) JsonPath . read ( item . getJsonbContent (), "$" ));
assertThat ( document . jsonString ()). isEqualTo ( "{ " child " :{ " pets " :[ " crab " , " chameleon " ]}, " inventory " :[ " mask " , " fins " , " compass " ]}" );
CriteriaUpdate < Item > criteriaUpdate = entityManager . getCriteriaBuilder (). createCriteriaUpdate ( Item . class );
Root < Item > root = criteriaUpdate . from ( Item . class );
JSONArray toRemoveJSONArray = new JSONArray ( Arrays . asList ( "mask" , "compass" ));
String hqlUpdate = "UPDATE Item SET jsonbContent = %s(jsonbContent, %s(:path, 'text[]'), %s(jsonb_extract_path( jsonbContent , 'inventory' ), %s(:to_remove, 'jsonb')) ) WHERE id = :id" . formatted ( JSONB_SET_FUNCTION_NAME , hibernateContext . getCastFunctionOperator (), hibernateContext . getRemoveJsonValuesFromJsonArrayFunction (), hibernateContext . getCastFunctionOperator ());
// WHEN
entityManager . createQuery ( hqlUpdate )
. setParameter ( "id" , 24L )
. setParameter ( "path" , new JsonTextArrayBuilder (). append ( "inventory" ). build (). toString ())
. setParameter ( "to_remove" , toRemoveJSONArray . toString ())
. executeUpdate ();
// THEN
entityManager . refresh ( item );
document = JsonPath . parse (( Object ) JsonPath . read ( item . getJsonbContent (), "$" ));
assertThat ( document . jsonString ()). isEqualTo ( "{ " child " :{ " pets " :[ " crab " , " chameleon " ]}, " inventory " :[ " fins " ]}" );ตัวอย่างทั้งสองนั้นจะสร้างคำสั่ง SQL ด้านล่าง:
update
item
set
jsonb_content = jsonb_set(jsonb_content, ?:: text [], remove_values_from_json_array(jsonb_extract_path(jsonb_content, ?), ?::jsonb))
where
id = ?การใช้ฟังก์ชั่น JSONB_SET เดียวเพื่อตั้งค่าคุณสมบัติเดียวสำหรับ JSON ด้วยคำสั่งการอัปเดตเดียวอาจมีประโยชน์อย่างไรก็ตามอาจมีประโยชน์มากกว่าที่จะสามารถตั้งค่าคุณสมบัติหลายอย่างในระดับที่แตกต่างกันของต้นไม้ JSON ด้วยคำสั่งอัปเดตเดียว
เพื่อตรวจสอบรหัสด้านล่างตัวอย่าง:
// GIVEN
Item item = tested . findById ( 23L );
DocumentContext document = JsonPath . parse (( Object ) JsonPath . read ( item . getJsonbContent (), "$" ));
assertThat ( document . jsonString ()). isEqualTo ( "{ " child " :{ " pets " :[ " dog " ]}, " inventory " :[ " mask " , " fins " ], " nicknames " :{ " school " : " bambo " , " childhood " : " bob " }}" );
CriteriaUpdate < Item > criteriaUpdate = entityManager . getCriteriaBuilder (). createCriteriaUpdate ( Item . class );
Root < Item > root = criteriaUpdate . from ( Item . class );
Hibernate6JsonUpdateStatementBuilder hibernate6JsonUpdateStatementBuilder = new Hibernate6JsonUpdateStatementBuilder ( root . get ( "jsonbContent" ), ( NodeBuilder ) entityManager . getCriteriaBuilder (), hibernateContext );
hibernate6JsonUpdateStatementBuilder . appendJsonbSet ( new JsonTextArrayBuilder (). append ( "child" ). append ( "birthday" ). build (), quote ( "2021-11-23" ));
hibernate6JsonUpdateStatementBuilder . appendJsonbSet ( new JsonTextArrayBuilder (). append ( "child" ). append ( "pets" ). build (), "[ " cat " ]" );
hibernate6JsonUpdateStatementBuilder . appendDeleteBySpecificPath ( new JsonTextArrayBuilder (). append ( "inventory" ). append ( "0" ). build ());
hibernate6JsonUpdateStatementBuilder . appendJsonbSet ( new JsonTextArrayBuilder (). append ( "parents" ). append ( 0 ). build (), "{ " type " : " mom " , " name " : " simone " }" );
hibernate6JsonUpdateStatementBuilder . appendJsonbSet ( new JsonTextArrayBuilder (). append ( "parents" ). build (), "[]" );
hibernate6JsonUpdateStatementBuilder . appendDeleteBySpecificPath ( new JsonTextArrayBuilder (). append ( "nicknames" ). append ( "childhood" ). build ());
// Set the property you want to update and the new value
criteriaUpdate . set ( "jsonbContent" , hibernate6JsonUpdateStatementBuilder . build ());
// Add any conditions to restrict which entities will be updated
criteriaUpdate . where ( entityManager . getCriteriaBuilder (). equal ( root . get ( "id" ), 23L ));
// WHEN
entityManager . createQuery ( criteriaUpdate ). executeUpdate ();
// THEN
entityManager . refresh ( item );
document = JsonPath . parse (( Object ) JsonPath . read ( item . getJsonbContent (), "$" ));
assertThat ( document . jsonString ()). isEqualTo ( "{ " child " :{ " pets " :[ " cat " ], " birthday " : " 2021-11-23 " }, " parents " :[{ " name " : " simone " , " type " : " mom " }], " inventory " :[ " fins " ], " nicknames " :{ " school " : " bambo " }}" );ในรหัสข้างต้นเราต้องการตั้งค่าคุณสมบัติ JSON สามรายการ "child.birthday", "child.pets" และ "ผู้ปกครอง" และลบอีกสองคน "Inventory.0" และ "Nickname.childhood" ทรัพย์สิน "ผู้ปกครอง" เป็นทรัพย์สินใหม่ที่คาดว่าจะเป็นอาร์เรย์ แม้ว่าการตั้งค่าคุณสมบัติอาร์เรย์ใหม่ที่มีค่าบางอย่างสามารถทำได้ด้วยการดำเนินการเดี่ยว แต่เพื่อการสาธิตเราใช้การดำเนินการสองครั้ง หนึ่งคือการตั้งค่าคุณสมบัติใหม่ที่เรียกว่า "ผู้ปกครอง" ด้วยอาร์เรย์ JSON ที่ว่างเปล่าเป็นค่า และการดำเนินการอื่นที่กำหนดองค์ประกอบของอาร์เรย์ที่ดัชนีเฉพาะ หากไม่มีคุณสมบัติที่สูงกว่าจะต้องสร้างก่อนหน้าคุณสมบัติภายใน โชคดีที่อินสแตนซ์เริ่มต้นของ Hibernate6JsonUpDatestatementBuilder ประเภทมีการเรียงลำดับและการกรองที่เหมาะสมเพื่อช่วยให้คุณกำหนดลำดับการดำเนินงานที่เหมาะสม ดังนั้นจึงไม่สำคัญว่าเราจะเพิ่มการดำเนินการเสริมองค์ประกอบก่อนหรือหลังการเพิ่มการดำเนินการสร้างอาร์เรย์ โดยค่าเริ่มต้นการดำเนินการที่ลบเนื้อหาจะถูกเพิ่มก่อนที่จะเพิ่มหรือแทนที่เนื้อหา แน่นอนว่ามันเป็นไปได้ที่จะปิดการใช้งานพฤติกรรมนี้โดยการตั้งส่วนประกอบเหล่านี้ให้เป็นโมฆะ สำหรับรายละเอียดเพิ่มเติมโปรดตรวจสอบ Javadoc สำหรับ Hibernate6JsonUpDatestatementBuilder ประเภท
รหัสนี้สร้างคำสั่ง SQL ด้านล่าง:
update
item
set
jsonb_content =
jsonb_set(
jsonb_set(
jsonb_set(
jsonb_set(
(
(jsonb_content # - ?::text[]) -- the most nested #- operator
# - ?::text[])
, ?:: text [], ?::jsonb) -- the most nested jsonb_set operation
, ?:: text [], ?::jsonb)
, ?:: text [], ?::jsonb)
, ?:: text [], ?::jsonb)
where
id = ?การดำเนินการฟังก์ชั่น JSONB_SET ภายในมากที่สุดสำหรับคำสั่งที่เตรียมไว้นี้จะตั้งค่าอาร์เรย์ที่ว่างเปล่าสำหรับคุณสมบัติ "ผู้ปกครอง"
ตัวสร้างมีวิธีการตั้งค่า:
การลบคุณสมบัติ:
AppEndDeleteByspecificPath (jsonTextarray jsonTextarray)
การเพิ่มองค์ประกอบอาร์เรย์
การลบองค์ประกอบอาร์เรย์
วิธีการบางอย่างที่เกี่ยวข้องกับการปรับเปลี่ยนในอาร์เรย์ JSON โดยค่าเริ่มต้นต้องการ org.json.json ไลบรารี (ตรวจสอบการพึ่งพาตัวเลือก) อย่างไรก็ตามมีความเป็นไปได้ที่จะผ่านการใช้งานอินเทอร์เฟซที่กำหนดเองที่แมปคอลเลกชันวัตถุไปยังค่าอาร์เรย์ JSON ด้วย "WithCollectionToJsonArrayStringMapper (com.github.starnowski.posjsonhelper.hibernate6
Hibernate6JsonUpDatestatementBuilder ประเภททั่วไป ประเภททั่วไปที่สองคือค่าที่กำหนดเองที่สามารถเพิ่มลงในบริบท Hibernate6JsonUpDatestatementBuilder ด้านล่างเป็นตัวอย่างโค้ดที่มีประเภทแสดงถึงการดำเนินการอาร์เรย์ (องค์ประกอบที่ควรเพิ่มและลบออกจากอาร์เรย์)
ประเภทค่าที่กำหนดเอง:
private static class JsonArrayOperations {
private final List < String > toDelete ;
private final List < String > toAdd ;
public JsonArrayOperations ( List < String > toDelete , List < String > toAdd ) {
this . toDelete = toDelete ;
this . toAdd = toAdd ;
}
public List < String > getToDelete () {
return toDelete ;
}
public List < String > getToAdd () {
return toAdd ;
}
}ตัวอย่างการใช้งาน:
// GIVEN
Item item = tested . findById ( 24L );
DocumentContext document = JsonPath . parse (( Object ) JsonPath . read ( item . getJsonbContent (), "$" ));
assertThat ( document . jsonString ()). isEqualTo ( "{ " child " :{ " pets " :[ " crab " , " chameleon " ]}, " inventory " :[ " mask " , " fins " , " compass " ]}" );
CriteriaUpdate < Item > criteriaUpdate = entityManager . getCriteriaBuilder (). createCriteriaUpdate ( Item . class );
Root < Item > root = criteriaUpdate . from ( Item . class );
Hibernate6JsonUpdateStatementBuilder < Object , JsonArrayOperations > hibernate6JsonUpdateStatementBuilder = new Hibernate6JsonUpdateStatementBuilder ( root . get ( "jsonbContent" ), ( NodeBuilder ) entityManager . getCriteriaBuilder (), hibernateContext );
hibernate6JsonUpdateStatementBuilder . appendJsonbSet ( new JsonTextArrayBuilder (). append ( "child" ). append ( "pets" ). build (), null , new JsonArrayOperations ( Arrays . asList ( "crab" , "ant" ), Arrays . asList ( "lion" , "dolphin" )));
hibernate6JsonUpdateStatementBuilder . appendJsonbSet ( new JsonTextArrayBuilder (). append ( "name" ). build (), JSONObject . quote ( "Simon" ));
hibernate6JsonUpdateStatementBuilder . appendJsonbSet ( new JsonTextArrayBuilder (). append ( "inventory" ). build (), null , new JsonArrayOperations ( Arrays . asList ( "compass" , "mask" ), Arrays . asList ( "knife" )));
hibernate6JsonUpdateStatementBuilder . withJsonbSetFunctionFactory ( new Hibernate6JsonUpdateStatementBuilder . DefaultJsonbSetFunctionFactory < Object , JsonArrayOperations >() {
public JsonbSetFunction build ( NodeBuilder nodeBuilder , Path < Object > rootPath , JsonUpdateStatementConfiguration . JsonUpdateStatementOperation < JsonArrayOperations > operation , HibernateContext hibernateContext ) {
if ( operation . getCustomValue () != null ) {
JSONArray toAddJSONArray = new JSONArray ( operation . getCustomValue (). getToAdd ());
ConcatenateJsonbOperator concatenateOperator = new ConcatenateJsonbOperator ( nodeBuilder , new JsonBExtractPath ( rootPath , nodeBuilder , operation . getJsonTextArray (). getPath (). stream (). map ( ob -> ob . toString ()). collect ( Collectors . toList ())), toAddJSONArray . toString (), hibernateContext );
JSONArray toRemoveJSONArray = new JSONArray ( operation . getCustomValue (). getToDelete ());
RemoveJsonValuesFromJsonArrayFunction deleteOperator = new RemoveJsonValuesFromJsonArrayFunction ( nodeBuilder , concatenateOperator , toRemoveJSONArray . toString (), hibernateContext );
return new JsonbSetFunction ( nodeBuilder , ( SqmTypedNode ) rootPath , operation . getJsonTextArray (). toString (), deleteOperator , hibernateContext );
} else {
return super . build ( nodeBuilder , rootPath , operation , hibernateContext );
}
}
@ Override
public JsonbSetFunction build ( NodeBuilder nodeBuilder , SqmTypedNode sqmTypedNode , JsonUpdateStatementConfiguration . JsonUpdateStatementOperation < JsonArrayOperations > operation , HibernateContext hibernateContext ) {
if ( operation . getCustomValue () != null ) {
JSONArray toAddJSONArray = new JSONArray ( operation . getCustomValue (). getToAdd ());
ConcatenateJsonbOperator concatenateOperator = new ConcatenateJsonbOperator ( nodeBuilder , new JsonBExtractPath ( root . get ( "jsonbContent" ), nodeBuilder , operation . getJsonTextArray (). getPath (). stream (). map ( ob -> ob . toString ()). collect ( Collectors . toList ())), toAddJSONArray . toString (), hibernateContext );
JSONArray toRemoveJSONArray = new JSONArray ( operation . getCustomValue (). getToDelete ());
RemoveJsonValuesFromJsonArrayFunction deleteOperator = new RemoveJsonValuesFromJsonArrayFunction ( nodeBuilder , concatenateOperator , toRemoveJSONArray . toString (), hibernateContext );
return new JsonbSetFunction ( nodeBuilder , sqmTypedNode , operation . getJsonTextArray (). toString (), deleteOperator , hibernateContext );
} else {
return super . build ( nodeBuilder , sqmTypedNode , operation , hibernateContext );
}
}
});
// Set the property you want to update and the new value
criteriaUpdate . set ( "jsonbContent" , hibernate6JsonUpdateStatementBuilder . build ());
// Add any conditions to restrict which entities will be updated
criteriaUpdate . where ( entityManager . getCriteriaBuilder (). equal ( root . get ( "id" ), 24L ));
// WHEN
entityManager . createQuery ( criteriaUpdate ). executeUpdate ();
// THEN
entityManager . refresh ( item );
document = JsonPath . parse (( Object ) JsonPath . read ( item . getJsonbContent (), "$" ));
assertThat ( document . jsonString ()). isEqualTo ( "{ " name " : " Simon " , " child " :{ " pets " :[ " chameleon " , " lion " , " dolphin " ]}, " inventory " :[ " fins " , " knife " ]}" );| ชื่ออสังหาริมทรัพย์ | คำอธิบาย |
|---|---|
| com.github.starnowski.posjsonhelper.core.functions.jsonb_all_array_strings_exist | ชื่อของฟังก์ชัน SQL ที่ตรวจสอบว่าองค์ประกอบทั้งหมดผ่านเป็นข้อความ [] มีอยู่ในคุณสมบัติอาร์เรย์ JSON หรือไม่ โดยค่าเริ่มต้นชื่อคือ JSONB_ALL_ARRAY_STRINGS_EXIST |
| com.github.starnowski.posjsonhelper.core.functions.jsonb_any_array_strings_exist | ชื่อของฟังก์ชัน SQL ที่ตรวจสอบว่าองค์ประกอบใด ๆ ที่ผ่านเป็นข้อความ [] มีอยู่ในคุณสมบัติอาร์เรย์ JSON หรือไม่ โดยค่าเริ่มต้นชื่อคือ jsonb_any_array_strings_exist |
| com.github.starnowski.posjsonhelper.core.functions.remove_values_from_json_array | ชื่อของฟังก์ชัน SQL ที่ส่งคืนอาร์เรย์ JSONB โดยการลบองค์ประกอบจากอาร์เรย์ JSONB ส่งผ่านเป็นอินพุตสำหรับฟังก์ชั่น โดยค่าเริ่มต้นชื่อคือ remove_values_from_json_array |
| com.github.starnowski.posjsonhelper.core.schema | ชื่อของฐานข้อมูลสคีมาที่ควรสร้างฟังก์ชัน SQL |
| com.github.starnowski.posjsonhelper.core.hibernate.functions.jsonb_all_array_strings_exist | ชื่อของฟังก์ชัน HQL ที่เรียกใช้ฟังก์ชัน SQL ที่ระบุโดย com.github.starnowski.posjsonhelper.core.functions.jsonb_all_array_strings_exist โดยค่าเริ่มต้นชื่อคือ JSONB_ALL_ARRAY_STRINGS_EXIST |
| com.github.starnowski.posjsonhelper.core.hibernate.functions.jsonb_any_array_strings_exist | ชื่อของฟังก์ชัน HQL ที่เรียกใช้ฟังก์ชัน SQL ที่ระบุโดย com.github.starnowski.posjsonhelper.core.functions.jsonb_any_array_strings_exist โดยค่าเริ่มต้นชื่อคือ jsonb_any_array_strings_exist |
| com.github.starnowski.posjsonhelper.core.hibernate.functions.json_function_json_array | ชื่อของฟังก์ชั่น HQL ที่ห่อหุ้มอาร์เรย์ใน PostgreSQL โดยค่าเริ่มต้นชื่อคือ json_function_json_array |
| com.github.starnowski.posjsonhelper.core.hibernate.functions.remove_values_from_json_array | ชื่อของฟังก์ชั่น HQL ที่ห่อฟังก์ชั่นที่ส่งคืนอาร์เรย์ JSONB โดยการลบองค์ประกอบจากอาร์เรย์ JSONB ผ่านเป็นอินพุตสำหรับฟังก์ชั่น โดยค่าเริ่มต้นชื่อคือ remove_values_from_json_array |
| com.github.starnowski.posjsonhelper.core.hibernate.functions.sqldefinitioncontextfactory.types | คุณสมบัติระบบที่เก็บรายการของ com.github.starnowski.posjsonhelper.core.sql.isqldefinitioncontextfactory ประเภทที่ควรโหลด แทนที่จะเป็นประเภทการโหลดที่สามารถพบได้บน classpath สำหรับแพ็คเกจ "com.github.starnowski.posjsonhelper" ประเภทในรายการจะถูกคั่นด้วยอักขระเครื่องหมายจุลภาค "." |
| com.github.starnowski.posjsonhelper.hibernate6.functiondescriptorregisterfactory.types | (ใช้เฉพาะใน Hibernate 6) คุณสมบัติระบบที่เก็บรายการของ com.github.starnowski.posjsonhelper.hibernate6.descriptor.functiondescriptorregisterfactoriessupplier ที่ควรโหลด แทนที่จะเป็นประเภทการโหลดที่สามารถพบได้บน classpath สำหรับแพ็คเกจ "com.github.starnowski.posjsonhelper" ประเภทในรายการจะถูกคั่นด้วยอักขระเครื่องหมายจุลภาค "." |
| com.github.starnowski.posjsonhelper.hibernate6.functiondescriptorregisterfactory.types.excluded | (ใช้เฉพาะใน Hibernate 6) คุณสมบัติระบบที่เก็บรายการของ com.github.starnowski.posjsonhelper.hibernate6.descriptor.functiondescriptorregisterfactoriessupplier ที่ควรแยกออกจากการโหลด ถ้า "com.github.starnowski.posjsonhelper.hibernate6.functiondescriptorregisterfactory.types" ยังมีการระบุไว้เช่นกันแล้ว "com.github.starnowski.posjsonhelper.hibernate6 ประเภทในรายการจะถูกคั่นด้วยอักขระเครื่องหมายจุลภาค "." |
เมทริกซ์ความเข้ากันได้กับไฮเบอร์เนต 6
| posjsonhelper | ไฮเบอร์เนต 6 |
|---|---|
| 0.3.0 | 6.4.0.final |
| 0.2.0 - 0.2.1 | 6.1.5.Final |
ปัญหาเกี่ยวกับแพ็คเกจไฮเบอร์เนตเวอร์ชันหรือคลาส ฯลฯ
หากคุณประสบปัญหาที่เกี่ยวข้องกับคำจำกัดความวิธีการที่หายไปหรือประเภทเช่น:
java.lang.NoSuchMethodError: 'org.hibernate.query.criteria.JpaExpression
ก่อนอื่นโปรดตรวจสอบว่าโครงการของคุณมีห้องสมุด Hibernate-Core บน ClassPath หรือไม่ Hibernate-Core เป็นการพึ่งพาตัวเลือกสำหรับโครงการนี้และคุณต้องตรวจสอบให้แน่ใจว่ามีการเพิ่มในโครงการของคุณ โปรดตรวจสอบปัญหาที่คล้ายกัน 145. หากคุณ Hibernate-Core อยู่ใน ClassPath และปัญหายังคงมีอยู่แล้วโปรดรายงานปัญหา