main
GORM Oracle Driver
基于 go-ora 实现的 GORM Oracle 数据库驱动,内置版本感知能力、驱动抽象层(go-ora / godror 可切换)、自定义回调体系(INSERT/UPDATE/DELETE/QUERY)与完整测试套件。
特性
- 版本感知:自动识别 Oracle 数据库版本,按版本适配 SQL 语法与类型
- 12c+:原生
IDENTITY列、OFFSET / FETCH分页、DEFAULT <seq>.NEXTVAL - 11g:自动创建序列 +
BEFORE INSERT触发器模拟自增,分页改写为ROWNUM - 21c+:原生
BOOLEAN列类型(更早版本用NUMBER(1)模拟) - 23ai:支持
VECTOR类型(AI Vector Search) - 12c+(Extended):
VARCHAR2支持最大 32k 字节,超出自动降级为CLOB
- 12c+:原生
- 驱动抽象层(
driver_adapter):统一 go-ora(纯 Go)与 godror(基于 ODPI-C)的差异,通过Config.DriverType一键切换 - 自定义回调体系:
INSERT ... RETURNING INTO:支持默认值/自增字段回填,批量插入逐行执行保证一致性与返回值正确性ON CONFLICT→MERGE INTO:自动改写为 OracleMERGE语法- 单行
UPDATE/DELETE ... RETURNING INTO - WHERE 安全检查:无有效 WHERE 条件时拒绝执行
UPDATE/DELETE,避免全表误操作(软删除条件除外) - 软删除支持
- 数据迁移(Migrator):
- 表/列/索引/约束的增删改查,列名大小写自动映射(Oracle 返回大写列名)
- 从数据字典(
USER_TAB_COLUMNS)获取真实数据类型,避免 AutoMigrate 误判触发多余 ALTER - Oracle 不支持原生
ON UPDATE外键操作,自动生成触发器模拟CASCADE/SET NULL - Oracle 保留字自动加引号
- 命名策略统一转换为大写
环境要求
- Oracle 11g、12c 及以上(支持 21c、23ai 等新版本)
- Golang 1.22+
- GORM v1.31.2+
- 底层驱动默认使用 go-ora v2(纯 Go 实现,无需安装 ODPI-C)
安装
go get git.charlienet.top/go/oracle
快速开始
import (
"gorm.io/gorm"
oracle "git.charlienet.top/go/oracle"
)
func main() {
dsn := "oracle://user:password@127.0.0.1:1521/XE?SSL=false"
db, err := gorm.Open(oracle.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
// do something...
}
DSN 格式
DSN 使用 go-ora 的 URL 格式:
oracle://user:password@host:port/service?SSL=false&CONNECTION TIMEOUT=90&SOCKET TIMEOUT=90
常用参数:
SSL:是否启用 TLS 加密CONNECTION TIMEOUT:连接建立超时(秒),go-ora v2.9.0 起该参数只控制连接建立SOCKET TIMEOUT:socket 读写超时(秒),需要读超时保护时配合CONNECTION TIMEOUT一起设置LANGUAGE/TERRITORY:会话语言与地区,如LANGUAGE=SIMPLIFIED+CHINESE&TERRITORY=CHINA
配置项
使用 oracle.New(Config{}) 可获得更多配置能力:
import (
"gorm.io/gorm"
oracle "git.charlienet.top/go/oracle"
"git.charlienet.top/go/oracle/driver_adapter"
)
db, err := gorm.Open(oracle.New(oracle.Config{
DSN: "oracle://user:password@127.0.0.1:1521/XE",
DriverType: driver_adapter.DriverGoOra, // 驱动类型:go-ora(默认)或 godror
SkipQuoteIdentifiers: false, // 是否跳过标识符引用
DBName: "SCOTT", // 指定 Schema(表名将带 Schema 前缀)
// Conn: 传入已存在的 *sql.DB 连接池
}), &gorm.Config{})
| 配置项 | 说明 |
|---|---|
DSN |
连接串 |
DriverType |
底层驱动类型:driver_adapter.DriverGoOra(默认)/ driver_adapter.DriverGodror |
SkipQuoteIdentifiers |
为 true 时不引用标识符 |
DBName |
指定 Schema 名,开启后表名自动带上 SCHEMA.TABLE 前缀 |
Conn |
直接传入已建立的连接池(*sql.DB),此时忽略 DSN |
DefaultStringSize |
字符串字段未指定大小时的默认长度(默认 1024) |
驱动抽象层
driver_adapter 包统一了不同 Oracle 驱动的差异(输出参数、LOB、批量数据、多行 RETURNING 等能力探测),默认使用 go-ora(纯 Go,无需本地依赖)。如需切换到 godror:
- 在代码中显式指定
DriverType: driver_adapter.DriverGodror - 引入 godror 依赖并使用
-tags godror构建(driver_adapter/godror.go受go:build godror约束)
版本适配行为
| 特性 | Oracle 11g | Oracle 12c+ | Oracle 21c+ | Oracle 23ai |
|---|---|---|---|---|
| 自增主键 | 序列 + BEFORE INSERT 触发器 | GENERATED BY DEFAULT AS IDENTITY |
同 12c | 同 12c |
DEFAULT <seq>.NEXTVAL |
建表后创建触发器实现 | 原生 DEFAULT 子句 |
同 12c | 同 12c |
| 分页(Limit/Offset) | ROWNUM 改写 |
OFFSET n ROWS FETCH NEXT n ROWS ONLY |
同 12c | 同 12c |
BOOLEAN 列 |
NUMBER(1) |
NUMBER(1) |
原生 BOOLEAN |
原生 BOOLEAN |
| 超长字符串(>4000) | CLOB |
VARCHAR2(n)(32k) |
同 12c | 同 12c |
VECTOR 类型 |
不支持 | 不支持 | 不支持 | 支持 |
版本通过连接后执行
select version from product_component_version where rownum = 1自动探测,无需手动配置。
常用操作示例
// 创建(自动回填自增主键/默认值字段)
user := User{Name: "Alice", Email: "alice@example.com"}
db.Create(&user) // user.ID 自动回填
// 批量插入
users := []User{{Name: "A"}, {Name: "B"}}
db.Create(&users)
// Upsert(自动改写为 MERGE INTO)
db.Clauses(clause.OnConflict{DoUpdates: clause.AssignmentColumns([]string{"name"})}).
Create(&user)
// 更新(无 WHERE 条件会被拒绝)
db.Model(&User{}).Where("id = ?", 1).Update("name", "Bob")
// 删除(无 WHERE 条件会被拒绝;带 DeletedAt 字段时自动软删除)
db.Delete(&User{}, 1)
db.Unscoped().Delete(&User{}, 1) // 强制物理删除
注意事项与已知限制
UPDATE/DELETE执行了 WHERE 安全检查:缺少有效条件(包括仅有软删除条件)时返回missing WHERE condition错误- Oracle 仅支持单行
RETURNING:多行UPDATE不启用 RETURNING 回填;go-ora 不支持批量INSERT + RETURNING,驱动采用逐行插入保证返回值正确 - 创建表时若关联关系声明了
ON UPDATE CASCADE / SET NULL,驱动会自动生成同名触发器;删除表时需先删除依赖的表或使用CASCADE CONSTRAINTS(已内置) - 11g 下通过序列 + 触发器模拟自增时,触发器和序列按
SEQ_<table>/TRG_<table>命名,删除表会级联清理 - 布尔值在写入时转换为
1/0,读取时转换回 Gobool
测试
tests/ 目录下为集成测试套件(创建、查询、更新、删除、软删除、Hook、迁移、序列、MERGE 等),需要真实的 Oracle 数据库:
ORACLE_DSN="oracle://user:password@host:1521/service" go test ./tests/...
驱动单元测试(无需数据库):
go test ./...
License
见 License。
Description
Languages
Go
100%