環境需求
- Oracle 8.0+ (含 Spatial 選項)
- JDBC Thin Driver (
ojdbc*.jar)
- Spatial Java API (
sdoapi.jar)
表結構
CREATE TABLE POISDO (
ID INTEGER PRIMARY KEY,
GNAME VARCHAR2(256),
GSHAPE MDSYS.SDO_GEOMETRY
);
CREATE SEQUENCE SEQ_POI_ID;
Java 完整程式碼
import java.sql.*;
import oracle.sql.*;
import oracle.spatial.geometry.JGeometry;
public class SdoAdd {
public static void main(String[] args) {
String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@172.16.75.200:1521:starmap";
String uid = "hmbst";
String psw = "hmbst";
Connection conn = null;
PreparedStatement ps = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, uid, psw);
// 1. 建立 JGeometry 物件 (點: X, Y, SRID=0 表示無座標系)
JGeometry jGeom = new JGeometry(41884696, 14377039, 0);
// 2. 轉換為 Oracle STRUCT (含 SDO_GTYPE, SDO_SRID, SDO_POINT, SDO_ELEM_INFO, SDO_ORDINATES)
STRUCT obj = JGeometry.store(jGeom, conn);
// 3. 參數化插入
String sql = "INSERT INTO POISDO VALUES (SEQ_POI_ID.NEXTVAL, ?, ?)";
ps = conn.prepareStatement(sql,
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
ps.clearParameters();
ps.setString(1, "我的家"); // GNAME
ps.setObject(2, obj); // GSHAPE (STRUCT)
ps.executeUpdate();
conn.commit();
System.out.println("空間資料插入成功");
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (ps != null) try { ps.close(); } catch (SQLException e) { e.printStackTrace(); }
if (conn != null) try { conn.close(); } catch (SQLException e) { e.printStackTrace(); }
}
}
}
關鍵點解析
- JGeometry 建構子:
new JGeometry(x, y, srid) 建立點;多邊形/線串請用 JGeometry.createPolygon/LineString。
- JGeometry.store():將 Java 物件序列化為 Oracle
STRUCT,自動填充 SDO_GTYPE=2001 (點)、SDO_POINT 等屬性。
- PreparedStatement.setObject():直接傳遞
STRUCT,驅動處理型別映射。
- SRID:生產環境務必指定正確 SRID (如 8307=WGS84),並對
GSHAPE 建立空間索引 (CREATE INDEX ... INDEXTYPE IS MDSYS.SPATIAL_INDEX)。
常見錯誤排查
| 錯誤 | 原因 | 解決 |
| ClassNotFoundException: JGeometry | 缺少 sdoapi.jar | 加入 Classpath ($ORACLE_HOME/md/jlib/sdoapi.jar) |
| ORA-29875: 執行例程失敗 | 空間索引未建立或 SRID 不匹配 | 建立空間索引、確認 SRID 一致 |
| Invalid SRID | JGeometry 建構子傳入 0 | 改為有效 SRID (如 8307) |
總結
新 Spatial Java API (JGeometry) 封裝了複雜的 SDO_GEOMETRY 結構,開發者只需操作幾何物件,再透過 store() 轉 STRUCT 寫入,大幅降低空間資料開發門檻。
- 上一篇文章: Oracle RAC 狀態檢查利器:crs_stat 完整用法指南
- 下一篇文章: Oracle 優化器選擇指南:RULE、COST、CHOOSE 三模式深度解析與最佳實踐
Copyright ©
程式碼之家 All Rights Reserved