<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Jason ---分享,共同進步

    激情成就夢想,努力創造未來
    隨筆 - 53, 文章 - 1, 評論 - 45, 引用 - 0
    數據加載中……

    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 就很方便的使用了。

    這方面的資料比較少,大家都交流 ,有什么好的經驗大家分享一下。 

     

    posted on 2008-07-15 23:05 agun 閱讀(2797) 評論(7)  編輯  收藏 所屬分類: 架構設計與系統分析

    評論

    # re: hibernate 支持 postgis函數  回復  更多評論   

    我用HQL去查詢結果(hibernate+postgis)
    select t.fname from Tgpoi t where t.ftcd=111;

    select asText(t.the_geom) from Tgpoi t where t.ftcd=111;

    都可以查找出來

    但我想得到多個字段的話,輸出:
    Ljava.lang.Object;@232dsfdff

    請問一下如何能得到某條記錄所有的值
    2008-07-16 13:20 | ads

    # re: hibernate 支持 postgis函數  回復  更多評論   

    又來麻煩你了,
    hibernate 與 postgis 結合可以看看這個
    http://www.hibernatespatial.org/tutorial.html
    上面說的還不錯,提供大家參考
    2008-07-16 13:38 | ads

    # re: hibernate 支持 postgis函數  回復  更多評論   

    呵呵,這個文章很好,你上面說想得到多個字段,hibernate查詢輸出的一定是對象。
    如果是 select asText(t.the_geom) ,asText(t.the_geom) from Tgpoi t where t.ftcd=111;
    這樣的HQL,那么
    Query query = session.createQuery("select asText(t.the_geom) ,asText(t.the_geom) from Tgpoi t where t.ftcd=111");
    List l= query.list();
    System.out.println(((List)l.get(0)).get(0).toString());
    System.out.println(((List)l.get(0)).get(1).toString());
    這樣就能分別拿到查詢了列了。
    不知道你不是你說的意思。多交流。
    2008-07-17 13:57 | agun

    # re: hibernate 支持 postgis函數  回復  更多評論   

    呵呵
    謝謝了
    我做出來了,主要問題出在了
    我的驅動包引錯了,大大的失誤
    嘿嘿!!現在學習這個,資料太小,幾乎都是外文的,可憐我的外文水平!!!
    2008-07-28 10:54 | ads

    # re: hibernate 支持 postgis函數  回復  更多評論   

    呵呵,出來就好,現在這方面的中文的資料不是很多,hibernate的postgis支持不是很好,許多gis函數都需要自己聲明。有什么好的資料,到時候都拿出來分享,一起學習。
    2008-07-29 16:31 | agun

    # re: hibernate 支持 postgis函數  回復  更多評論   

    如果是大量的GIS開發,最好不要用HIBERNATE即使用上面地方法能夠支持,也只是支持不多的幾個函數,要想做更多更好的空間處理,用ibatis可以很容易結合自己的Handler Type來處理。
    2010-11-29 11:17 | agun

    # re: hibernate 支持 postgis函數  回復  更多評論   

    這個項目文件還有沒有?可不可以拷我一份?最近需要用到這個但是一直搞不定!!我的郵箱是:youdianshen@126.com
    2013-03-20 11:31 | 沈維海
    主站蜘蛛池模板: 国产麻豆视频免费观看| 亚洲日本中文字幕一区二区三区| 亚洲精华国产精华精华液| 亚洲成a人片在线观看日本麻豆| 丝袜足液精子免费视频| 亚洲性色成人av天堂| 免费在线观看你懂的| 9420免费高清在线视频| 黄床大片30分钟免费看| 亚洲午夜精品久久久久久人妖 | 亚洲线精品一区二区三区| 日韩欧毛片免费视频 | 国内精品免费视频自在线| 精品多毛少妇人妻AV免费久久| 亚洲精品视频免费在线观看| 亚洲AV日韩精品一区二区三区| 91大神在线免费观看| 一级毛片a免费播放王色| 亚洲一区二区三区亚瑟| 久久久无码精品亚洲日韩软件| 国产乱码免费卡1卡二卡3卡| aa在线免费观看| 亚洲av色香蕉一区二区三区蜜桃| 亚洲国产精品lv| 亚洲美女高清一区二区三区| 性生交片免费无码看人| 国产情侣久久久久aⅴ免费| 337P日本欧洲亚洲大胆精品| 亚洲人成影院在线高清| 亚洲乱码中文字幕久久孕妇黑人| 成年女人毛片免费播放人| 日韩精品无码免费一区二区三区| 青青草国产免费国产是公开| 亚洲国产欧美国产综合一区 | 国产免费看JIZZ视频| 免费无码H肉动漫在线观看麻豆| 国产精品成人亚洲| 亚洲va成无码人在线观看| 亚洲黄色网站视频| 久久精品国产99精品国产亚洲性色 | 成人AV免费网址在线观看|