抽象工厂模式常用于程序适配多种数据库,以达到开放扩展关闭修改的原则。

首先需要有一个思想就是数据库表结构都是固定,但是每种数据库语言存在差异性,因此使用接口规范功能,各种数据库有自己不同的语言实现,业务中也是使用接口操作,运行时根据配置实例化各种数据库实现。好处是增加新的数据库时,只需要用新的数据库语言实现即可,不用修改原来的代码。部署程序时,只需要修改配置即可适配不同的数据库。

一,数据模型(Model层)

myProject/MyORM/Model/User.go
 package Model

 type User struct {
Id int
UID string
LoginName string
PassWord string
} func (t *User) TableName() string {
return "User"
}

myProject/MyORM/Model/Product.go

 package Model

 type Product struct {
Id int
UID string
Name string
Price float64
} func (t *Product) TableName() string {
return "Product"
}

二,接口定义(Interface层)

myProject/MyORM/Data/IUser.go
 package Data

 import (
"myProject/MyORM/Model"
) type IUser interface {
Add(entity *Model.User) bool
Edit(entity *Model.User) Model.User
}

myProject/MyORM/Data/IProduct.go

 package Data

 import (
"myProject/MyORM/Model"
) type IProduct interface {
Add(entity *Model.Product) bool
Edit(entity *Model.Product) Model.Product
}

myProject/MyORM/Data/IProvider.go

♥ 抽象工厂接口

 package Data

 type IProvider interface {
GetUser() IUser
GetProduct() IProduct
}

三,接口实现(DAL层)

♣ 注意:Go语言的接口实现是隐式的,无须让实现接口的类型写出实现了哪些接口。这个设计被称为非侵入式设计。在类型中添加与接口签名一致的方法就可以实现该方法。

1.SQL实现

myProject/MyORM/SqlData/SqlUser.go

 package SqlData

 import (
"fmt"
"myProject/MyORM/Model"
) type SqlUser struct {
} func (p *SqlUser) Add(entity *Model.User) bool {
fmt.Println("sql执行UserAdd")
return true
} func (p *SqlUser) Edit(entity *Model.User) Model.User {
fmt.Println("sql执行UserEdit")
return *entity
}

myProject/MyORM/SqlData/SqlProduct.go

 package SqlData

 import (
"fmt"
"myProject/MyORM/Model"
) type SqlProduct struct {
} func (p *SqlProduct) Add(entity *Model.Product) bool {
fmt.Println("sql执行ProductAdd")
return true
} func (p *SqlProduct) Edit(entity *Model.Product) Model.Product {
fmt.Println("sql执行ProductEdit")
return *entity
}

myProject/MyORM/SqlData/SqlProvider.go

♥ SQL工厂实现

 package SqlData

 import (
"myProject/MyORM/Data"
) type SqlProvider struct {
} func (p *SqlProvider) GetUser() Data.IUser {
return new(SqlUser)
} func (p *SqlProvider) GetProduct() Data.IProduct {
return new(SqlProduct)
}

2.Mysql实现

myProject/MyORM/MysqlData/MysqlUser.go

 package MysqlData

 import (
"fmt"
"myProject/MyORM/Model"
) type MysqlUser struct {
} func (p *MysqlUser) Add(entity *Model.User) bool {
fmt.Println("mysql执行UserAdd")
return true
} func (p *MysqlUser) Edit(entity *Model.User) Model.User {
fmt.Println("mysql执行UserEdit")
return *entity
}

myProject/MyORM/MysqlData/MysqlProduct.go

 package MysqlData

 import (
"fmt"
"myProject/MyORM/Model"
) type MysqlProduct struct {
} func (p *MysqlProduct) Add(entity *Model.Product) bool {
fmt.Println("mysql执行ProductAdd")
return true
} func (p *MysqlProduct) Edit(entity *Model.Product) Model.Product {
fmt.Println("mysql执行ProductEdit")
return *entity
}

myProject/MyORM/MysqlData/MysqlProvider.go

♥ MYSQL工厂实现

 package MysqlData

 import (
"myProject/MyORM/Data"
) type MysqlProvider struct {
} func (p *MysqlProvider) GetUser() Data.IUser {
return new(MysqlUser)
} func (p *MysqlProvider) GetProduct() Data.IProduct {
return new(MysqlProduct)
}

三,业务逻辑(BLL层)

myProject/MyORM/Service/Factory.go

 package Service

 import (
"myProject/MyORM/Data"
"myProject/MyORM/MysqlData"
"myProject/MyORM/SqlData"
)
// 设置配置
const db = "sql" // 简单工厂方法,根据配置加载不同的实现库
func Provider() Data.IProvider {
switch db {
case "sql":
return new(SqlData.SqlProvider)
case "mysql":
return new(MysqlData.MysqlProvider)
default:
panic("无法映射配置的数据库")
}
}

myProject/MyORM/Service/UserService.go

 package Service

 import (
"myProject/MyORM/Data"
"myProject/MyORM/Model"
) type UserService struct {
} var user Data.IUser func init() {
user = Provider().GetUser()
} func (u *UserService) Add(entity *Model.User) bool {
return user.Add(entity)
} func (u *UserService) Update(entity *Model.User) Model.User {
return user.Edit(entity)
}

myProject/MyORM/Service/ProductService.go

 package Service

 import (
"myProject/MyORM/Data"
"myProject/MyORM/Model"
) type ProductService struct {
} var product Data.IProduct func init() {
product = Provider().GetProduct()
} func (p *ProductService) Add(entity *Model.Product) bool {
return product.Add(entity)
} func (p *ProductService) Update(entity *Model.Product) Model.Product {
return product.Edit(entity)
}

四,界面展示(UI层)

myProject/MyORM/main.go

 package main

 import (
"myProject/MyORM/Model"
"myProject/MyORM/Service"
) func main() {
user := &Model.User{
Id: ,
UID: "",
LoginName: "admin",
PassWord: "",
}
userService := new(Service.UserService)
userService.Add(user) product := &Model.Product{
Id: ,
UID: "",
Name: "苹果",
Price: 12.5,
}
productService := new(Service.ProductService)
productService.Update(product)
}

学习Go语言之简易ORM框架的更多相关文章

  1. Django学习(三)---Models(ORM框架)

    1) Django 中Models是与数据库相关的,与数据库相关的代码一般写在 models.py中,Django 支持 sqlite3, MySQL, PostgreSQL等数据库,只需要在sett ...

  2. 基于Torndb的简易ORM

    ============================================================================ 原创作品,同意转载. 转载时请务必以超链接形式 ...

  3. 笔记:学习go语言的网络基础库,并尝试搭一个简易Web框架

    在日常的 web 开发中,后端人员常基于现有的 web 框架进行开发.但单纯会用框架总感觉不太踏实,所以有空的时候还是看看这些框架是怎么实现的会比较好,万一要排查问题也快一些. 最近在学习 go 语言 ...

  4. 十四、EnterpriseFrameWork框架核心类库之简易ORM

    在写本章前先去网上找了一下关于ORM的相关资料,以为本章做准备,发现很多东西今天才了解,所以在这里也对ORM做不了太深入的分析,但还是浅谈一下EFW框架中的设计的简易ORM:文中有一点讲得很有道理,D ...

  5. Android 数据库ORM框架GreenDao学习心得及使用总结<一>

    转: http://www.it165.net/pro/html/201401/9026.html 最近在对开发项目的性能进行优化.由于项目里涉及了大量的缓存处理和数据库运用,需要对数据库进行频繁的读 ...

  6. 【转载】Android开源:数据库ORM框架GreenDao学习心得及使用总结

    转载链接:http://www.it165.net/pro/html/201401/9026.html 最近在对开发项目的性能进行优化.由于项目里涉及了大量的缓存处理和数据库运用,需要对数据库进行频繁 ...

  7. 学习ORM框架—hibernate(三):跟踪持久化对象状态,掌握对象持久化

    准备工作 在上篇博客中学习ORM框架—hibernate(一):初识hibernate,通过简单的实例说明O和R的映射过程.本篇博客将要介绍hibernate中持久化对象的状态,并使用hibernat ...

  8. golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍

    golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍 go语言爬虫框架:gocolly/colly,goquery,colly,chrom ...

  9. go语言,golang学习笔记3 用命令下载框架报错问题解决 设置环境变量

    go语言,golang学习笔记3 用命令下载框架报错问题解决 设置环境变量 下载安装:go get github.com/astaxie/beego 首页 - beego: 简约 & 强大并存 ...

随机推荐

  1. 143.vector模板库

    myvector.h #pragma once #include <initializer_list> #include <iostream> using namespace ...

  2. xBIM 实战02 在浏览器中加载IFC模型文件并设置特效

    系列目录    [已更新最新开发文章,点击查看详细]  在模型浏览器中加载模型后,可以对模型做一些特殊操作.下图是常用的设置. 都是通过 xbim-viewer.js 中的 API 来设置以达到一定的 ...

  3. IEEE Access的模板的问题

    这个模板果然问题还是有一些,比如caption换行得自己改class文件.首先感谢一下CSDN的一位网友的经验https://blog.csdn.net/baidu_21381705/article/ ...

  4. 配置 centos apache 的日志文件为每天保存,在home分区

    /usr/local/apache/bin/rotatelogs 这个执行程序会根据安装方式不同的位置也不同,yum安装的话,路径为:/usr/sbin/rotatelogs 改为: ErrorLog ...

  5. 修改input标签中的placeholder样式

    input::-webkit-input-placeholder { color: #fff !important; } input:-moz-placeholder { color: #fff !i ...

  6. swift 20 - Nested Types

    Nested Types 只是为了方便类型的整合和使用 struct BlackjackCard { // nested Suit enumeration enum Suit: Character { ...

  7. 【BZOJ4005】[JLOI2015]骗我呢

    题意: Alice和Bob在经过了数学的洗礼之后,不再喜欢玩对抗游戏了,他们喜欢玩合作游戏.现在他们有一个n×m的网格,Alice和Bob要在一定规则下往网 格里填数字,Alice和Bob都是聪明绝顶 ...

  8. 【xsy2440】【GDOI2016】疯狂动物城

    感受一下这恐怖的题目长度~~~ 其实题意很裸,但是作为GDOI的一道防AK题,自然有他优秀的地方. 简化题意:给出一棵树,要求支持三个操作: 1.修改点值 2.询问点$x$到$y$之间的一些东东 3. ...

  9. [洛谷P3948]数据结构

    题目大意:有n个数,opt个操作,并给你md.min.max. 每种操作有以下两种:1.给一段区间加一个固定值.2.询问一段区间内满足$min\leq T*i\ mod\ md\leq max$(T是 ...

  10. [转] 经典排序算法 - 基数排序Radix sort

    原理类似桶排序,这里总是需要10个桶,多次使用 首先以个位数的值进行装桶,即个位数为1则放入1号桶,为9则放入9号桶,暂时忽视十位数 例如 待排序数组[62,14,59,88,16]简单点五个数字 分 ...