对代码生成器的一点想法

原创
2013/09/12 16:09
阅读数 8.8K

本文是《轻量级 Java Web 框架架构设计》的系列博文。

代码生成器,这个东西很早就有人再搞了。比较典型的应用场景就是中间件平台,国内的像普元的 EOS 算是做的比较好的。通过图形化界面的方式拖、拉、拽几下,一个应用软件就生成了,因为平台中已经包括了大量的代码生成器。当然中间件平台大多数都是一些商业产品,不是我们这些屌丝买得起的。一般都是金融企业,像银行、券商这类公司才敢玩。

今天我不谈这些商业产品,我要讲的是关于代码生成器的应用,也就是说:为什么要用代码生成器呢?

我想最有价值的地方就是减小了手工的重复劳动,计算机自动帮我们生成代码,将我们的双手解脱出来。然而,这些代码的格式是我们预先定义好的,也就是模板了,它们需要模板引擎来做解析。

在 Java 这个圈圈里面,做的比较好的模板引擎不多,Velocity 与 FreeMarker 算是比较好的两款了。但本人还是比较钟情与 Velocity,因为它足够轻巧,足够 Smart!而且还有 Apache 这个老大来保护它。当然,遇到 Velocity 搞不定的情况,不妨再去找 FreeMarker 帮忙吧。

回到今天的主题,我想开发一块轻量级代码生成器,使用场景如下:

  1. 用户在 Excel 模板中填写表结构相关信息。
  2. 通过命令行(或批处理程序)方式执行代码生成器。
  3. 生成数据表结构(一份 SQL 脚本)与 Entity 类文件(一堆 Java 文件)。
  4. 手工或自动的方式执行 SQL 脚本,将数据表结构初始化到数据库中(省去了手工建表的过程)。
  5. 将生成的 Entity 类 Java 文件复制到自己的 IDE 中(省去了编写 Entity 的过程)。

以一张 product 表为例吧。

Excel 模板大致长这个模样:

生成的 SQL 脚本是这样的:

DROP TABLE IF EXISTS `product`;
CREATE TABLE `product` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `product_type_id` bigint(20) NOT NULL,
  `product_name` varchar(100) NOT NULL,
  `product_code` char(5) NOT NULL,
  `price` int(10) NOT NULL,
  `description` text,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
生成的 Entity 类如下:
public class Product extends BaseEntity {

    private long productTypeId;

    private String productName;

    private String productCode;

    private int price;

    private String description;

    public long getProductTypeId() {
        return productTypeId;
    }

    public void setProductTypeId(long productTypeId) {
        this.productTypeId = productTypeId;
    }

    // ... 省略其他 getter/setter 方法
}
从数据库脚本到实体类,其实有一个映射关系(ORM):
  1. 将表名首字母大写,对应于实体名。
  2. 将列名转为驼峰式命名法,对应于实体属性(类的成员变量)。

若表名或列名出现 Java 关键字或保留字,则使用一定的规则,将其转换过来,比如:可在变量名后面加上一个下划线。

有朋友会问:为什么只生成 Entity 类,其他代码难道不用生成吗?

不错,很多快速开发框架确实将许多代码都生成了,从后台到前台。对于我而言,需要做一些取舍,找准这款工具的定位。它是为 Smart Framework 提供代码生成的辅助工具,而不是一个强大的代码生成软件。我认为,先一步步的来吧,至少表结构和实体定义是比较浪费时间的,我们先把这些代码生成出来。以后看看还有哪些代码需要生成,但是完全的代码生成也有它的弊端,比如:当反复生成代码时,不小心就会覆盖掉自己已经修改的代码,那你就崩溃了。

此外,我们编写的这份 Excel 文件也可以作为系统的数据字典使用(看 PM 还敢不敢说我们没有文档了),对于后期的维护工作也比较合适。

大家看看,有必要做这个小工具吗?如果需要的话,我同样也会把实现过程完全开放出来,与大家共同探讨。

展开阅读全文
加载中
点击加入讨论🔥(12) 发布并加入讨论🔥
打赏
12 评论
5 收藏
6
分享
返回顶部
顶部