背景:
近期学习了一下Go-Admin开源项目,里面的亮点就是可以自动配置化实现数据库的增删改查工作,然后自己看了一下源码其实实现原理很简单,就是采用IO流实现文件的创建和更新工作。里面主要就是根据模板语言的数据交互,这样就会实现按照不同的数据生成不同的文件:
下面以一个很简单的实例进行解析实现的原理:
步骤:
首先就是要撰写模板文件:文件名为 test1.template ,模板语言就是采用{{.}}的形式进行数据的交互,后台数据要传输的类型为map类型。
package test
import (
"fmt"
"testing"
)
var Data string
var Package string
func _{{.DataString}}Init() {
Data = strconv.FormatInt({{.DataString}}, 10)
Package = "{{.Package}}"
fmt.Println("当前版本:",Package )
}
func Test111(t *testing.T) {
_{{.DataString}}Init()
fmt.Println("当前时间:", Data)
}
然后就是写的测试代码:实现原理就是在用template包的读取模板文件得到模板对象,然后就是创建map对象,里面传输模板文件中需要的数据,按照上面的情况应该是就是Package和DataString两个变量。接着就是执行t1.Execute()将map数据传入到字节流b1中,最后就是执行文件创建创建和更新逻辑以及字节流的输入。
/**
* @Author GCG
* @Description: 功能描述(按照需求生成模板文件)
* @Date : 2020/12/7
*/
func Test0(t *testing.T) {
// template.ParseFiles实现模板文件的创建
t1, err := template.ParseFiles("conf/test1.template")
if err != nil {
panic(err)
}
m := map[string]string{}
m["Package"] = "test"
//纳秒转毫秒时间戳
m["DataString"] = strconv.FormatInt(time.Now().UnixNano()/1e6, 10)
var b1 bytes.Buffer
//将上面获得的模板数据进行相关的数据绑定(即将m中数据输入到字节流中)
err = t1.Execute(&b1, m)
FileCreate(b1, "./autogeneration_test.go")
}
// 创建文件并且将模板数据写入到新文件中
func FileCreate(content bytes.Buffer, name string) {
file, err := os.Create(name)
if err != nil {
fmt.Println("错误异常:", err)
log.Println(err)
}
_, err = file.WriteString(content.String())
if err != nil {
log.Println(err)
}
file.Close()
}
执行后的效果如下:生成如下的文件:
具体代码如下:
package test
import (
"fmt"
"strconv"
"testing"
)
var Data string
var Package string
func _1607309784637Init() {
Data = strconv.FormatInt(1607309784637, 10)
Package = "test"
fmt.Println("当前版本:", Package)
}
func Test111(t *testing.T) {
_1607309784637Init()
fmt.Println("当前时间:", Data)
}
最后测试一下生成的代码: (完美的可以使用,)
GOROOT=D:\Go #gosetup
GOPATH=E:\Gopath;E:\Develop\gowork;E:\GITwork\ginWork #gosetup
D:\Go\bin\go.exe test -c -o C:\Users\gree\AppData\Local\Temp\___Test111_in_test_test.exe test/test #gosetup
D:\Go\bin\go.exe tool test2json -t C:\Users\gree\AppData\Local\Temp\___Test111_in_test_test.exe -test.v -test.run ^Test111$ #gosetup
log.level:INFO
=== RUN Test111
当前版本: test
当前时间: 1607309784637
--- PASS: Test111 (0.00s)
PASS
Process finished with exit code 0
注意事项:
模板语言中{{.DataString}}及时你传输的是字符串,他会直接将结果输出到生成文件中,所以如果要是赋值给一个变量的话需要直接用““号括起来:
例如:
Package = "{{.Package}}" fmt.Println("当前版本:",Package )
这样就是可以实现变量的转换了,否则会报错,(大家可以尝试一下,如果有更好的方式可以互相交流)