golang ORM框架实现原理
go自带database/sql和mysql驱动
sqlx/xorm/gorm
beego orm/goframe orm
orm对比
- 相似性
- 各orm支持的数据库都基本相同(主流数据库都支持)
- 支持事务性、链式查询等
- 差异
- xorm、gorose支持批量查询处理
- xorm支持主从式读写分离
- gorm支持热加载
- gorose便于在多个数据库切换
- 文档全面性gorm>xorm>gorose
- 表设计
- 在models包下定义init方法,程序启动后自动调用该方法进行建表操作
- 修改main.go文件,导入models包
- 在orm包下定义连接数据库和建表函数,通过反射获取结构体中的字段,拼接sql
- 导入mysql数据库驱动
- orm设置,设置数据库连接数、日志等,orm.Debug=true,可以看到日志
beego orm
读写锁,反射reflec.value转成interface{}
BoltDB K/V数据库
BoltDB是相当出名的纯Go实现的KV读写引擎, 用户有etcd, consul等.
BoltDB源码相当清晰, 没有黑魔法, 就是经典的B+Tree实现, 在工程中是非常可控的. etcd和consul都用了它, 未必是因为性能有多高而是简单可靠. Raft就是为了稳定, 如果最底层的读写引擎出错, 那就失去了全部意义.
此外B+Tree天然优势, 随机查询比LSMT快, 就不赘述了.
BoltDB支持完全可序列化的ACID事务,让应用程序可以更简单的处理复杂操作。
Golang beego orm源码分析
路径:storage/database/cmd.go
package database
import (
"neuron/base/file"
"neuron/base/log"
"neuron/common/env"
// faceAnalyse "neuron/function/intelli/face/analyse/dsd"
// faceWarn "neuron/function/intelli/face/warn/dsd"
eventlog "neuron/manager/eventlog/dsd"
picture "neuron/storage/picture/dsd"
videofile "neuron/storage/videofile/dsd"
"path"
"github.com/astaxie/beego/orm"
_ "github.com/mattn/go-sqlite3" //数据库驱动
)
var FaceBoltDB *BoltDB
//Init 数据库初始化需要统一处理
func Init() {
log.Info("create database begin...")
orm.Debug = false //数据库SQL语句打印开关
//系统数据库
orm.RegisterModel(new(eventlog.EventLogDbt))
orm.RegisterDriver("sqlite", orm.DRSqlite)
orm.RegisterDataBase("default", "sqlite3", env.DbtSystem)
//存储数据库
storageDirExist, _ := file.PathExists(path.Dir(env.DbtStorage))
if storageDirExist {
orm.RegisterModel(new(picture.PictureFileDbt))
orm.RegisterModel(new(videofile.VideoFileDbt))
orm.RegisterDriver("sqlite", orm.DRSqlite)
orm.RegisterDataBase("storage", "sqlite3", env.DbtStorage)
}
// //结构化数据库
// faceDirExist, _ := file.PathExists(path.Dir(env.DbtFace))
// if faceDirExist {
// orm.RegisterModel(new(faceAnalyse.FaceAnalyseInfoDbt))
// orm.RegisterModel(new(faceWarn.FaceWarnStructDbt))
// orm.RegisterModel(new(faceWarn.FaceWarnLibDbt))
// orm.RegisterModel(new(faceWarn.FaceWarnPicDbt))
// orm.RegisterModel(new(faceWarn.FaceWarnEventDbt))
// orm.RegisterDriver("sqlite", orm.DRSqlite)
// orm.RegisterDataBase("face_info", "sqlite3", env.DbtFace)
// }
orm.RunSyncdb("default", false, true)
if storageDirExist {
orm.RunSyncdb("storage", false, true)
}
// if faceDirExist {
// orm.RunSyncdb("face_info", false, true)
// }
//开启Bolt数据库
FaceBoltDB, _ = Open(env.DbtBolt)
log.Info("create database end...")
}
MDD
1.数据库初始化,orm.Debug = false,sql日志是否打印;
2.orm.RegisterModel 注册model;
if modelCache.done ,panic->RegisterModel must be run before BootStrap,model使用缓存;
modelCache 使用sync.RWMutex,only used outsite for bootStrap 仅在外部用于引导;
RegisterModelWithPrefix ,PrefixOrSuffix表示表名前缀或后缀。isPrefix前缀是前缀还是后缀;
BootStrap(),BootStrap引导模型,解析所有模型,并且不能添加更多模型;
3.orm.RegisterDriver 注册一个数据库驱动,使用指定的驱动名;
4.orm.RegisterDataBase 注册数据库,设置数据库连接参数,使用数据库驱动程序自身的数据源参数;
type DB struct {
*sync.RWMutex
DB *sql.DB
stmtDecorators *lru.Cache
}
*sync.RWMutex ,读写锁读多写少
*sql.DB
type DB struct {
// Atomic access only. At top of struct to prevent mis-alignment
// on 32-bit platforms. Of type time.Duration.
waitDuration int64 // Total time waited for new connections. 等待新连接总时间,原子性访问
connector driver.Connector //驱动连接
// numClosed is an atomic counter which represents a total number of
// closed connections. Stmt.openStmt checks it before cleaning closed
// connections in Stmt.css.
numClosed uint64 //原子计数器,标识关闭连接
mu sync.Mutex // protects following fields
freeConn []*driverConn //释放连接
connRequests map[uint64]chan connRequest
nextRequest uint64 // Next key to use in connRequests.
numOpen int // number of opened and pending open connections 已打开和挂起的打开连接数
// Used to signal the need for new connections 用于发出需要新连接的信号
// a goroutine running connectionOpener() reads on this chan and
// maybeOpenNewConnections sends on the chan (one send per needed connection)
// It is closed during db.Close(). The close tells the connectionOpener
// goroutine to exit.
openerCh chan struct{}
closed bool
dep map[finalCloser]depSet
lastPut map[*driverConn]string // stacktrace of last conn's put; debug only 最后一个连接的put的堆栈跟踪;仅调试
maxIdleCount int // zero means defaultMaxIdleConns; negative means 0 零表示defaultMaxIdleConns负值表示0
maxOpen int // <= 0 means unlimited
maxLifetime time.Duration // maximum amount of time a connection may be reused
maxIdleTime time.Duration // maximum amount of time a connection may be idle before being closed
cleanerCh chan struct{}
waitCount int64 // Total number of connections waited for.
maxIdleClosed int64 // Total number of connections closed due to idle count. 由于空闲计数而关闭的连接总数。
maxIdleTimeClosed int64 // Total number of connections closed due to idle time.
maxLifetimeClosed int64 // Total number of connections closed due to max connection lifetime limit.
stop func() // stop cancels the connection opener. 取消连接
}
*lru.Cache 这提供了lru实现固定大小线程安全 LRU 缓存的包。它基于 Groupcache 中的缓存。
5.orm.RunSyncdb RunSyncdb运行Syncdb命令行。名称是指表的别名。默认是“默认”。如果当前错误,强制意味着运行下一个sql。verbose表示是否运行命令时显示所有信息。
// sync database struct command interface. 同步数据库结构命令接口。
// RunSyncdb运行Syncdb命令行。
// name表示表的别名。默认是“默认”。
// force表示如果当前错误,则运行下一条sql。
// verbose表示是否运行命令时显示所有信息。
type commandSyncDb struct {
al *alias
force bool
verbose bool
noInfo bool
rtOnError bool
}
Ubuntu20.04查找文件
find -name "*neu*" #单引号或双引号都可以
vim中查找字段,/ptz 。
相机设备IP冲突或相机设备IP不在同一网段
电脑,2根网线,1台交换机,相机电源12V
- 相机设备网线连交换机,电源通电,172.16.10.68;
- 电脑通过网线连交换机;
- 修改电脑IP与设备在同一网段 ,如172.16.10.12;
- 电脑可以ping通相机设备,登录相机设备修改IP;