環境
- Oracle 8.0+、JDBC Thin Driver (
oracle.jdbc.driver.OracleDriver)
- 需
ojdbc*.jar、sdoapi.jar (Spatial Java API)
表結構
CREATE TABLE poisdo (
id NUMBER,
gname VARCHAR2(256),
gshape MDSYS.SDO_GEOMETRY
);
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 jGeometry = new JGeometry(41884696, 14377039, 0);
// 2. 轉換為 Oracle STRUCT 物件
STRUCT obj = JGeometry.store(jGeometry, conn);
// 3. 準備插入 SQL
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 (SDO_GEOMETRY)
// 4. 執行
ps.executeUpdate();
conn.commit();
System.out.println("Insert success");
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (ps != null) try { ps.close(); } catch (SQLException ignore) {}
if (conn != null) try { conn.close(); } catch (SQLException ignore) {}
}
}
}
關鍵點解析
| 步驟 | 說明 |
JGeometry | 客戶端構建幾何物件(點、線、面、集合),支援 2D/3D、SRID、精度。 |
JGeometry.store() | 將 JGeometry 序列化為 oracle.sql.STRUCT,內含 SDO_GTYPE、SDO_SRID、SDO_POINT、SDO_ELEM_INFO、SDO_ORDINATES。 |
PreparedStatement.setObject() | 綁定 STRUCT 到 SDO_GEOMETRY 欄位,JDBC 驅動自動處理型別映射。 |
| 空間索引 | 插入大量資料後,必須建立空間索引:CREATE INDEX poisdo_idx ON poisdo(gshape) INDEXTYPE IS MDSYS.SPATIAL_INDEX; |
常見問題
ClassNotFoundException: oracle.spatial.geometry.JGeometry → 缺少 sdoapi.jar。
- 插入後查詢
SDO_GEOMETRY 為 NULL → 忘記 conn.commit() 或交易未提交。
- 座標系不匹配 → 確認資料庫
USER_SDO_GEOM_METADATA 登記的 SRID 與插入資料一致。