`
lorry1113
  • 浏览: 268909 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

(转)hibernate中是否支持postgis函数的问题

阅读更多
今天上午一位朋友问到了,关于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):

数据库脚本:
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();
        System.out.println("Filter is : " + filter);
        Criteria testCriteria = session.createCriteria(Event.class);
        testCriteria.add(SpatialRestrictions.within("location", filter, filter));
        List results = testCriteria.list();
        session.getTransaction().commit();
        return results;
    }
    
    private List find1(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();
        
        Query query = session.createQuery("select within(location,'srid=4326;POLYGON ((1 1, 20 1, 20 20, 1 20, 1 1))') from Event ");

        List list = query.list();
        return list;
    }


    public Point pointFromText(String txt) throws Exception {

        String tmp = txt;
        if (!tmp.startsWith("POINT")) {
            tmp = tmp.replace(",", " ");
            tmp = "POINT(" + tmp + ")";
        }

        try {
              WKTReader fromText = new WKTReader();
                Geometry  geom = fromText.read(tmp);
                
            
            Point pt = (Point) fromText.read(tmp);
            pt.setSRID(SRID);
            return pt;
        } catch (Exception e) {
            return null;
        }
    }


    }
通过上面的方法,我们可以测试出来,hibernate已经可以支持空间数据类型的数据操作了,可以实现空间数据入库到空间数据对象影射到java 对象中(插入和查询方法),但是有一个问题,就是支持的空间数据操作方法太少了。例如 contains,disjoint,within等十几个方法。这些方法都是简单的空间数据操作方法,要想实现复杂的空间数据这还远远不够的。相对于这方面来说ibatis 就很方便的使用了。

英文好的可以看看这个:http://www.hibernatespatial.org/tutorial.html
分享到:
评论
2 楼 lorry1113 2011-01-13  
ibatis没有怎么用过的,不大清楚
不过,hibernate有空间支持,ibatis也应该有的,google一下吧
1 楼 zhjgrace 2011-01-13  
ibatis怎么解析mysql的opengis中的point函数呢

相关推荐

    postgis jar包

    描述中提到“postgis的官网上不去”,这可能是因为网络问题或者官方站点暂时不可访问。在这种情况下,分享这个jar包是为了确保开发者或用户能够获取到所需的驱动,以便在自己的项目中连接和操作PostGIS数据库。"可以...

    spring-gis:Spring Data JPA、Hibernate Spatial、Postgis

    PostGIS支持标准的地理空间数据类型和函数,允许存储、查询和分析地理信息。它能够处理复杂的几何对象,并提供丰富的空间运算,如距离计算、缓冲区生成、拓扑分析等。PostGIS广泛应用于地图服务、地理信息系统、...

    hibernate spatial 文档

    Hibernate Spatial支持Geometry类型的属性,使其能够将这些复杂的几何对象存储到支持空间数据的数据库中,例如PostGIS(基于PostgreSQL的空间扩展)和Oracle Spatial。 在使用Hibernate Spatial前,需要确保获取到...

    NHibernate.Spatial-2.1.2.GA

    在Java世界中,Hibernate是广泛使用的ORM(对象关系映射)工具,而NHibernate是其在.NET上的等价物。这个版本2.1.2.GA意味着这是一个稳定版本,GA代表“General Availability”,意味着它已经过充分测试并适合生产...

    支持pyramid2.x的kotti web代码

    Kotti 是一个基于 Pyramid 框架的 Python 内容管理系统(CMS),适合用来搭建中小型网站、文档库、企业展示平台、知识库等需要灵活内容结构和权限模型的项目。它本身更像一个可以二次开发的 CMS 框架,比 WordPress、Drupal 这类“一装就用”的系统更倾向于开发者定制和扩展。 这是支持pyramid2.x版本的kotti! tar -xzvf kotti1.0.tar.gz 解压缩 进入目录执行 pip install -e . 来安装, 然后执行pserve app.ini 启动。 用浏览器浏览127.0.0.1:5000 即可浏览。 用户名admin ,口令qwerty

    cmd-bat-批处理-脚本-hello world.zip

    cmd-bat-批处理-脚本-hello world.zip

    知识付费系统自动采集V3.0 跳转不卡顿+搭建教程

    知识付费系统自动采集V3.0 跳转不卡顿+搭建教程,不和外面的一样跳转卡顿,这个跳转不卡顿,支持三级分销。

    基于Matlab实现图像形状纹理颜色特征提取

    在Matlab环境下,对图像进行特征提取时,主要涵盖形状、纹理以及颜色这三大关键特征。其中,对于纹理特征的提取,采用灰度梯度共生矩阵这一方法来实现。通过灰度梯度共生矩阵,可以有效地捕捉图像中像素灰度值之间在不同方向和距离上的相互关系,进而量化地反映出图像的纹理特性,为后续的图像分析、分类等任务提供重要的纹理信息依据。

    实证数据-2010-2023年上市公司-管理层情感语调数据-社科经管.rar

    该数据集为2010-2023年中国A股上市公司管理层情感语调的年度面板数据,覆盖45,320条样本,数据源自年报及半年报的"管理层讨论与分析"部分。通过构建中文金融情感词典(融合《知网情感分析用词典》与L&M金融词汇表),采用文本分析方法计算情感语调指标,包括:正面/负面词汇数量、文本相似度、情感语调1((积极词-消极词)/总词数)和情感语调2((积极词-消极词)/(积极词+消极词))。同时包含盈利预测偏差、审计意见类型等衍生指标,可用于研究信息披露质量、市场反应及代理问题。该数据复刻了《管理世界》《财经研究》等期刊的变量构建方法,被应用于分析语调操纵对债券市场的影响,学术常用度与稀缺度较高。

    cmd-bat-批处理-脚本-FTIME.zip

    cmd-bat-批处理-脚本-FTIME.zip

    1747829038637.png

    1747829038637.png

    2025年自动化X光检查机项目大数据研究报告.docx

    2025年自动化X光检查机项目大数据研究报告.docx

    基于Logisim的原码与补码一位乘法器设计

    在计算机组成原理课程设计中,我全程跟随老师的指导,独立完成了以下两项任务:一是利用Logisim软件进行原码一位乘法器的仿真设计,通过逐步搭建电路、配置逻辑单元,实现了原码乘法运算的完整流程,深入理解了原码乘法的原理和实现机制;二是完成了补码一位乘法器的Logisim仿真,同样按照老师讲解的步骤,精心设计电路,确保补码乘法运算的正确性,进一步掌握了补码乘法的运算规则和电路实现方法。通过这两个项目,我不仅巩固了理论知识,还提升了动手实践能力和逻辑思维能力。

    cmd-bat-批处理-脚本-msvc2017.zip

    cmd-bat-批处理-脚本-msvc2017.zip

    cmd-bat-批处理-脚本-virtualcam-install.zip

    cmd-bat-批处理-脚本-virtualcam-install.zip

    二十四节气之立秋介绍.pptx

    二十四节气之立秋介绍.pptx

    cmd-bat-批处理-脚本-shift.zip

    cmd-bat-批处理-脚本-shift.zip

    二十四节气之小雪介绍.pptx

    二十四节气之小雪介绍.pptx

    java、SpringBoot面试专题,6页面试题

    java、SpringBoot面试专题,6页面试题

    cmd-bat-批处理-脚本-GenerateUnionWinMD.zip

    cmd-bat-批处理-脚本-GenerateUnionWinMD.zip

Global site tag (gtag.js) - Google Analytics