<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 | 沈維海
    主站蜘蛛池模板: 亚洲美女高清一区二区三区| 污视频网站免费观看| 国产日韩久久免费影院| 野花高清在线观看免费3中文| 亚洲色WWW成人永久网址| 狠狠入ady亚洲精品| 国产精品久久香蕉免费播放| 亚洲AV成人无码网站| 国产乱子伦精品免费无码专区| 亚洲精品无码一区二区| 免费a级毛片高清视频不卡| 亚洲夂夂婷婷色拍WW47| 妞干网手机免费视频| 国产亚洲福利精品一区二区| 四虎永久免费地址在线网站| 男女交性无遮挡免费视频| 亚洲Av无码乱码在线播放| 久久久精品国产亚洲成人满18免费网站| 亚洲精品无码精品mV在线观看| 免费无码看av的网站| 成人在线免费视频| 亚洲熟妇少妇任你躁在线观看无码 | 无码国产精品一区二区免费式影视| 亚洲免费视频一区二区三区| 久久亚洲精品成人综合| 麻豆最新国产剧情AV原创免费| 亚洲AV日韩AV永久无码色欲| 亚洲国产午夜中文字幕精品黄网站| 久久久久亚洲AV无码去区首| 国产专区一va亚洲v天堂| 久久国产免费直播| 久久亚洲AV成人无码软件| 成人午夜大片免费7777| 亚洲色欲www综合网| 国产色爽免费视频| 中文字幕无码日韩专区免费| 亚洲综合伊人制服丝袜美腿| 亚洲国产香蕉人人爽成AV片久久 | 免费无码成人AV在线播放不卡| 亚洲乱码无限2021芒果| va亚洲va日韩不卡在线观看|