hibernate 支持postgis函数
要想使用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):
数据库脚本:
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();
通过上面的方法,我们可以测试出来,hibernate已经可以支持空间数据类型的数据操作了,可以实现空间数据入库到空间数据对象影射到java对象中(插入和查询方法),但是有一个问题,就是支持的空间数据操作方法太少了。例如 contains,disjoint,within等十几个方法。这些方法都是简单的空间数据操作方法,要想实现复杂的空间数据这还远远不够的。相对于这方面来说ibatis 就很方便的使用了。
这方面的资料比较少,大家都交流 ,有什么好的经验大家分享一下。
页:
[1]