1.gorm 源码阅读之 schema
2.å¦ä½ç¼è¯arm linuxçgo
3.[灵性编程]GO的源码依赖注入AND自动生成代码
gorm 源码阅读之 schema
深入探讨基于github.com/go-gorm/gorm v1..x的ORM框架,我们将通过代码对比,解析揭示数据映射的源码奥秘。
首先,解析让我们从原始的源码spark源码如何运行MySQL驱动连接代码开始,尝试查询一个user,解析1001源码多少观察两者之间的源码差异。
GORM,解析作为一个高效的源码ORM框架,其核心在于如何巧妙地实现数据字段与结构体的解析映射,这一特性使其在数据库操作方面展现出显著优势。源码
实现这一目标的解析关键,GORM借助反射机制,源码关于本站源码通过Schema结构来建立数据库字段与目标对象间的解析关联。Schema保存了目标对象,源码即user的数据结构,成为数据映射的虚幻源码剖析核心。
在初始化数据库连接阶段,db.Statement的实例并未预先初始化Schema。要深入理解Parse方法的实现逻辑,首先需要掌握与反射相关的安庆源码网基础知识。
参考相关资料,如 xie.infoq.cn/article/...,可以帮助你更好地理解反射的运用。
回到Parse()方法,其核心功能在于通过反射技术,将user结构体中的每一个属性映射到Field中,包括属性名称、索引等关键信息。
当Schema解析完成,接下来的问题是如何将数据库查询结果实际赋值到user实例上。这一过程,巧妙地结合了反射与结构体赋值机制,实现了数据的双向绑定。
å¦ä½ç¼è¯arm linuxçgo
Golangä¹å°±æ¯Goè¯è¨ï¼ç°å¨å·²ç»åè¡å°1.4.1çæ¬äºï¼è¯è¨ç¹æ§ä¼è¶æ§åèåGoogle强大é å±±ä»ä¹çå°±ä¸å¤è¯´äºãGolangçå®æ¹æä¾äºå¤ä¸ªå¹³å°ä¸çäºè¿å¶å®è£ å ï¼éæ¾çæ¯å¹¶é没æåå¸ARMå¹³å°çäºè¿å¶å®è£ å ãARMå¹³å°æ²¡åæ³ç´æ¥ä»å®ç½ä¸è½½äºè¿å¶å®è£ å æ¥å®è£ ï¼å¥½å¨Golangæ¯æ¯æå¤å¹³å°å¹¶ä¸å¼æºçè¯è¨ï¼å æ¤å¯ä»¥éè¿ç´æ¥å¨ARMå¹³å°ä¸ç¼è¯æºä»£ç æ¥å®è£ ãæ´ä¸ªè¿ç¨ä¸»è¦å æ¬ç¼è¯å·¥å ·é ç½®ãè·åGolangæºä»£ç ã设置Golangç¼è¯ç¯å¢åéãç¼è¯ãé ç½®Golangè¡ç¯å¢åéçæ¥éª¤ã
注ï¼æ¬æéç¨æ èæ´¾åæµè¯ï¼å 为æ èæ´¾æ¯åºäºARMå¹³å°çã
1ãç¼è¯å·¥å ·é ç½®
æ®è¯´ä¸ä¸ªçæ¬çgolangç¼è¯å·¥å ·è¦ä½¿ç¨golangèªå·±æ¥åï¼ä½ç®åè¿æ¯ä½¿ç¨Cç¼è¯å·¥å ·çãå æ¤ï¼é¦å è¦é 置好Cç¼è¯å·¥å ·ï¼
1.1 å¨UbuntuæDebianå¹³å°ä¸å¯ä»¥ä½¿ç¨sudo apt-get install gcc libc6-devå½ä»¤å®è£ ï¼æ èæ´¾çRaspBianç³»ç»æ¯åºäºDebianä¿®æ¹çï¼æ以å¯ä»¥ä½¿ç¨è¿ç§æ¹æ³å®è£ ã
1.2 å¨RedHatæCentOS 6å¹³å°ä¸å¯ä»¥ä½¿ç¨sudo yum install gcc libc-develå½ä»¤å®è£ ã
å®è£ å®æåå¯ä»¥è¾å ¥ gcc --versionå½ä»¤éªè¯æ¯å¦æåå®è£ ã
2ãè·ågolangæºä»£ç
2.1 ç´æ¥ä»å®ç½ä¸è½½æºä»£ç å缩å ã
golangå®ç½æä¾golangçæºä»£ç å缩å ï¼å¯ä»¥ç´æ¥ä¸è½½ï¼ææ°ç1.4.1çæ¬æºä»£ç é¾æ¥ï¼/golang/go1.4.1.src.tar.gz
2.2 使ç¨gitå·¥å ·è·åã
golang使ç¨gitçæ¬ç®¡çå·¥å ·ï¼ä¹å¯ä»¥ä½¿ç¨gitè·ågolangæºä»£ç ãæ¨è使ç¨è¿ä¸ªæ¹æ³ï¼å 为以åå¯ä»¥éæ¶è·åææ°çgolangæºä»£ç ã
2.2.1 é¦å 确认ARMå¹³å°ä¸å·²ç»å®è£ äºgitå·¥å ·ï¼å¯ä»¥ä½¿ç¨git --versionå½ä»¤ç¡®è®¤ãä¸è¬linuxå¹³å°é½å®è£ äºgitï¼æ²¡æçè¯å¯ä»¥èªè¡å®è£ ï¼ä¸åå¹³å°çå®è£ æ¹æ³å¯ä»¥åèï¼/download/linux
2.2.2 å éè¿ç¨golangçgitä»åºå°æ¬å°
å¨ç»ç«¯cdå°ä½ æ³è¦å®è£ golangçç®å½ï¼ç¡®ä¿è¯¥ç®å½ä¸æ²¡æå为goçç®å½ãç¶å以ä¸å½ä»¤è·å代ç ä»åºï¼
git clone /go
大éå°åºå¯è½ä¼è·å失败ï¼å¨ä¸ç¿»å¢çæ åµä¸æè¯äºå 次é½æ²¡æåï¼åå 大家é½æçã好å¨googleå·²ç»å°golangä¹æ管å°githubä¸é¢ï¼æ以ä¹å¯ä»¥éè¿ä¸é¢å½ä»¤è·åï¼
git clone /golang/go.git
è§ç½ç»æ åµï¼ä¸è½½å¯è½éè¦ä¸å°æ¶é´ãæ2Mç带宽è±äºå°è¿ä¸¤ä¸ªå°æ¶æä¸è½½å®ï¼è½ç¶æ´ä¸ªé¡¹ç®ä¸è¿å åå = =
ä¸è½½å®æåï¼å¯ä»¥çå°ç®å½ä¸å¤äºä¸ä¸ªgoç®å½ï¼éé¢å³ä¸ºgolangçæºä»£ç ï¼å¨ç»ç«¯ä¸æ§è¡cd goå½ä»¤è¿å ¥è¯¥ç®å½ã
æ§è¡ä¸é¢å½ä»¤æ£åºgo1.4.1çæ¬çæºä»£ç ï¼å 为ç°å¨å·²ç»ææ°ç代ç æ交ä¸å»äºï¼ææ°ç代ç å¯è½ä¸æ¯æ稳å®çï¼
git checkout go1.4.1
è³æ¤ï¼ææ°1.4.1åè¡ççæºä»£ç è·åå®æ¯
3ã设置golangçç¼è¯ç¯å¢åé
主è¦æGOROOTãGOOSãGOARCHãGOARMå个ç¯å¢åééè¦è®¾ç½®ï¼å 解éå个ç¯å¢åéçæä¹ã
3.1 GOROOT
主è¦ä»£è¡¨golangæ ç»æç®å½çè·¯å¾ï¼ä¹å°±æ¯ä¸é¢gitæ£åºçgoç®å½ãä¸è¬å¯ä»¥ä¸ç¨è®¾ç½®è¿ä¸ªç¯å¢åéï¼å 为ç¼è¯çæ¶åé»è®¤ä¼ä»¥goç®å½ä¸srcåç®å½ä¸çall.bashèæ¬è¿è¡æ¶çç¶ç®å½ä½ä¸ºGOROOTçå¼ã为äºä¿é©èµ·è§ï¼å¯ä»¥ç´æ¥è®¾ç½®ä¸ºgoç®å½çè·¯å¾ã
3.2 GOOSåGOARCH
åå«ä»£è¡¨ç¼è¯çç®æ ç³»ç»åå¹³å°ï¼å¯éå¼å¦ä¸ï¼
GOOS GOARCH
darwin
darwin amd
dragonfly
dragonfly amd
freebsd
freebsd amd
freebsd arm
linux
linux amd
linux arm
netbsd
netbsd amd
netbsd arm
openbsd
openbsd amd
plan9
plan9 amd
solaris amd
windows
windows amd
éè¦æ³¨æçæ¯è¿ä¸¤ä¸ªå¼ä»£è¡¨çæ¯ç®æ ç³»ç»åå¹³å°ï¼èä¸æ¯ç¼è¯æºä»£ç çç³»ç»åå¹³å°ãæ èæ´¾çRaspBianæ¯linuxç³»ç»ï¼æ以è¿äºGOOS设置为linuxï¼GOARCH设置为armã
3.3 GOARM
表示使ç¨çæµ®ç¹è¿ç®åå¤çå¨çæ¬å·ï¼åªå¯¹armå¹³å°æç¨ï¼å¯éå¼æ5ï¼6ï¼7ãå¦ææ¯å¨ç®æ å¹³å°ä¸ç¼è¯æºä»£ç ï¼è¿ä¸ªå¼å¯ä»¥ä¸è®¾ç½®ï¼å®ä¼èªå¨å¤æéè¦ä½¿ç¨åªä¸ä¸ªçæ¬ã
æ»ç»ä¸æ¥ï¼å¨æ èæ´¾ä¸è®¾ç½®golangçç¼è¯ç¯å¢åéï¼å¯ç¼è¾$HOME/.bashrcæ件ï¼å¨æ«å°¾æ·»å ä¸é¢å 容ï¼
export GOROOT=ä½ çgoç®å½è·¯å¾
export GOOS=linux
export GOARCH=arm
ç¼è¾å®åä¿åï¼æ§è¡source ~/.bashrcå½ä»¤è®©ä¿®æ¹çæã
4ãç¼è¯æºä»£ç
ç¯å¢åéé ç½®å®æèªåå°±å¯ä»¥å¼å§ç¼è¯æºä»£ç ãå¨goç®å½ä¸çsrcåç®å½ä¸ï¼ä¸»è¦æall.bashåmake.bash两个èæ¬ï¼å¦å¤è¿æ两个all.batåmake.batèæ¬éç¨äºwindowå¹³å°ï¼ãç¼è¯å®é ä¸å°±æ¯æ§è¡å ¶ä¸ä¸ä¸ªèæ¬ï¼ä¸¤è çåºå«å¨äºall.bashå¨ç¼è¯å®æåè¿ä¼æ§è¡ä¸äºæµè¯å¥ä»¶ãå¦æå¸æåªç¼è¯ä¸æµè¯ï¼å¯ä»¥è¿è¡make.bashèæ¬ã使ç¨cdå½ä»¤è¿å ¥goä¸srcç®å½ï¼æ§è¡./all.bashæè ./make.bashå½ä»¤å³å¯å¼å§ç¼è¯ãç±äºç¡¬ä»¶æ åµä¸åï¼ç¼è¯èè´¹çæ¶é´ä¸åãå¨æçBåæ èæ´¾ç¼è¯è¿ç¨è±è´¹äºå°è¿å个å°æ¶ï¼ç¼è¯å®æåæ§è¡çæµè¯å¥ä»¶åè±è´¹äºå·®ä¸å¤ä¸ä¸ªå°æ¶ï¼æ»å ±è±è´¹äºä¸ä¸ªåå°æ¶å·¦å³ã
5ãé ç½®golangè¿è¡ç¯å¢åé
ç¼è¯å®æåï¼goç®å½ä¸ä¼çæbinç®å½ï¼éé¢å°±æ¯goçè¿è¡èæ¬ã为äºä»¥å使ç¨æ¹æ³ï¼å¯ä»¥å°è¿ä¸ªbinè·¯å¾æ·»å å°PATHç¯å¢åéä¸ãåæ ·ç¼è¾~/.bashrcæ件ï¼å 为åé¢è®¾ç½®è¿GOROOTç¯å¢åéæågoç®å½äºï¼æ以åªéè¦å¨æ«å°¾å ä¸
export PATH=$PATH:$GOROOT/bin
ä¿åååæ ·æ§è¡source ~/.bashrcå½ä»¤è®©ç¯å¢åéçæã
è³æ¤ï¼golangæºä»£ç ç¼è¯å®è£ æåãæ§è¡go versionåºè¯¥å°±è½çå°å½ågolangççæ¬ä¿¡æ¯ï¼è¡¨ç¤ºç¼è¯å®è£ æåã
[灵性编程]GO的依赖注入AND自动生成代码
依赖
总结下先有的获取对象依赖方式
比较原始的New,全局global保存
基于反射读取对象的依赖,程序启动时由DI库实例化(代表作dig等)
基于反射读取对象的依赖,编译前生成完整构建函数(代表作wire等)
第一种:最方便,直接快捷,大量依赖时候,但是因为是手动的,容易出现实例顺序非预期,不方便自动测试,mock等。
第二种:因为是启动时反射获取依赖的,需要定义额外的函数给DI系统解析,例如一个结构的注入必须要要额外的代码,非常麻烦,不建议使用
//提供者err:=c.Provide(func(conn*sql.DB)(*UserGateway,*CommentGateway,error){ //...})iferr!=nil{ //...}//使用者err:=c.Invoke(func(l*log.Logger){ //...})iferr!=nil{ //...}第三种,同样是基于反射,所以依然需要一个额外函数(只有配置信息)提供反射信息,生成同名函数,便捷度基本和手动New一致,wire由Google开源
funcInitializeNewGormProvider()*Gorm{ wire.Build(NewGormProvider,InitializeNewConfProvider)returnnil}我的方案原理和wire一样,根据配置信息生成自动构建函数,但是不基于反射,因为反射需要程序是完整的,编译后才读取信息,相对慢,需要每个目录改完手动执行wire.命令(每个目录每次花费1秒等)。
先看一个场景,数据库服务是依赖配置服务,从结构体就能看出来,不需要funcInitializeNewGormProvider()*Gorm{ }函数反射,未了更加准确(防止注入了不需要的内容)添加一个taginject:""和@Bean注解
//@BeantypeGormstruct{ conf*Conf`inject:""`}所以,注入其实是可以直接基于源码的信息都能实现的。
我只要实现一个go代码解析工具,就能生成和wire工具生成相同的代码,因为go源码的关键字和结构实在是太简单了,没有多少语法糖,做一下分词再按语法规则读取源码信息,工具实现比较容易。工具使用php实现(公司都是mac,php环境mac电脑自带,方便使用模版生成go代码)/go-home-admin/home-toolset-php重要是php解析很快,整个项目生成一次都是一秒内
ORM生成代码编写工具后,也可以生成其他辅助代码,例如原始结构,添加@Orm后,自动根据字段信息生成通用代码
//@OrmtypeGormstruct{ Iduint`json:"id"`UserNamestring`json:"user_name"`}逻辑就可以直接使用
u:=&UsersTable{ }data:=u.WhereUserName("test").And(func(table*UsersTable){ table.WhereId(1).OrWhereId(2)}).Or(func(table*UsersTable){ table.WhereId(2).Or(func(table*UsersTable){ table.WhereId(1)})}).Find()//select*formuserswhereuser_name=?and(id=?orid=?)or(id=?or(id=?))utils.Dump(data)作者:程序狗著作权归作者所有。