package main
import (
"github.com/ying32/govcl/vcl"
"github.com/ying32/govcl/vcl/types"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"strings"
"text/template"
)
const (
JavaEntityTplPath = "template/java_entity.tpl"
JavaMapperTplPath = "template/java_mapper.tpl"
JavaMapperXmlTplPath = "template/java_mapper_xml.tpl"
JavaServiceTplPath = "template/java_service.tpl"
JavaControllerTplPath = "template/java_controller.tpl"
)
var JavaTemplateFiles = [5]string{JavaEntityTplPath, JavaMapperTplPath, JavaMapperXmlTplPath, JavaServiceTplPath, JavaControllerTplPath}
// 创建java代码生成页面
func (f *MainForm) createGenJavaFrame(index int) {
var (
genTables *vcl.TLabeledEdit
basePath *vcl.TLabeledEdit
basePackage *vcl.TLabeledEdit
genModules *vcl.TLabeledEdit
genModuleList = [5]string{"entity", "mapper", "mapperXml", "service", "controller"}
)
// 创建容器
f.ContentFrame[index] = vcl.NewFrame(f)
f.ContentFrame[index].SetParent(f)
f.ContentFrame[index].SetAlign(types.AlClient)
f.ContentFrame[index].SetColor(ContentColor)
var top int32 = CommonPadding
// 数据源列表
dataSourcesLabel := vcl.NewLabel(f)
dataSourcesLabel.SetParent(f.ContentFrame[index])
dataSourcesLabel.SetBounds(Custom5LabelPadding, top+LabelFix, FormLabelWidth, FormItemHeight)
dataSourcesLabel.SetCaption("选择数据源")
f.JavaGenDataSources = vcl.NewComboBox(f)
f.JavaGenDataSources.SetParent(f.ContentFrame[index])
f.JavaGenDataSources.SetBounds(FormLabelWidth+CommonPadding, top, FormEditWidth, Empty)
f.JavaGenDataSources.SetStyle(types.CsDropDownList)
f.JavaGenDataSources.SetOnSelect(func(sender vcl.IObject) {
GenJavaCurrentIndex = f.JavaGenDataSources.ItemIndex()
if GenJavaConfigs != nil && GenJavaCurrentIndex <= int32(len(GenJavaConfigs)-1) {
vcl.ThreadSync(func() {
basePath.SetText(GenJavaConfigs[GenJavaCurrentIndex].BasePath)
basePackage.SetText(GenJavaConfigs[GenJavaCurrentIndex].BasePackage)
genModules.SetText(GenJavaConfigs[GenJavaCurrentIndex].GenModules)
})
}
})
refreshDataSources := vcl.NewButton(f)
refreshDataSources.SetParent(f.ContentFrame[index])
refreshDataSources.SetBounds(f.JavaGenDataSources.Left()+f.JavaGenDataSources.Width()+CommonPadding, top, FormButtonWidth, FormItemHeight)
refreshDataSources.SetCaption("刷新数据源")
refreshDataSources.SetOnClick(func(sender vcl.IObject) {
GetConfigs(0)
GetConfigs(1)
vcl.ThreadSync(func() {
f.JavaGenDataSources.Items().Clear()
for _, dataSourceConfig := range DataSourceConfigs {
f.JavaGenDataSources.Items().Add(dataSourceConfig.DataSourceName)
}
GenJavaCurrentIndex = -1
genTables.Clear()
basePath.Clear()
basePackage.Clear()
genModules.Clear()
})
})
// 选择数据表
top += CommonPadding + FormItemHeight
genTables = vcl.NewLabeledEdit(f)
genTables.SetParent(f.ContentFrame[index])
genTables.SetBounds(FormLabelWidth+CommonPadding, top, FormEditWidth, Empty)
genTables.SetLabelPosition(types.LpLeft)
genTables.SetLabelSpacing(CommonPadding)
genTables.EditLabel().SetCaption("选择数据表")
genTables.SetReadOnly(true)
chooseGenTables := vcl.NewButton(f)
chooseGenTables.SetParent(f.ContentFrame[index])
chooseGenTables.SetBounds(genTables.Left()+genTables.Width()+CommonPadding, top, FormButtonWidth, FormItemHeight)
chooseGenTables.SetCaption("选择")
chooseGenTables.SetOnClick(func(sender vcl.IObject) {
if GenJavaCurrentIndex == -1 {
vcl.ShowMessage("未选择数据源")
return
}
// 创建新的窗口展示数据
tablesForm := vcl.NewForm(f)
tablesForm.SetCaption("选择数据库表")
tablesForm.SetPosition(types.PoMainFormCenter)
tablesForm.SetWidth(250)
tablesForm.SetHeight(400)
// 数据库表列表
tablesChkListBox := vcl.NewCheckListBox(tablesForm)
tablesChkListBox.SetParent(tablesForm)
tablesChkListBox.SetAlign(types.AlClient)
go func() {
if err, tables := GetTables(DataSourceConfig{
DataSourceUrl: DataSourceConfigs[GenJavaCurrentIndex].DataSourceUrl,
DatabaseName: DataSourceConfigs[GenJavaCurrentIndex].DatabaseName,
DatabaseUsername: DataSourceConfigs[GenJavaCurrentIndex].DatabaseUsername,
DatabasePassword: DataSourceConfigs[GenJavaCurrentIndex].DatabasePassword,
}); err != nil {
vcl.ShowMessage("获取数据表信息失败" + LineBreak + err.Error())
tablesForm.Close()
} else {
// 切换到主线程更新UI
vcl.ThreadSync(func() {
// 渲染数据库表列表
for i := 0; i < len(tables); i++ {
tablesChkListBox.Items().Add(tables[i])
}
})
}
}()
selectAllBtn := vcl.NewButton(tablesForm)
selectAllBtn.SetParent(tablesForm)
selectAllBtn.SetCaption("全选")
selectAllBtn.SetAlign(types.AlBottom)
selectAllBtn.SetOnClick(func(sender vcl.IObject) {
tablesChkListBox.CheckAll(types.CbChecked, true, true)
})
deselectAllBtn := vcl.NewButton(tablesForm)
deselectAllBtn.SetParent(tablesForm)
deselectAllBtn.SetCaption("取消全选")
deselectAllBtn.SetAlign(types.AlBottom)
deselectAllBtn.SetOnClick(func(sender vcl.IObject) {
tablesChkListBox.CheckAll(types.CbUnchecked, true, true)
})
confirmBtn := vcl.NewButton(tablesForm)
confirmBtn.SetParent(tablesForm)
confirmBtn.SetCaption("确定")
confirmBtn.SetAlign(types.AlBottom)
confirmBtn.SetOnClick(func(sender vcl.IObject) {
tablesForm.Close()
})
tablesForm.Show()
tablesForm.SetOnClose(func(sender vcl.IObject, action *types.TCloseAction) {
tables := ""
tablesChk := strings.Split(tablesChkListBox.Items().Text(), LineBreak)
for i, tableName := range tablesChk {
if len(tableName) > 0 && tablesChkListBox.Checked(int32(i)) {
tables += tableName + Separator
}
}
vcl.ThreadSync(func() {
genTables.SetText(tables)
})
})
})
// 生成位置
top += CommonPadding + FormItemHeight
basePath = vcl.NewLabeledEdit(f)
basePath.SetParent(f.ContentFrame[index])
basePath.SetBounds(FormLabelWidth+CommonPadding, top, FormEditWidth, Empty)
basePath.SetLabelPosition(types.LpLeft)
basePath.SetLabelSpacing(CommonPadding)
basePath.EditLabel().SetCaption("生成位置")
basePath.SetReadOnly(true)
chooseBasePath := vcl.NewButton(f)
chooseBasePath.SetParent(f.ContentFrame[index])
chooseBasePath.SetBounds(basePath.Left()+basePath.Width()+CommonPadding, top, FormButtonWidth, FormItemHeight)
chooseBasePath.SetCaption("选择")
chooseBasePath.SetOnClick(func(sender vcl.IObject) {
if ok, dir := vcl.SelectDirectory1(0); ok {
basePath.SetText(dir)
}
})
// 生成包名
top += CommonPadding + FormItemHeight
basePackage = vcl.NewLabeledEdit(f)
basePackage.SetParent(f.ContentFrame[index])
basePackage.SetBounds(FormLabelWidth+CommonPadding, top, FormEditWidth, Empty)
basePackage.SetLabelPosition(types.LpLeft)
basePackage.SetLabelSpacing(CommonPadding)
basePackage.EditLabel().SetCaption("生成包名")
// 生成类型
top += CommonPadding + FormItemHeight
genModules = vcl.NewLabeledEdit(f)
genModules.SetParent(f.ContentFrame[index])
genModules.SetBounds(FormLabelWidth+CommonPadding, top, FormEditWidth, Empty)
genModules.SetLabelPosition(types.LpLeft)
genModules.SetLabelSpacing(CommonPadding)
genModules.EditLabel().SetCaption("选择模块名")
genModules.SetReadOnly(true)
chooseGenModules := vcl.NewButton(f)
chooseGenModules.SetParent(f.ContentFrame[index])
chooseGenModules.SetBounds(genModules.Left()+genModules.Width()+CommonPadding, top, FormButtonWidth, FormItemHeight)
chooseGenModules.SetCaption("选择")
chooseGenModules.SetOnClick(func(sender vcl.IObject) {
// 创建新的窗口展示数据
modulesForm := vcl.NewForm(f)
modulesForm.SetCaption("选择模块名")
modulesForm.SetPosition(types.PoMainFormCenter)
modulesForm.SetWidth(250)
modulesForm.SetHeight(250)
// 数据库表列表
modulesChkListBox := vcl.NewCheckListBox(modulesForm)
modulesChkListBox.SetParent(modulesForm)
modulesChkListBox.SetAlign(types.AlClient)
for i := 0; i < len(genModuleList); i++ {
modulesChkListBox.Items().Add(genModuleList[i])
}
selectAllBtn := vcl.NewButton(modulesForm)
selectAllBtn.SetParent(modulesForm)
selectAllBtn.SetCaption("全选")
selectAllBtn.SetAlign(types.AlBottom)
selectAllBtn.SetOnClick(func(sender vcl.IObject) {
modulesChkListBox.CheckAll(types.CbChecked, true, true)
})
deselectAllBtn := vcl.NewButton(modulesForm)
deselectAllBtn.SetParent(modulesForm)
deselectAllBtn.SetCaption("取消全选")
deselectAllBtn.SetAlign(types.AlBottom)
deselectAllBtn.SetOnClick(func(sender vcl.IObject) {
modulesChkListBox.CheckAll(types.CbUnchecked, true, true)
})
confirmBtn := vcl.NewButton(modulesForm)
confirmBtn.SetParent(modulesForm)
confirmBtn.SetCaption("确定")
confirmBtn.SetAlign(types.AlBottom)
confirmBtn.SetOnClick(func(sender vcl.IObject) {
modulesForm.Close()
})
modulesForm.Show()
modulesForm.SetOnClose(func(sender vcl.IObject, action *types.TCloseAction) {
modules := ""
modulesChk := strings.Split(modulesChkListBox.Items().Text(), LineBreak)
for i, module := range modulesChk {
if len(module) > 0 && modulesChkListBox.Checked(int32(i)) {
modules += module + Separator
}
}
vcl.ThreadSync(func() {
genModules.SetText(modules)
})
})
})
// 操作按钮
top += CommonPadding + FormItemHeight*2
genHandle := vcl.NewButton(f)
genHandle.SetParent(f.ContentFrame[index])
genHandle.SetBounds(FormLabelWidth+CommonPadding, top, FormButtonWidth, FormItemHeight)
genHandle.SetCaption("生成代码")
genHandle.SetOnClick(func(sender vcl.IObject) {
// 需要检查模板是否存在
for i := 0; i < len(JavaTemplateFiles); i++ {
if !FileExists(JavaTemplateFiles[i]) {
vcl.ShowMessage("模板文件不存在,无法生成代码")
return
}
}
// 没有选择数据源
if GenJavaCurrentIndex == -1 {
vcl.ShowMessage("未选择数据源")
return
}
// 没有选择表
if len(genTables.Text()) == 0 {
vcl.ShowMessage("未选择表")
return
}
// 没有选择模块
if len(genModules.Text()) == 0 {
vcl.ShowMessage("未选择生成模块")
return
}
// 使所有控件都不可用
f.JavaGenDataSources.SetEnabled(false)
refreshDataSources.SetEnabled(false)
chooseGenTables.SetEnabled(false)
chooseBasePath.SetEnabled(false)
basePackage.SetEnabled(false)
chooseGenModules.SetEnabled(false)
// 修改按钮状态
genHandle.SetCaption("生成中")
genHandle.SetEnabled(false)
// 更新或者保存当前配置
basePathText := basePath.Text()
basePackageText := basePackage.Text()
genModulesText := genModules.Text()
exist := false
for i := range GenJavaConfigs {
if GenJavaConfigs[i].DataSourceName == DataSourceConfigs[GenJavaCurrentIndex].DataSourceName {
exist = true
GenJavaConfigs[i].BasePath = basePathText
GenJavaConfigs[i].BasePackage = basePackageText
GenJavaConfigs[i].GenModules = genModulesText
}
}
if !exist {
genJavaConfig := GenJavaConfig{
DataSourceName: DataSourceConfigs[GenJavaCurrentIndex].DataSourceName,
BasePath: basePathText,
BasePackage: basePackageText,
GenModules: genModulesText,
}
GenJavaConfigs = append(GenJavaConfigs, genJavaConfig)
}
// 执行操作
go func() {
// 生成代码
tableList := strings.Split(genTables.Text(), Separator)
// 遍历表查询字段信息
for _, tableName := range tableList {
if len(tableName) == 0 {
continue
}
fields := GetFields(tableName, DataSourceConfig{
DataSourceUrl: DataSourceConfigs[GenJavaCurrentIndex].DataSourceUrl,
DatabaseName: DataSourceConfigs[GenJavaCurrentIndex].DatabaseName,
DatabaseUsername: DataSourceConfigs[GenJavaCurrentIndex].DatabaseUsername,
DatabasePassword: DataSourceConfigs[GenJavaCurrentIndex].DatabasePassword,
})
if err := GenJava(basePathText, basePackageText, tableName, fields); err != nil {
vcl.ThreadSync(func() {
vcl.ShowMessage(err.Error())
})
break
}
}
// 保存配置
SaveConfigs(1)
vcl.ThreadSync(func() {
vcl.ShowMessage("生成代码完毕")
// 使所有控件可用
f.JavaGenDataSources.SetEnabled(true)
refreshDataSources.SetEnabled(true)
chooseGenTables.SetEnabled(true)
chooseBasePath.SetEnabled(true)
basePackage.SetEnabled(true)
chooseGenModules.SetEnabled(true)
// 修改按钮状态
genHandle.SetCaption("生成代码")
genHandle.SetEnabled(true)
})
}()
})
openDirHandle := vcl.NewButton(f)
openDirHandle.SetParent(f.ContentFrame[index])
openDirHandle.SetBounds(genHandle.Left()+genHandle.Width()+CommonPadding, top, FormButtonWidth, FormItemHeight)
openDirHandle.SetCaption("打开目录")
openDirHandle.SetOnClick(func(sender vcl.IObject) {
if len(basePackage.Text()) == 0 {
vcl.ShowMessage("未选择目录")
return
}
_ = exec.Command(`cmd`, `/c`, `explorer`, basePackage.Text()).Start()
})
}
func (f *MainForm) renderGenJavaFrame() {
if len(DataSourceConfigs) == 0 {
GetConfigs(0)
}
if len(GenJavaConfigs) == 0 {
GetConfigs(1)
}
vcl.ThreadSync(func() {
f.JavaGenDataSources.Items().Clear()
if len(DataSourceConfigs) > 0 {
for _, dataSourceConfig := range DataSourceConfigs {
f.JavaGenDataSources.Items().Add(dataSourceConfig.DataSourceName)
}
// 需要有一个默认选择
if GenJavaCurrentIndex >= 0 {
f.JavaGenDataSources.SetItemIndex(ListDefaultIndex)
}
}
})
}
// 具体生成代码的执行类
func GenJavaRun(filePath string, tplData []byte, data *map[string]interface{}) error {
var (
err error
tmpl *template.Template
file *os.File
)
if err = os.MkdirAll(filepath.Dir(filePath), 0755); err != nil {
return err
}
if file, err = os.OpenFile(filePath, os.O_CREATE, 0755); err != nil {
return err
}
defer func() {
_ = file.Close()
}()
if tmpl, err = template.New(TemplateName).Funcs(template.FuncMap{
"SmallCamelString": SmallCamelString,
"BigCamelString": BigCamelString,
"MySQLToMybatisType": MySQLToMybatisType,
"EntityExclude": EntityExclude,
}).Delims("${", "}").Parse(string(tplData)); err != nil {
return err
}
if err = tmpl.Execute(file, data); err != nil {
return err
}
return nil
}
// 生成java代码
func GenJava(basePath, basePackageName, tableName string, fields []Field) error {
var (
filePath string
tplData []byte
)
if !strings.HasSuffix(basePackageName, ".") {
basePackageName = basePackageName + "."
}
camelTableName := BigCamelString(tableName)
// 获取文件路径
filePath = filepath.Join(basePath, tableName)
data := map[string]interface{}{
"BasePackageName": basePackageName,
"PackageName": tableName,
"TableName": tableName,
"Fields": fields,
}
// 生成entity代码
tplData, _ = ioutil.ReadFile(JavaEntityTplPath)
if err := GenJavaRun(filepath.Join(filePath, "entity", camelTableName+".java"), tplData, &data); err != nil {
return err
}
// 生成Mapper代码
tplData, _ = ioutil.ReadFile(JavaMapperTplPath)
if err := GenJavaRun(filepath.Join(filePath, "mapper", camelTableName+"Mapper.java"), tplData, &data); err != nil {
return err
}
// 生成Mapper的Xml代码
tplData, _ = ioutil.ReadFile(JavaMapperXmlTplPath)
if err := GenJavaRun(filepath.Join(filePath, "mapper", "xml", camelTableName+"Mapper.xml"), tplData, &data); err != nil {
return err
}
// 生成service代码
tplData, _ = ioutil.ReadFile(JavaServiceTplPath)
if err := GenJavaRun(filepath.Join(filePath, "service", camelTableName+"Service.java"), tplData, &data); err != nil {
return err
}
// 生成controller代码
tplData, _ = ioutil.ReadFile(JavaControllerTplPath)
if err := GenJavaRun(filepath.Join(filePath, "controller", camelTableName+"Controller.java"), tplData, &data); err != nil {
return err
}
return nil
}
一键复制
编辑
Web IDE
原始数据
按行查看
历史