iris 数据库配置及连接方法封装

2023年 8月 13日 88.5k 0

iris 数据库配置及连接方法封装

上一节讲完项目结构 & 生成数据表映射之后,接下来就是项目连接数据库操作数据库的代码封装:

连接数据库配置

数据库配置的主要目的就是为了把 Golang 链接数据库链接

"[User]:[Pwd]@tcp([Host]:[Port])/[DbName]?charset=[DbCharset]"

中的各项参数,变成结构体可标准配置。比如:

    type DbConf struct { Host string Port int User string Pwd string DbName string DbCharset string}

    工业项目一般都涉及多人开发,开发维护的时候为了统一管理。开发组内都会有自己的代码标准,所以这也是项目需要这配置那配置的配置化原因

    真正链接数据库的时候,使用fmt格式化输出函数,就可以轻易获得链接数据库链接

      const DriverName = "mysql"var MasterDbConf DbConf = DbConf{ Host : "127.0.0.1", Port : 3306, User : "root", Pwd : "", DbName : "superstar", DbCharset: "utf8",}conf := MasterDbConfdriverSource := fmt.Sprintf( "%s:%s@tcp(%s:%d)/%s?charset=%s", c.User, c.Pwd, c.Host, c.Port, c.DbName, c.DbCharset)fmt.Println(driverSource)masterEngine, err := xorm.NewEngine(conf.DriverName, driverSource)if err != nil { log.Fatal("dbhelper.DbInstanceMaster err:", err) return nil}

      配置可以不只一份,比如主从配置,读写分离。数据同步交给数据库主从同步,读取数据xorm.NewEngine注意使用从库配置即可:

        var SlaveDbConf DbConf = DbConf{ Host : "127.0.0.1", Port : 3306, User : "root", Pwd : "", DbName : "superstar", DbCharset: "utf8",}

        到了实操阶段,我们在项目根目录下的conf文件夹建db.go文件:

        conf/db.go

          package confconst DriverName = "mysql"type DbConf struct { Host string Port int User string Pwd string DbName string}var MasterDbConf DbConf = DbConf{ Host : "127.0.0.1", Port : 3306, User : "root", Pwd : "", DbName : "superstar",}var SlaveDbConf DbConf = DbConf{ Host : "127.0.0.1", Port : 3306, User : "root", Pwd : "", DbName : "superstar",}

          连接数据库方法封装

          封装好数据库配置之后,为了使链接数据库方法变得一致,有利于日后统一管理。于是把上面提及的数据库链接方式封装成函数,就能在需要连接数据库时建立新的数据库链接。方便调用:

            package datasourceimport ( "fmt" _ "github.com/go-sql-driver/mysql" "log" "superstar/conf" "sync" "xorm.io/xorm")func InstanceMaster() *xorm.Engine { c := conf.MasterDbConf driverSource := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?", c.User, c.Pwd, c.Host, c.Port, c.DbName) fmt.Println(driverSource) masterEngine, err := xorm.NewEngine(conf.DriverName, driverSource) if err != nil { log.Fatal("dbhelper.DbInstanceMaster err:", err) return nil } return masterEngine}

            但每次操作数据库是,都建立新的数据库链接。不仅浪费数据库连接池资源、还容易在并发高情况下造成无法链接数据库。

            于是我们需要一个数据库链接对象masterEngine,在链接数据库前,检查对象是否为空,不为空就复用数据库链接;为空则重新建立数据库链接:

              func InstanceMaster() *xorm.Engine { if masterEngine != nil { return masterEngine } c := conf.MasterDbConf driverSource := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", c.User, c.Pwd, c.Host, c.Port, c.DbName) fmt.Println(driverSource) masterEngine, err := xorm.NewEngine(conf.DriverName, driverSource) if err != nil { log.Fatal("dbhelper.DbInstanceMaster err:", err) return nil } return masterEngine}

              并发情况下数据库链接

              但这里还有一个问题:

                if masterEngine != nil { return masterEngine}

                如果一下子,进来 10 个请求。第 1 个请求的 masterEngine 没来得及生成,导致后面 9 个请求也需要重复实例化 masterEngine 这种情况也不合理。

                为了避免这种情况,我们在实例化 masterEngine 时加锁:

                  if masterEngine != nil { return masterEngine}lock.Lock()defer lock.Unlock() 后解锁

                  协程情况下数据库链接

                  协程时,上面 10 个请求一起进来,每个都到 lock.Lock() 加锁挂起。等第 1 个请求解锁后,后面 9 个请求也逐个实例化 masterEngine 这种情况也不合理。

                  为了避免这种情况,我在再加锁之后再次 判断 masterEngine 是否已存在:

                    if masterEngine != nil { return masterEngine}lock.Lock()defer lock.Unlock()// 协程时,上面十个一起进来,每个都到 lock.Lock() 加锁挂起。这里避免 个加锁然后创建实例后,每个协程都创建实例if masterEngine != nil { return masterEngine}

                    到了实操阶段,我们在项目根目录下的datasource文件夹建dbhelper.go文件:

                    datasource/dbhelper.go

                      package datasourceimport ( "fmt" _ "github.com/go-sql-driver/mysql" "log" "superstar/conf" "sync" "xorm.io/xorm")// 数据库单例 dbhelper.govar ( masterEngine *xorm.Engine slaveEngine *xorm.Engine lock sync.Mutex)func InstanceMaster() *xorm.Engine { if masterEngine != nil { return masterEngine } lock.Lock() defer lock.Unlock() if masterEngine != nil { return masterEngine } c := conf.MasterDbConf driverSource := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", c.User, c.Pwd, c.Host, c.Port, c.DbName) fmt.Println(driverSource) masterEngine, err := xorm.NewEngine(conf.DriverName, driverSource) if err != nil { log.Fatal("dbhelper.DbInstanceMaster err:", err) return nil } // DEBUG 模式,打印全部sql, 帮助对比 orm 与 sql 执行对照关系 masterEngine.ShowSQL(false) masterEngine.SetTZLocation(conf.SysTimeLocation) return masterEngine}

                      相关文章

                      Golang中的错误处理:使用context包处理请求超时错误

                      2023-08-07
                      请求
                      错误
                      超时

                      SQL数据库触发器语法详解 (sql数据库触发器语法)

                      2023-08-06
                      数据库
                      语法
                      触发器

                      快速简单的删除Oracle数据库字段方法 (删除oracl数据库字段)

                      2023-08-06
                      数据库
                      字段
                      删除

                      如何打开社工数据库bak文件 (社工数据库bak怎么打开)

                      2023-08-06
                      数据库
                      打开
                      社工

                      实现数据库按拼音排序的方法和技巧 (数据库按拼音排序)

                      2023-08-06
                      数据库
                      排序
                      按拼音

                      探究Sybase数据库的性能和功能特点 (sybase数据库怎么样)

                      2023-08-06
                      数据库
                      性能
                      探究

                      SQL Server 如何成功建立自己的数据库? (sql server 建立数据库)

                      2023-08-06
                      数据库
                      自己的
                      建立

                      如何在Oracle中查看数据库触发器? (oracle查看数据库触发器)

                      2023-08-06
                      数据库
                      查看
                      触发器

                      数据库表数据量千万级,对性能影响有多大? (数据库表千万级数据量多吗)

                      2023-08-06
                      数据库
                      级数
                      有多大

                      如何使用Oracle按时间导出表数据库? (oracle按时间导出表数据库)

                      2023-08-06
                      数据库
                      导出
                      如何使用

                      数据库存储:帖子长期保存,信息永不丢失 (帖子存数据库)

                      2023-08-06
                      数据库
                      丢失
                      帖子

                      小米六数据库:全方位数据保障和优化方案 (小米六数据库)

                      2023-08-05
                      数据库
                      优化
                      小米

                      简易教程:使用dbe数据库实现数据连接 (dbe数据库 数据连接)

                      2023-08-05
                      数据
                      数据库
                      连接

                      Oracle实现多个数据库链接的简便方法 (oracle链接多个数据库)

                      2023-08-05
                      数据库
                      多个
                      链接

                      数据库索引:用哪种方法建立? (数据库索引用什么建的)

                      2023-08-05
                      索引
                      数据库
                      哪种

                      实现高效缓存同步:Redis数据库技巧大全 (redis 数据库缓存同步)

                      2023-08-05
                      数据库
                      缓存
                      同步

                      如何利用数据库实现高效的模糊匹配查询? (数据库实现模糊查询)

                      2023-08-05
                      查询
                      数据库
                      模糊

                      数据库有哪些安装方式和位置? (数据库是装在什么上)

                      2023-08-05
                      数据库
                      位置
                      装在

                      Lactmed数据库:妈妈们必备的喂养指南 (lactmed 数据库)

                      2023-08-05
                      数据库
                      必备
                      喂养

                      数据库设计中的主属性定义及作用 (数据库主属性是什么)

                      2023-08-05
                      数据库
                      定义
                      属性

                      相关文章

                      Oracle如何使用授予和撤销权限的语法和示例
                      Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
                      下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
                      社区版oceanbase安装
                      Oracle 导出CSV工具-sqluldr2
                      ETL数据集成丨快速将MySQL数据迁移至Doris数据库

                      发布评论