我正在尝试使用JDBC在Oracle 11g数据库中创建的表中显示行,问题是我无法使用以下代码获取“SDO_GEOMETRY”类型的属性“SHAPE”的值顺便说一下,当涉及到表的其他属性时,顺便说一句:
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();
}
以下是用于创建testGeo表和一些测试数据的DDL语句。
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 :(得分:8)
问题本身是由于您正在尝试检索作为自定义Oracle对象的复杂对象,而该对象应使用自己的映射库进行处理。 SDO_GEOMETRY
类型在你的示例声明中使用:
SDO_GEOMETRY(
2003,
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,3),
SDO_ORDINATE_ARRAY(1,1, 5,7)
)
是Oracle Spatial包的一部分,依赖于自定义对象。这些内容无法像VARCHAR
或NUMBER
这样的基本SQL列轻松阅读,这就是为什么getString("shape")
调用不会产生任何结果的原因。
解决方案是使用专为此目的而设计的Oracle提供的JGeometry package:
映射Oracle Spatial的SQL类型MDSYS.SDO_GEOMETRY的Java类。 仅支持Oracle JDBC驱动程序版本8.1.7或更高版本。提供 Oracle Spatial中覆盖的几何体的基本访问函数 数据库中。
使用类路径上的这个库,您可以使用自定义Java映射来操作形状对象:
/// 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);
答案 1 :(得分:5)
为此,您应该在Oracle Spatial Java包中使用JGeometry类。您可以调用空间类型,例如:
// 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.
如果您需要将Geometry写回数据库,可以试试这个:
// 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();
注意:请参阅JGeometry文档以了解类API的用法。
答案 2 :(得分:3)
您可以使用类似
的内容select g.geoid, g.name, go.column_value
from testgeo g, table(g.shape.SDO_ORDINATES) go;
但是你会在形状中为每个数字获得一行。
答案 3 :(得分:2)
我认为错误是getString()
,因为SDO_GEOMETRY无法转换为字符串。说实话,我不了解oracleDB,所以这只是猜测。
您是否尝试过getInt()
或getByteArray()
或类似选项?
从数据库获取数据时有很多可能性。