Úvod do režimu dlhodobého spánku

1. Úvod

V tomto článku sa pozrieme na priestorové rozšírenie hibernácie, hibernácie-priestorové.

Počnúc verziou 5, Hibernate Spatial poskytuje štandardné rozhranie pre prácu s geografickými údajmi.

2. Pozadie týkajúce sa režimu dlhodobého spánku

Geografické údaje zahŕňajú zastúpenie subjektov ako a Bod, čiara, mnohouholník. Takéto dátové typy nie sú súčasťou špecifikácie JDBC, a preto sa JTS (JTS Topology Suite) stal štandardom pre reprezentáciu typov priestorových údajov.

Hibernate spatial okrem JTS podporuje aj Geolatte-geom - nedávnu knižnicu, ktorá má niektoré funkcie, ktoré v JTS nie sú k dispozícii.

Obe knižnice sú už zahrnuté v hibernačno-priestorovom projekte. Používanie jednej knižnice nad druhou je jednoducho otázkou, z ktorej nádoby importujeme dátové typy.

Aj keď priestorový režim Hibernate podporuje rôzne databázy ako Oracle, MySQL, PostgreSQLql / PostGIS a niekoľko ďalších, podpora funkcií špecifických pre databázu nie je jednotná.

Je lepšie si prečítať najnovšiu dokumentáciu o režime spánku, aby ste skontrolovali zoznam funkcií, pre ktoré režim dlhodobého spánku poskytuje podporu pre danú databázu.

V tomto článku budeme používať pamäť Mariadb4j v pamäti, ktorá zachováva úplnú funkčnosť MySQL.

Konfigurácia pre Mariadb4j a MySql je podobná, dokonca aj knižnica mysql-connector funguje pre obe tieto databázy.

3. Maven závislosti

Pozrime sa na Mavenove závislosti potrebné na nastavenie jednoduchého priestorového projektu hibernácie:

 org.hibernate hibernate-core 5.2.12.Final org.hibernate hibernate-spatial 5.2.12.Final mysql mysql-connector-java 6.0.6 ch.vorburger.mariaDB4j mariaDB4j 2.2.3 

The prezimovať-priestorový závislosť je tá, ktorá poskytne podporu pre typy priestorových údajov. Najnovšie verzie hibernate-core, hibernate-spatial, mysql-connector-java a mariaDB4j je možné získať z Maven Central.

4. Konfigurácia priestorového režimu dlhodobého spánku

Prvým krokom je vytvorenie a prezimovať.vlastnosti v zdrojov adresár:

hibernate.dialect = org.hibernate.spatial.dialect.mysql.MySQL56SpatialDialect // ...

Jediná vec, ktorá je špecifická pre režim dlhodobého spánku, je MySQL56SpatialDialect nárečie. Tento dialekt rozširuje MySQL55Dialect a poskytuje ďalšie funkcie súvisiace s typmi priestorových údajov.

Kód špecifický pre načítanie súboru vlastností, vytvorenie a SessionFactorya inštancia inštancie Mariadb4j je rovnaká ako v štandardnom projekte hibernácie.

5. Pochopenie Geometria Typ

Geometria je základný typ pre všetky priestorové typy v JTS. To znamená, že iné typy majú radi Bod, Polygóna ďalšie siahajú od Geometria. The Geometria typ v jave zodpovedá GEOMETRIA zadajte aj MySql.

Analýzou a String reprezentácia typu, dostaneme inštanciu Geometria. Úžitková trieda WKTReader poskytnuté spoločnosťou JTS môžu byť použité na prevod akejkoľvek známej textovej reprezentácie na a Geometria typ:

public Geometry wktToGeometry (String wellKnownText) throws ParseException {return new WKTReader (). read (wellKnownText); }

Teraz sa pozrime na túto metódu v akcii:

@Test public void shouldConvertWktToGeometry () {Geometry geometry = wktToGeometry ("POINT (2 5)"); assertEquals ("Bod", geometry.getGeometryType ()); assertTrue (geometria instanceof Point); }

Ako vidíme, aj keď je návratový typ metódy čítať() metóda je Geometria, skutočný prípad je prípad a Bod.

6. Uloženie bodu do DB

Teraz, keď máme dobrú predstavu o tom, čo Geometria typ je a ako získať Bod z a String, poďme sa pozrieť na PointEntity:

@Entity verejná trieda PointEntity {@Id @GeneratedValue private Long id; súkromný bod bodu; // štandardné getre a setre}

Všimnite si, že entita PointEntity obsahuje priestorový typ Bod. Ako už bolo preukázané skôr, a Bod je reprezentovaná dvoma súradnicami:

public void insertPoint (reťazcový bod) {entita PointEntity = nová PointEntity (); entity.setPoint ((Point) wktToGeometry (point)); session.persist (entita); }

Metóda insertPoint () prijíma známu textovú (WKT) reprezentáciu a Bod, prevádza ho na a Bod napríklad a uloží do DB.

Pripomíname, že zasadanie nie je špecifický pre hibernáciu-priestorovú a je vytvorený podobným spôsobom ako v inom projekte hibernácie.

Môžeme si tu všimnúť, že akonáhle budeme mať inštanciu Bod proces ukladania PointEntity je podobný ako každý bežný subjekt.

Pozrime sa na niekoľko testov:

@Test public void shouldInsertAndSelectPoints () {PointEntity entity = new PointEntity (); entity.setPoint ((Point) wktToGeometry ("POINT (1 1)")); session.persist (entita); PointEntity fromDb = session .find (PointEntity.class, entity.getId ()); assertEquals ("POINT (1 1)", fromDb.getPoint (). toString ()); assertTrue (geometria instanceof Point); }

Telefonovanie natiahnuť() na a Bod vráti WKT reprezentáciu a Bod. Je to preto, lebo Geometria trieda prepíše natiahnuť() metóda a interne používa WKTWriter, bezplatná trieda do WKTReader ktoré sme videli skôr.

Po spustení tohto testu sa vytvorí režim dlhodobého spánku PointEntity stôl pre nás.

Pozrime sa na túto tabuľku:

desc PointEntity; Typ poľa Nulový identifikátor kľúča bigint (20) ŽIADNA geometria bodu PRI ÁNO

Podľa očakávania Typ z LúkaBod je GEOMETRIA. Z tohto dôvodu potrebujeme pri načítaní údajov pomocou nášho editora SQL (ako napríklad pracovný stôl MySql) previesť tento typ GEOMETRIE na text čitateľný človekom:

vyberte id, astext (bod) z PointEntity; id astext (bod) 1 BOD (2 4)

Pretože však hibernácia už vracia reprezentáciu WKT, keď voláme natiahnuť() metóda na Geometria alebo ktorejkoľvek z jeho podtried, s touto konverziou sa nemusíme trápiť.

7. Používanie priestorových funkcií

7.1. ST_WITHIN () Príklad

Teraz sa pozrieme na využitie databázových funkcií, ktoré pracujú s typmi priestorových údajov.

Jednou z takýchto funkcií v MySQL je ST_WITHIN () to hovorí, či jeden Geometria je v inom. Dobrým príkladom by tu bolo zistiť všetky body v danom okruhu.

Na úvod sa pozrieme na to, ako vytvoriť kruh:

verejná Geometry createCircle (dvojité x, dvojité y, dvojitý polomer) {GeometricShapeFactory shapeFactory = nový GeometricShapeFactory (); shapeFactory.setNumPoints (32); shapeFactory.setCentre (nová súradnica (x, y)); shapeFactory.setSize (polomer * 2); návrat shapeFactory.createCircle (); }

Kruh je reprezentovaný konečnou sadou bodov určených znakom setNumPoints () metóda. The polomer sa pred volaním na číslo zdvojnásobí setSize () metóda, pretože potrebujeme nakresliť kruh okolo stredu, v oboch smeroch.

Poďme teraz dopredu a pozrime sa, ako načítať body v rámci daného polomeru:

@ Test public void shouldSelectAllPointsWithinRadius () hodí ParseException {insertPoint ("POINT (1 1)"); insertPoint ("BOD (1 2)"); insertPoint ("BOD (3 4)"); insertPoint ("BOD (5 6)"); Dotaz na dotaz = session.createQuery ("vyberte p z PointEntity p, kde v rámci (p.point,: circle) = true", PointEntity.class); query.setParameter ("kruh", createCircle (0,0, 0,0, 5)); assertThat (query.getResultList (). stream () .map (p -> ((PointEntity) p) .getPoint (). toString ())) .containsOnly ("POINT (1 1)", "POINT (1 2)" "); }

Hibernácia mapuje svoje v rámci () funkcie do ST_WITHIN () funkcia MySql.

Zaujímavé je tu pozorovanie, že Bod (3, 4) padá presne na kruh. Dotaz však tento bod nevracia. To je preto, že the v rámci () funkcia vráti true iba ak je zadaná Geometria je úplne v inom Geometria.

7.2. ST_TOUCHES () Príklad

Tu uvedieme príklad, ktorý vloží množinu Polygóns v databáze a vyberte Polygóns ktoré susedia s daným Polygón. Poďme sa rýchlo pozrieť na PolygonEntity trieda:

@Entity verejná trieda PolygonEntity {@Id @GeneratedValue private Long id; súkromný polygón mnohouholník; // štandardné getre a setre}

Jediná vec odlišná od predchádzajúcej PointEntity je to, že používame typ Polygón namiesto Bod.

Poďme teraz k testu:

@Test public void shouldSelectAdjacentPolygons () hodí ParseException {insertPolygon ("POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))"); insertPolygon ("POLYGON ((3 0, 3 5, 8 5, 8 0, 3 0))"); insertPolygon ("POLYGON ((2 2, 3 1, 2 5, 4 3, 3 3, 2 2))"); Dotaz na dotaz = session.createQuery ("vyberte p z PolygonEntity p, kde sa dotkne (p.polygon,: polygon) = true", PolygonEntity.class); query.setParameter ("mnohouholník", wktToGeometry ("POLYGON ((5 5, 5 10, 10 10, 10 5, 5 5))")); assertThat (query.getResultList (). stream () .map (p -> ((PolygonEntity) p) .getPolygon (). toString ())). containsOnly ("POLYGON ((0 0, 0 5, 5 5, 5) 0, 0 0)) "," POLYGON ((3 0, 3 5, 8 5, 8 0, 3 0)) "); }

The insertPolygon () metóda je podobná insertPoint () metóda, ktorú sme videli skôr. Zdroj obsahuje úplnú implementáciu tejto metódy.

Používame dotyky () funkcia nájsť Polygóns susedí s daným Polygón. Jednoznačne tretí Polygón sa vo výsledku nevráti, pretože sa daný okraj nedotýka hrany Polygón.

8. Záver

V tomto článku sme videli, že hibernácia-priestorové zjednodušuje prácu s priestorovými dátovými typmi, pretože sa stará o detaily na nízkej úrovni.

Aj keď tento článok používa Mariadb4j, môžeme ho nahradiť MySql bez úpravy akejkoľvek konfigurácie.

Celý zdrojový kód tohto článku nájdete ako vždy na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found