要想使用hibernate的空间数据操作,就要提到一个概念 java Topology Suite (字面上理解就是 空间拓扑的意思,简称JTS , 注意:过需要声明一点,本文中的JTS与进行java事务处理的JTS、JTA没有联系). HIBERNATE中对空间数据作了支持(Hibernate Spatial ),Hibernate Spatial 是对处理空间数据的一个Hibernate扩展 ,Hibernate Spatial 使用标准的方式处理地理信息数据 ,并且提供了一个可以跨数据库的处理的接口函数,Hibernate Spatial 中包含了多种 OGC 简单的处理函数. 支持的数据库为: Oracle 10g/11g, Postgresql/Postgis, and MySQL. 要想使用 Hibernate Spatial 就要引入JTS, JTS 从根本上而言其实并不是很复杂,它主要是完成了java对几何对象、空间拓扑得核心操作算法。 下面通过简单配置来说明一下如何使用(我们使用的数据库是postgis): 数据库脚本: sql: CREATE TABLE events ( id bigint NOT NULL, event_date timestamp without time zone, title character varying(255), "location" geometry, CONSTRAINT events_pkey PRIMARY KEY (id) ) 1,引入 jts-1.8.jar, hibernate3.jar 等包 ,同时还要应用 hibernate-spatial-postgis-1.0-20070920.111959-1.jar 和 hibernate-spatial-1.0-20070920.111959-1.jar 包(如果不是postgre sql就要引用相应的数据库包)。 2,创建一个持久化类(po对象) 如下:
import
java.util.Date;
import
com.vividsolutions.jts.geom.Point;
public
class
Event
{ private Long id; private String title; private Date date; private Point location; public Event() {} public Long getId() { return id; } private void setId(Long id) { this .id = id; } public Date getDate() { return date; } public void setDate(Date date) { this .date = date; } public String getTitle() { return title; } public void setTitle(String title) { this .title = title; } public Point getLocation() { return this .location; } public void setLocation(Point location) { this .location = location; } }
注意:上面的po对象中的location属性的类型。这个类型是空间数据类型。 3,创建相应的Mapping 文件
<
hibernate
-
mapping
>
<
class
name
=
"
Event
"
table
=
"
EVENTS
"
>
<
id name
=
"
id
"
column
=
"
EVENT_ID
"
>
<
generator
class
=
"
native
"
/>
</
id
>
<
property name
=
"
date
"
type
=
"
timestamp
"
column
=
"
EVENT_DATE
"
/>
<
property name
=
"
title
"
/>
<
property name
=
"
location
"
type
=
"
org.hibernatespatial.GeometryUserType
"
column
=
"
location
"
/>
</
class
>
</
hibernate
-
mapping
>
注意:在上面的影射文件中,type="org.hibernatespatial.GeometryUserType" 这type类型声明很特别,我们知道在hibernate中要自定义影射类型,可以自定义类型UserType.在这个配置文件中定义的类型org.hibernatespatial.GeometryUserType就是hibernatespatial中定义支持空间数据库的类型。 4,配置hibernate 配置文件
<?
xml version='1.0' encoding='utf-8'
?>
<!
DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"
>
<
hibernate-configuration
>
<
session-factory
>
<!--
Database connection settings
-->
<
property
name
="connection.driver_class"
>
org.postgresql.Driver
</
property
>
<
property
name
="connection.url"
>
jdbc:postgresql://localhost:5432/test
</
property
>
<
property
name
="connection.username"
>
postgres
</
property
>
<
property
name
="connection.password"
>
test
</
property
>
<!--
JDBC connection pool (use the built-in)
-->
<
property
name
="connection.pool_size"
>
1
</
property
>
<!--
SPATIAL SQL dialect
-->
<
property
name
="dialect"
>
org.hibernatespatial.postgis.PostgisDialect
</
property
>
<!--
Enable Hibernate's automatic session context management
-->
<
property
name
="current_session_context_class"
>
thread
</
property
>
<!--
Disable the second-level cache
-->
<
property
name
="cache.provider_class"
>
org.hibernate.cache.NoCacheProvider
</
property
>
<!--
Echo all executed SQL to stdout
-->
<
property
name
="show_sql"
>
true
</
property
>
<!--
Drop and re-create the database schema on startup
-->
<
property
name
="hbm2ddl.auto"
>
create
</
property
>
<
mapping
resource
="Event.hbm.xml"
/>
</
session-factory
>
</
hibernate-configuration
>
注意:在上面的配置文件中, <property name="dialect">org.hibernatespatial.postgis.PostgisDialect</property> 这句配置起到了重要的作用,这里声明了 hibernate 的方言。该方言声明了对postgis的一些支持。 并且大家也应该知道,在使用hibernate时候,如果需要自定义函数,要需要自定义方言。 5,第一个主类
import
org.hibernate.Criteria;
import
org.hibernate.Query;
import
org.hibernate.Session;
import
org.hibernatespatial.criterion.SpatialRestrictions;
import
org.postgis.Geometry;
import
org.postgis.LineString;
import
org.postgis.MultiLineString;
import
org.postgis.MultiPolygon;
import
org.postgis.PGgeometry;
import
org.postgis.Polygon;
import
com.vividsolutions.jts.geom.Point;
import
com.vividsolutions.jts.io.ParseException;
import
com.vividsolutions.jts.io.WKTReader;
import
com.vividsolutions.jts.geom.
*
;
import
java.util.Date;
import
java.util.List;
import
util.HibernateUtil;
public
class
EventManager
{ public int SRID = 4326 ; public static void main(String[] args) { EventManager mgr = new EventManager(); String testPiont = " 2,3 " ; mgr.createAndStoreEvent( " My Event " , new Date(), testPiont); HibernateUtil.getSessionFactory().close(); } private void createAndStoreEvent(String title, Date theDate, String wktPoint) { com.vividsolutions.jts.geom.Geometry geom = null ; try { geom = pointFromText(wktPoint); } catch (Exception e) { throw new RuntimeException( " Not a WKT string: " + wktPoint); } Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); Event theEvent = new Event(); theEvent.setTitle(title); theEvent.setDate(theDate); theEvent.setLocation((Point) geom); session.save(theEvent); session.flush(); session.getTransaction().commit(); List l = find( " POLYGON((1 1,20 1,20 20, 1 20, 1 1)) " ); System.out.println(l.size()); List l1 = find1( " POLYGON((1 1,20 1,20 20, 1 20, 1 1)) " ); System.out.println(l1.size()); } private List find(String wktFilter) { WKTReader fromText = new WKTReader(); com.vividsolutions.jts.geom.Geometry filter = null ; try { filter = fromText.read(wktFilter); filter.setSRID(SRID); } catch (ParseException e) { throw new RuntimeException( " Not a WKT String: " + wktFilter); } Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction();