开源Java代码生成器(全网最强,界面美观,功能丰富)

一、在线地址

Java在线代码生成器:在线访问

二、页面截图

在这里插入图片描述
在这里插入图片描述

三、核心功能

  • 支持Mybatis、MybatisPlus、Jpa代码生成
  • 使用 antlr4 解析SQL语句,保证了SQL解析的成功率
  • 支持自定义包名、作者名信息
  • 支持自定义方法名、接口地址
  • 支持自定义选择是否生成某个方法
  • 支持选择是否集成Swagger、Lombok、validation等依赖

四、技术介绍

前端: React 16.8.6、Ant-design 4.24.12、Umi 3.5.41

后端: Java 1.8、SpringBoot2.3.4.RELEASE、knife4j(Swagger)2.0.9、Freemarker 2.3.31

五、源码

前端: tool4j-generator-ui

后台: tool4j-generator

部分代码节选:

    /**
     * 代码生成入口类
     *
     * @param params
     * @return
     */
    public Map<String, Object> generate(JavaCodeConfig params) {
        /*
          生成代码
         */
        List<ParserResult> results = execute(params);
        Map<String, Object> map = new HashMap<>();
        map.put("results", results);
        TreeVO root;
        root = new TreeVO().setKey(params.getBasePackage()).setTitle(params.getBasePackage());
        String basePath = params.getBasePackage().replace(".", "/") + "/";
        for (ParserResult parserResult : results) {
            String[] dirArr = parserResult.getFileName().replace(basePath, "").split("/");
            buildFileTree(root, dirArr, 0);
        }
        map.put("fileTree", root);
        if (CollUtil.isEmpty(results)) {
            log.error("SQL解析失败,建议您切换SQL解析器重试,Input = {}", params.getInput());
            throw new IllegalArgumentException("SQL解析失败,建议您切换SQL解析器重试");
        }
        if (results.stream().anyMatch(ParserResult::isErrored)) {
            List<ParserResult> errors = results.stream().filter(ParserResult::isErrored).collect(Collectors.toList());
            log.info(">>>>>>>>>>>>>>> generate code exists error: total={}, error={},Input = {}", results.size(), errors.size(), params.getInput());
        } else {
            log.info(">>>>>>>>>>>>>>> generate code all succeed.");
        }
        return map;
    }
import React, { Component } from 'react';
import { Divider, Input, Modal, Radio, Spin, Switch, Tag } from 'antd';
import styles from './GenerateModal.less';
import MethodSetting from '@/pages/components/MethodSetting';

const ORM_TYPE = {
  jpa: {
    label: 'JPA',
    color: '#138029',
  },
  mybatis: {
    label: 'Mybatis',
    color: '#f6b305',
  },
  mybatisPlus: {
    label: 'MybatisPlus',
    color: '#008585',
  },
};

class GenerateModal extends Component {

  constructor (props) {
    super(props);
    this.state = {
      init: false,
      parserType: 'common',
      basePackage: 'com.tool4j',
      author: 'system',
      apiPathPrefix: '/api',
      tableNamePrefix: '',
      restType: 'restful',
      ormType: 'mybatisPlus',
      methods: {
        findPage: {
          label: '分页查询',
          name: 'findPage',
          apiPath: '/findPage',
          enabled: true,
        },
        findList: {
          label: '列表查询',
          name: 'findList',
          apiPath: '/findList',
          enabled: true,
        },
        findById: {
          label: '查询详情',
          name: 'findById',
          apiPath: '/{id}',
          enabled: true,
        },
        save: {
          label: '新增',
          name: 'insert',
          apiPath: '',
          enabled: true,
        },
        update: {
          label: '修改',
          name: 'update',
          apiPath: '',
          enabled: true,
        },
        delete: {
          label: '删除',
          name: 'delete',
          apiPath: '/{id}',
          enabled: true,
        },
      },
      dependencies: ['lombok', 'swagger', 'validator'],
    };
  }

  cancel = () => {
    this.props.cancel();
  };

  generate = () => {
    const {
      parserType,
      basePackage,
      author,
      apiPathPrefix,
      tableNamePrefix,
      restType,
      ormType,
      methods,
      dependencies,
    } = this.state;

    const generateConfig = {
      parserType,
      basePackage,
      author,
      apiPathPrefix,
      tableNamePrefix,
      restType,
      ormType,
      methods,
      dependencies,
    };
    this.props.submit(generateConfig);
  };

