基于go,go template的数据层代码生成器,支持生成基于xorm go,spring jpa的数据层代码生成
main.go
package main
import (
"fmt"
"io/ioutil"
"os"
"strings"
"text/template"
"unsafe"
_ "github.com/go-sql-driver/mysql"
"gopkg.in/yaml.v2"
"xorm.io/xorm"
)
const (
selectCurrentDbSql = "SELECT DATABASE()"
allColumnInfoSql = "SELECT * FROM information_schema.columns WHERE table_schema =? ORDER BY table_schema ASC,table_name ASC,ordinal_position ASC"
)
func main() {
config, err := NewConfiguration()
if err != nil {
fmt.Println("can not read configuration file,err:", err)
return
}
engine, err := xorm.NewEngine("mysql", config.Datasource)
if err != nil {
fmt.Println("can not create database engine,err:", err)
return
}
currentDb := ""
if _, err := engine.SQL(selectCurrentDbSql).Get(¤tDb); err != nil {
fmt.Println("can not get current database,err:", err)
return
}
columns := make([]DataColumn, 0)
if err := engine.SQL(allColumnInfoSql, currentDb).Find(&columns); err != nil {
fmt.Println("can not get column information,err:", err)
return
}
tableMap := make(map[string][]DataColumn)
for _, column := range columns {
tableName := column.TableName
if _, ok := tableMap[tableName]; !ok {
tableMap[tableName] = make([]DataColumn, 0)
}
tableMap[tableName] = append(tableMap[tableName], column)
}
funcMap := template.FuncMap{"upperCamelCase": UpperCamelCase, "lowerCamelCase": LowerCamelCase}
t, err := template.New(config.TplName).Funcs(funcMap).ParseFiles(config.TplFile)
if err != nil {
fmt.Println("parse file err:", err)
return
}
os.RemoveAll(config.Output)
for table, columns := range tableMap {
if _, err := os.Stat(config.Output); os.IsNotExist(err) {
os.Mkdir(config.Output, 0777)
os.Chmod(config.Output, 0777)
}
fileSb := new(strings.Builder)
fileSb.WriteString(config.Output)
fileSb.WriteString("/")
if config.Lang == "go" {
fileSb.WriteString(table)
if config.TargetType == "repository" {
fileSb.WriteString("_repository")
}
} else if config.Lang == "java" {
if config.TargetType == "entity" {
fileSb.WriteString(UpperCamelCase(table))
fileSb.WriteString("Entity")
} else if config.TargetType == "model" {
fileSb.WriteString(UpperCamelCase(table))
} else if config.TargetType == "repository" {
fileSb.WriteString(UpperCamelCase(table))
fileSb.WriteString("EntityRepository")
}
}
fileSb.WriteString(".")
fileSb.WriteString(config.Lang)
f, err := os.OpenFile(fileSb.String(), os.O_CREATE|os.O_WRONLY, 0666)
defer f.Close()
if err != nil {
fmt.Println("can not create output file,err:", err)
return
}
if err := t.Execute(f, &Config{TableName: table, Readonly: config.Readonly, PackageName: config.PackageName, Columns: columns}); err != nil {
fmt.Println("There was an error:", err.Error())
}
}
}
type Configuration struct {
Datasource string `yaml:"datasource"`
Lang string `yaml:"lang"`
TargetType string `yaml:"target-type"`
TplName string `yaml:"tpl-name"`
TplFile string `yaml:"tpl-file"`
Readonly bool `yaml:"readonly"`
Output string `yaml:"output"`
SkipTables []string `yaml:"skip-tables"`
SkipColumns []SkipColumn `yaml:"skip-columns"`
TypeMap map[string]string `yaml:"type-map"`
PackageName string `yaml:"package-name"`
}
type SkipColumn struct {
Table string `yaml:"table"`
Column string `yaml:"column"`
}
func NewConfiguration() (*Configuration, error) {
conf := new(Configuration)
data, err := ioutil.ReadFile("config.yml")
if err != nil {
return conf, err
}
err = yaml.Unmarshal(data, &conf)
return conf, err
}
type Config struct {
TableName string
Readonly bool
PackageName string
Columns []DataColumn
}
func (c *Config) PrimaryColumnDataType() string {
for _, column := range c.Columns {
if column.IsPrimary() {
return column.JavaType()
}
}
return ""
}
func (c *Config) HasDelStatus() bool {
for _, column := range c.Columns {
if column.IsDelStatus() {
return true
}
}
return false
}
func (c *Config) HasDecimalType() bool {
for _, column := range c.Columns {
if column.IsDecimalType() {
return true
}
}
return false
}
func (c *Config) HasDateType() bool {
for _, column := range c.Columns {
if column.IsDateType() {
return true
}
}
return false
}
func (c *Config) HasEnterpriseId() bool {
return c.HasColumn("enterprise_id")
}
func (c *Config) HasCode() bool {
return c.HasColumn("code")
}
func (c *Config) HasStat