2016-02-02 13 views
8

Sto cercando di utilizzare JDBC per visualizzare le righe in una tabella creata in un database Oracle 11g, il problema è che non riesco a ottenere il valore dell'attributo "SHAPE" di tipo "SDO_GEOMETRY" utilizzando il seguente codice, che tra l'altro funziona bene quando si tratta di altri attributi della tabella:Valore di visualizzazione dell'attributo di tipo SDO_GEOMETRY

 try { 

      Class.forName("oracle.jdbc.driver.OracleDriver"); 
      System.out.println("Driver O.K."); 

      String url = "jdbc:oracle:thin:@localhost:1521:xe"; 
      String user = "system"; 
      String passwd = "isima"; 

      Connection conn = DriverManager.getConnection(url, user, passwd); 
      System.out.println("Connexion effective"); 

      Statement myStmt = null; 
      ResultSet myRs = null;   

      myStmt = conn.createStatement(); 

      myRs = myStmt.executeQuery("SELECT * FROM testGeo"); 

      while (myRs.next()) { 
      System.out.println(myRs.getString("shape")); 

      } 

      } catch (Exception e) { 
      e.printStackTrace(); 
      } 

Ecco le istruzioni DDL utilizzate per creare la tabella testGeo e alcuni dati di test.

CREATE TABLE testGeo (
    GeoID NUMBER PRIMARY KEY, 
    name VARCHAR2(32), 
    shape SDO_GEOMETRY); 

INSERT INTO testGeo VALUES(
    1, 
    'cola_a', 
    SDO_GEOMETRY(
    2003, 
    NULL, 
    NULL, 
    SDO_ELEM_INFO_ARRAY(1,1003,3), 
    SDO_ORDINATE_ARRAY(1,1, 5,7) 
) 
); 

INSERT INTO testGeo VALUES(
    2, 
    'cola_b', 
    SDO_GEOMETRY(
    2003, 
    NULL, 
    NULL, 
    SDO_ELEM_INFO_ARRAY(1,1003,3), 
    SDO_ORDINATE_ARRAY(2,1, 6,7) 
) 
); 

INSERT INTO testGeo VALUES(
    3, 
    'cola_c', 
    SDO_GEOMETRY(
    2003, 
    NULL, 
    NULL, 
    SDO_ELEM_INFO_ARRAY(1,1003,3), 
    SDO_ORDINATE_ARRAY(1,1, 9,9) 
) 
); 
+0

È possibile fornire le istruzioni DDL utilizzate per creare la tabella 'testGeo' e alcuni dati di test. – MT0

+0

Possibile duplicato di http://stackoverflow.com/questions/7204200/how-to-retrieve-sdo-geometry-from-database-using-jdbc –

risposta

8

Il problema è causato dal fatto che si sta tentando di recuperare un oggetto complesso che è un oggetto Oracle personalizzato che deve essere gestito con la propria libreria di mapping. Il tipo SDO_GEOMETRY come usato qui in voi esempio dichiarazione:

SDO_GEOMETRY(
    2003, 
    NULL, 
    NULL, 
    SDO_ELEM_INFO_ARRAY(1,1003,3), 
    SDO_ORDINATE_ARRAY(1,1, 5,7) 
) 

fa parte del pacchetto di Oracle Spatial e si basa su oggetti personalizzati. Questi non possono essere letti facilmente come colonne SQL di base come VARCHAR o NUMBER, motivo per cui la tua chiamata getString("shape") non produce risultati.

La soluzione è quella di utilizzare il JGeometry package fornito da Oracle che è stato progettato proprio per questo scopo:

una classe Java che esegue il mapping di tipo SQL MDSYS.SDO_GEOMETRY di Oracle Spatial. Supporta solo Oracle JDBC Driver versione 8.1.7 o successiva. Fornisce le funzioni di accesso di base alle geomerie arricchite nel database Oracle Spatial .

Con questa libreria sul classpath si sarebbe in grado di utilizzare le mappature Java personalizzato per manipolare l'oggetto di forma:

/// reading a geometry from database 
ResultSet rs = statement.executeQuery("SELECT shape FROM testGeo"); 
STRUCT st = (oracle.sql.STRUCT) rs.getObject(1); 
//convert STRUCT into geometry 
JGeometry j_geom = JGeometry.load(st); 
+0

Grazie, sai come posso fare lo stesso usando Hibernate? – Neo

+0

Hibernate 5 non è supportato (ancora, immagino), ma per il resto esiste un supporto ufficiale per Spatial dal team di Hibernate: http://www.hibernatespatial.org/. –

3

Si può usare qualcosa di simile

select g.geoid, g.name, go.column_value 
from testgeo g, table(g.shape.SDO_ORDINATES) go; 

ma si otterrà una riga per ogni numero nella forma.

+0

Il problema è in realtà che ottengo "null" come valore dell'attributo SHAPE di ogni riga del mio tavolo, quando provo ad accedere al mio database usando JDBC come mostrato sopra. – Neo

2

Credo che l'errore sia con getString() perché SDO_GEOMETRY non può essere trasformato in una stringa. Non sono a conoscenza di oracleDB per essere onesto, quindi è solo un'ipotesi.

Hai provato getInt() o getByteArray() o opzioni simili?

Ci sono un sacco di possibilità per ottenere dati dal database.

5

si dovrebbe usare JGeometry classe nel pacchetto Java Oracle Spatial per questo. È possibile chiamare il tipo spaziale, come:

// Read a geometry from the DB. 
ResultSet rs = statement.executeQuery("SELECT shape FROM testGeo where name='cola_a'"); 
STRUCT stGeo = (oracle.sql.STRUCT) rs.getObject(1); 
JGeometry jGeo = JGeometry.load(stGeo); 
// Use jGeo to fetch the required data. 

Se avete bisogno di scrivere la geometria di nuovo al database, si può provare questo:

// Write a geometry back to the DB. 
PreparedStatement ps = connection.prepareStatement("UPDATE testGeo set shape=? where name='cola_a'"); 
STRUCT stGeo = JGeometry.store(jGeom, connection); 
ps.setObject(1, stGeo); 
ps.execute(); 

Nota: consultare la documentazione JGeometry per l'utilizzo di le API di classe.

Problemi correlati