wxPythonJavaWeb逆向工程实现3.3

同样的配置,是让用户通过界面去勾选简单,还是敲一堆代码?
由于项目越来越多,又都是没什么技术含量的。为了写得更快,这次我顺便把controller层,service层也一并生成了。注解,注入一个都没少。
3.3版本对于文件位置做了一些优化。如下所示,base路径是com包的直接父级路径。
运行效果
主界面

选择数据表

import wx
from pymysql import connect as pyconnect
from os.path import exists as oexist
from os.path import join
from os import makedirs as omkdirs

class myFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self,None,-1,'逆向工程',size=(400,600))
        self.panel = wx.Panel(self)
        self.connect_view()
        self.Center()

    def to_file(self,content, path):# 写入文件
        f = open(join(self.basePath,path), 'w', encoding='utf-8')
        f.write(content)
        f.close()

    def get_field_list(self, table_list):  # 从数据库中读取表结构信息
        reflect_dict = {'tinyint': 'Integer', 'smallint': 'Integer', 'mediumint': 'Integer',
                        'int': 'Integer', 'bigint': 'Integer', 'float': 'Float', 'double': 'Double',
                        'decimal': 'Double', 'date': 'Date', 'time': 'Date',
                        'datetime': 'Date', 'timestamp': 'Date', 'char': 'String',
                        'varchar': 'String', 'tinytext': 'String', 'text': 'String',
                        'mediumtext': 'String', 'longtext': 'String'}
        cursor = self.db_connection.cursor()
        cursor.execute('desc ' + table_list)
        field_list = []
        for i in cursor.fetchall():
            col_name = i[0]
            col_type = i[1].split('(')[0]
            field_name = self.sql_to_camel(col_name)
            field_name = self.first_lower(field_name) # 再过滤一次,防止数据库字段以大写开头
            field_type = reflect_dict[col_type]
            field_list.append((field_type, field_name))
        return field_list

    def sql_to_camel(self,string):  # 下划线形式命名转驼峰式命名
        words = string.split('_')
        name = words[0]
        if len(words) > 1:
            for i in words[1:]:
                name += self.first_upper(i)
        return name

    def first_upper(self,string):  # 字符串首字母大写
        return string[0].upper() + string[1:]

    def first_lower(self,string):
        return string[0].lower() + string[1:]

    def connect_view(self):# 连接数据库视图
        self.label1 = wx.StaticText(self.panel,-1,'用户名:',(50,50))
        self.username = wx.TextCtrl(self.panel,-1,'root',(160,50),(200,25))

        self.label2 = wx.StaticText(self.panel, -1, '密码:',(50,100))
        self.password = wx.TextCtrl(self.panel,-1,'root',(160,100),(200,25))

        self.label3 = wx.StaticText(self.panel, -1, '数据库名:',(50,150))
        self.db = wx.TextCtrl(self.panel, -1,'kh80',(160, 150),(200,25))

        self.label4 = wx.StaticText(self.panel, -1, '实体包:', (50, 200))
        self.pojo = wx.TextCtrl(self.panel, -1, 'com.shy.pojo', (160, 200),(200,25))

        self.label5 = wx.StaticText(self.panel, -1, 'Mapper接口包:', (50, 250))
        self.mapper = wx.TextCtrl(self.panel, -1, 'com.shy.mapper', (160, 250),(200,25))

        self.label6 = wx.StaticText(self.panel, -1, 'Service接口包:', (50, 300))
        self.service = wx.TextCtrl(self.panel, -1, 'com.shy.service', (160, 300), (200, 25))

        self.label7 = wx.StaticText(self.panel,-1,'Service实现类包:',(30,350))
        self.serviceImpl = wx.TextCtrl(self.panel,-1,'com.shy.service.impl',(160,350),(200,25))

        self.label8 = wx.StaticText(self.panel, -1, 'Controller包:', (50, 400))
        self.controller = wx.TextCtrl(self.panel, -1, 'com.shy.controller', (160, 400), (200, 25))

        self.label9 = wx.StaticText(self.panel, -1, 'base路径:', (50, 450))
        self.proPath = wx.TextCtrl(self.panel, -1,'', (160, 450), (200, 25))

        self.next = wx.Button(self.panel, -1, '下一步', (150, 500))
        self.next.Bind(wx.EVT_BUTTON, self.next_e)

    def table_view(self):# 选取数据表视图
        size = self.panel.GetSize()
        self.panel.Destroy()
        self.scroll = wx.ScrolledWindow(self,-1)
        self.scroll.SetSize(size[0], size[1])

        self.select_all_btn = wx.ToggleButton(self.scroll,-1,'全选',(50,10))

        self.select_all_btn.Bind(wx.EVT_TOGGLEBUTTON,self.select_all_e)

        self.next = wx.Button(self.scroll, -1, '创建', (150, 10))

        self.next.Bind(wx.EVT_BUTTON,self.generate_e)

        self.btn = wx.Button(self.scroll, -1, '清空类名', (250, 10))
        self.btn.Bind(wx.EVT_BUTTON, self.clear_tc_e)

        self.label2 = wx.StaticText(self.scroll, -1, '勾选数据表名', (50, 50))
        self.label3 = wx.StaticText(self.scroll, -1, '输入类名', (250, 50))
        cursor = self.db_connection.cursor()
        cursor.execute('show tables')
        data = cursor.fetchall()
        self.tables = []
        for i,j in enumerate(data):
            class_name = self.first_upper(self.sql_to_camel(j[0]))
            self.tables.append((wx.CheckBox(self.scroll , -1 , j[0] , (50,27*i+80)),
                                    wx.TextCtrl(self.scroll, -1, class_name, (200, 27 * i + 75),(150,25))))
        self.scroll.SetScrollbars(0, 1, 0, len(data)*27+120)

    def clear_tc_e(self,e):
        for i in self.tables:
            i[1].SetValue('')

    def create_dirs(self):# 建立文件夹
        path_list = []
        for i in self.packages:
            path = join(self.basePath,i.replace('.','\\'))
            if not oexist(path):
                omkdirs(path)
            path_list.append(path)
        return path_list

    def create_pojo(self,fields, class_name):  # 创建java实体类
        flag = False
        for i in fields:
            if i[0] == 'Date':
                flag = True
                break
        class_str = 'package ' + self.packages[0] + ';\n\n'
        if flag:
            class_str += 'import java.util.Date;\n'
        class_str += 'import org.springframework.stereotype.Component;\nimport java.io.Serializable;\n\n' \
                     '@Component\npublic class ' + class_name + ' implements Serializable {\n'  # 类名
        for i in fields:
            class_str += '\tprivate ' + i[0] + ' ' + i[1] + ';\n'  # 私有属性
        class_str += '\n\tpublic ' + class_name + '('
        for i in fields:
            class_str += i[0] + ' ' + i[1] + ','  # 构造函数参数
        class_str = class_str[:-1] + '){\n'
        for i in fields:
            class_str += '\t\tthis.' + i[1] + ' = ' + i[1] + ';\n'  # 构造函数传参
        class_str += '\t}\n\n\tpublic ' + class_name + '(){}\n\n'  # 无参构造
        for i in fields:  # gettr和setter方法
            class_str += '\tpublic ' + i[0] + ' get' + self.first_upper(i[1]) + '(){\n\t\treturn ' \
                         + i[1] + ';\n\t}\n\n\tpublic void set' + self.first_upper(i[1]) + '(' + i[0] + \
                         ' ' + i[1] + '){\n\t\tthis.' + i[1] + ' = ' + i[1] + ';\n\t}\n\n'
        class_str += '\t@Override\n\tpublic String toString(){\n\t\treturn \"' + class_name + \
                     '{\" +\n'
        to_string = ''
        for i in fields:  # toString方法
            if i[0] == 'String':
                to_string += '\t\t\t\", ' + str(i[1]) + '=\'\" + ' + str(i[1]) + ' + \'\\\'\' +\n'
            else:
                to_string += '\t\t\t\",' + str(i[1]) + '=\" + ' + str(i[1]) + ' +\n'
        class_str += '\t\t\t\"' + to_string[5:] + '\t\t\t\'}\';\n\t}\n}'
        file_name = self.packages[0].replace('.', '\\') + '\\' + class_name + '.java'
        self.to_file(class_str, file_name)

    def create_mapper_interface(self,class_name):# 创建mapper接口
        class_str = 'package ' +self.packages[1] + ';\n\n'\
                    +'import org.springframework.stereotype.Repository;\n\n' \
                     +'@Repository\npublic interface ' + class_name + 'Mapper{\n\n}'
        file_name = self.packages[1].replace('.', '\\') + '\\' + class_name + 'Mapper.java'
        self.to_file(class_str, file_name)

    def create_service_interface(self,class_name):
        service_str = 'package ' + self.packages[2] + \
                    ';\n\nimport org.springframework.stereotype.Component;\n' \
                    '\npublic interface ' \
                    + class_name + 'Service{\n\n}'
        file_name = self.packages[2].replace('.', '\\') + '\\' + class_name + 'Service.java'
        self.to_file(service_str, file_name)

    def create_service_impl(self,class_name):
        service_str = 'package ' + self.packages[3] + ';\n\n'\
                      +'import ' + self.packages[1] + '.' + class_name + 'Mapper;\n'\
                      +'import ' + self.packages[2]+'.'+ class_name +'Service;\n'\
                      +'import org.springframework.beans.factory.annotation.Autowired;\n' \
                      +'import org.springframework.stereotype.Service;\n\n'\
                      +'@Service\n'\
                      +'public class '+ class_name + 'ServiceImpl implements '+class_name+'Service {\n'\
                      +'\t@Autowired\n'\
                      +'\tprivate ' + class_name + 'Mapper mapper;\n}'
        file_name = self.packages[3].replace('.', '\\') + '\\' + class_name + 'ServiceImpl.java'
        self.to_file(service_str, file_name)

    def create_controller(self,controller_str):
        file_name = self.packages[4].replace('.', '\\') + '\\' + 'CenterController.java'
        self.to_file(controller_str, file_name)

    def generate_e(self,e):# 生成相应文件事件
        self.create_dirs()  # 建立文件夹
        class_names = []
        controller_str = 'package '+self.packages[4] + ';\n\n'\
                         +'import org.springframework.web.bind.annotation.RestController;\n'
        service_fields = ''
        service_imports = ''
        for i in self.tables:
            if i[0].GetValue() == True:
                class_name = i[1].GetValue() # 类名
                field_list = self.get_field_list(i[0].GetLabel()) # 所有的属性值和类型
                self.create_pojo(field_list,class_name)# 创建实体类
                self.create_mapper_interface(class_name)# 创建接口
                self.create_service_interface(class_name)# 创建service接口
                self.create_service_impl(class_name)# 创建service实现类
                service_imports += 'import '+self.packages[3]+'.'+class_name+'ServiceImpl;\n'
                service_fields += '\t@\n\tprivate '+class_name+'ServiceImpl '+self.first_lower(class_name)+'Service;\n'
        controller_str += service_imports+'\n@RestController\npublic class CenterController{\n'+service_fields+'\n}'
        self.create_controller(controller_str)
        self.db_connection.close() # 关闭数据库连接
        wx.MessageBox('成功!')# 弹出提示信息
        self.Destroy()

    def select_all_e(self,e):# 全选和全不选功能切换事件
        value = self.select_all_btn.GetValue()
        if(value):
            self.select_all_btn.SetLabel('全不选')
            for i in self.tables:
                i[0].SetValue(True)
        else:
            self.select_all_btn.SetLabel('全选')
            for i in self.tables:
                i[0].SetValue(False)

    def next_e(self,e):# 读取表名并获取连接事件
        self.db_connection = pyconnect('localhost',
                                             self.username.GetValue(),
                                             self.password.GetValue(),
                                             self.db.GetValue())# 获取数据库连接对象
        # 包名表
        self.packages = [self.pojo.GetValue(), self.mapper.GetValue(), self.service.GetValue(),self.serviceImpl.GetValue(),self.controller.GetValue()]
        # 工程所在的路径
        self.basePath = self.proPath.GetValue()
        # 销毁界面不需要用到的一些组件
        self.label1.Destroy()
        self.label2.Destroy()
        self.label3.Destroy()
        self.label4.Destroy()
        self.label5.Destroy()
        self.label6.Destroy()
        self.label7.Destroy()
        self.label8.Destroy()
        self.label9.Destroy()
        self.username.Destroy()
        self.password.Destroy()
        self.db.Destroy()
        self.pojo.Destroy()
        self.mapper.Destroy()
        self.service.Destroy()
        self.serviceImpl.Destroy()
        self.controller.Destroy()
        self.proPath.Destroy()
        self.next.Destroy()
        self.table_view()

if __name__=='__main__':
    app = wx.App()
    frame = myFrame()
    frame.Show()
    app.MainLoop()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值