  dependencyChange = (key, checked) => {
    let { dependencies = [] } = this.state;
    if (checked) {
      dependencies.push(key);
    } else {
      dependencies = dependencies.filter(item => item !== key);
    }
    this.setState({
      dependencies,
    });
  };

  formChange = (key, value) => {
    this.setState({
      [key]: value,
    });
  };

  init = () => {
    const setting = this.props.setting;
    if (setting) {
      const { methods } = this.state;
      if (setting.methods) {
        for (let key in methods) {
          methods[key] = { ...methods[key], ...setting.methods[key] };
        }
      }
      this.setState({
        ...setting,
        methods,
        init: true,
      });
    }
  };

  render () {
    const { init, dependencies = [], ormType } = this.state;
    if (!init) {
      this.init();
    }
    let { templates = [] } = this.props;
    if (ormType) {
      templates = templates.filter(item => item.ormType === ormType);
    }

    const templateOptions = [];
    templates.forEach(template => templateOptions.push({
      value: template.ormType,
      label: <div>
        <Tag style={{ marginLeft: '5px' }} color={ORM_TYPE[template.ormType].color}>
          {ORM_TYPE[template.ormType].label}
        </Tag>
      </div>,
    }));

    return <Modal
      title={
        <div style={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          height: '14px',
          marginRight: '40px',
        }}>
          <div>
            <span>代码生成配置</span>
          </div>
        </div>
      }
      bodyStyle={{ padding: '5px' }}
      open={this.props.visible}
      maskClosable={false}
      onOk={this.generate}
      okText={'生成'}
      onCancel={this.cancel}
      cancelText={'取消'}
      width={'800px'}
    >
      <Spin spinning={this.props.loading} tip={'代码生成中,请稍候...'}>
        <div className={styles['module']}>
          <div style={{ marginBottom: '10px' }}>
            <Divider
              type='vertical'
              className={styles['divider']}
            >
            </Divider>
            <span style={{ fontSize: '16px', fontWeight: 600 }}>选择解析器</span>
          </div>
          <div style={{ marginLeft: '20px', display: 'flex' }}>
            <Radio.Group value={this.state.parserType} onChange={e => this.formChange('parserType', e.target.value)}>
              <Radio.Button value='common'>智能SQL解析器</Radio.Button>
              <Radio.Button value='mysql'>MySQL 解析器</Radio.Button>
              <Radio.Button value='postgresql'>Postgresql 解析器</Radio.Button>
              <Radio.Button value='plsql'>Oracle 解析器</Radio.Button>
            </Radio.Group>
          </div>
        </div>
        <div className={styles['module']}>
          <div style={{ marginBottom: '10px' }}>
            <Divider
              type='vertical'
              className={styles['divider']}
            >
            </Divider>
            <span style={{ fontSize: '16px', fontWeight: 600 }}>基础配置</span>
          </div>
          <div style={{ marginLeft: '20px' }}>
            <Input
              placeholder={'统一包名,如:com.tool4j'}
              addonBefore={<div style={{ width: '100px' }}>包名:</div>}
              style={{ marginTop: '5px', width: '60%' }}
              onChange={e => this.formChange('basePackage', e.target.value)}
              value={this.state.basePackage}
            />
            <Input
              placeholder={'作者姓名,如:system'}
              addonBefore={<div style={{ width: '100px' }}>作者:</div>}
              style={{ marginTop: '5px', width: '60%' }}
              onChange={e => this.formChange('author', e.target.value)}
              value={this.state.author}
            />
            <Input
              placeholder={'统一的接口前缀,如:/api'}
              addonBefore={<div style={{ width: '100px' }}>接口前缀:</div>}
              style={{ marginTop: '5px', width: '60%' }}
              onChange={e => this.formChange('apiPathPrefix', e.target.value)}
              value={this.state.apiPathPrefix}
            />
            <Input
              placeholder={'生成代码时可忽略表的统一前缀,如:t_'}
              addonBefore={<div style={{ width: '100px' }}>忽略表前缀:</div>}
              style={{ marginTop: '5px', width: '60%' }}
              onChange={e => this.formChange('tableNamePrefix', e.target.value)}
              value={this.state.tableNamePrefix}
            />
          </div>
        </div>
        <div className={styles['module']}>
          <div style={{ marginBottom: '10px' }}>
            <Divider
              type='vertical'
              className={styles['divider']}
            >
            </Divider>
            <span style={{ fontSize: '16px', fontWeight: 600 }}>方法配置</span>
          </div>
          <div style={{ width: '100%' }}>
            <MethodSetting methods={this.state.methods} formChange={this.formChange} />
          </div>
        </div>
        <div className={styles['module']}>
          <div style={{ marginBottom: '10px' }}>
            <Divider
              type='vertical'
              className={styles['divider']}
            >
            </Divider>
            <span style={{ fontSize: '16px', fontWeight: 600 }}>更多选项</span>
          </div>
          <div>
            <div style={{ margin: '20px', display: 'flex', textAlign: 'left' }}>
              <div style={{ width: '120px', fontSize: '15px', fontWeight: 600 }}>ORM框架:</div>
              <Radio.Group onChange={e => this.formChange('ormType', e.target.value)} value={this.state.ormType}>
                <Radio value={'mybatisPlus'}>MybatisPlus</Radio>
                <Radio value={'mybatis'}>Mybatis</Radio>
                <Radio value={'jpa'}>SpringData(JPA</Radio>
              </Radio.Group>
            </div>
          </div>
        </div>
        <div className={styles['module']}>
          <div>
            <div style={{ marginBottom: '10px' }}>
              <Divider
                type='vertical'
                className={styles['divider']}
              >
              </Divider>
              <span style={{ fontSize: '16px', fontWeight: 600 }}>集成依赖</span>
            </div>
            <div style={{ width: '100%', padding: '20px 40px', display: 'flex', justifyContent: 'space-between' }}>
              <div style={{ textAlign: 'center' }}>
                <div style={{ height: '60px' }}>
                  <img src={'/icon/swagger.svg'} width={180} style={{ margin: '0 5px 5px 5px' }} />
                </div>
                <Switch
                  style={{ width: '60px', marginTop: '10px' }}
                  checkedChildren='使用'
                  unCheckedChildren='移除'
                  checked={dependencies.filter(item => item === 'swagger').length > 0}
                  onChange={checked => this.dependencyChange('swagger', checked)}
                >
                </Switch>
              </div>
              <div style={{ textAlign: 'center' }}>
                <div style={{
                  height: '60px',
                  fontSize: '40px',
                  fontFamily: 'Georgia',
                }}>
                  Lombok
                </div>
                <Switch
                  style={{ width: '60px', marginTop: '10px' }}
                  checkedChildren='使用'
                  unCheckedChildren='移除'
                  checked={dependencies.filter(item => item === 'lombok').length > 0}
                  onChange={checked => this.dependencyChange('lombok', checked)}
                >
                </Switch>
              </div>
              <div style={{ textAlign: 'center' }}>
                <div style={{
                  width: '100%',
                  height: '60px',
                  display: 'flex',
                  flexDirection: 'column',
                  justifyContent: 'center',
                }}>
                  <div style={{
                    height: '60px',
                    fontSize: '40px',
                    fontFamily: 'Georgia',
                  }}>
                    Validation 校验
                  </div>
                </div>
                <Switch
                  style={{ width: '60px', marginTop: '10px' }}
                  checkedChildren='使用'
                  unCheckedChildren='移除'
                  checked={dependencies.filter(item => item === 'validator').length > 0}
                  onChange={checked => this.dependencyChange('validator', checked)}
                >
                </Switch>
              </div>
            </div>
          </div>
        </div>
      </Spin>
    </Modal>;
  }
}

export default GenerateModal;

六、本地运行

可直接 clone 该项目到本地,无需修改任何内容即可运行

后端:

  1. 使用Maven安装依赖
  2. 运行 Tool4jGeneratorApplication.java

前端:
3. 切换到前端工程根目录
4. 安装依赖: npm i
5. 运行:umi dev

七、结束语

大家也可以直接使用在线版本,使用过程中有任何问题或建议都可以留言反馈。
Java在线代码生成器:在线访问

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值