告别无止境的增删改查:Java代码生成器
有感于马上要做个比较大的业务系统,想到那无止境的增删改查、粘贴复制,顿时脑后升起一阵凉风。于是想到个找或者写一个Java代码的生成器,这样在正常开发进度下,也能余下更多的时间去做些别的事情。
闲话少说,首先总结下需求:
我需要的这个工具能够读取数据库表结构,通过对字段类型、名称等分析得到需要的各种变量,根据模板生成相应的pojo类、hibernate的xml配置文件、dao和service的接口和类。
需求看起来很简单,但是一是没搞过这样的小工具,二是技术不过关,所以还是想到了找找有没有开源的代码拿过来根据自己的需求改。
于是找到了rapid-generator这个开源工具,同学们可以下载rapid-generator直接使用,根据自己的需求写好模板就行了。
由于自己项目中的特殊情况和公司规范等因素,另外也是想学习下别人的设计,所以我对源码进行了删减和功能的修改。
来看下主要的类:

Table:根据表结构建立的对象。
Column:根据表中每列建立的对象。
Generator:生成器核心类,主要负责根据表对象和读取FreeMarker模板生成最后的java代码文件。
GeneratorControl:控制生成过程等的一些参数,例如文件是否覆盖、文件编码等。
GeneratorProperties:读取配置文件的类,配置文件包括数据库连接信息和一些基本的参数配置。
下面来看一下模板的编写:
pojo模板:
- <#include "/java_copyright.include">
- <#assign className = table.className>
- <#assign classNameLower = className?uncap_first>
- package ${basepackage}.pojo.${mpackage}.${table.classNameFirstLower};
- <#include "/java_imports.include">
- import com.linkage.agri.pojo.base.BaseEntity;
- public class ${className} extends BaseEntity {
- private static final long serialVersionUID = 5454155825314635342L;
- <#list table.columns as column>
- /**
- * ${column.remarks}
- */
- private ${column.simpleJavaType} ${column.columnNameLower};
- </#list>
- <@generateJavaColumns/>
- <#macro generateJavaColumns>
- <#list table.columns as column>
- <#if column.isDateTimeColumn>
- public String get${column.columnName}String() {
- return DateConvertUtils.format(get${column.columnName}(), FORMAT_${column.constantName});
- }
- public void set${column.columnName}String(String ${column.columnNameLower}) {
- set${column.columnName}(DateConvertUtils.parse(${column.columnNameLower}, FORMAT_${column.constantName},${column.simpleJavaType}.class));
- }
- </#if>
- public void set${column.columnName}(${column.simpleJavaType} ${column.columnNameLower}) {
- this.${column.columnNameLower} = ${column.columnNameLower};
- }
- public ${column.simpleJavaType} get${column.columnName}() {
- return this.${column.columnNameLower};
- }
- </#list>
- </#macro>
FreeMarker的基本语法可以看下FreeMarker中文手册。
${}可以引用很多变量,这些变量包括:环境变量、table对象、配置变量等,这些变量都装在一个map里,如果自己有特殊需求,当然可以修改源码来装载更多的变量值。
注意:当变量为对象时,访问对象的属性是通过get方法来访问的。例如${table.classNameFirstLower},是引用 table对象的getNameFirstLower()方法,即使table对象中没有nameFirstLower这个属性也能够引用。
再看下我写的dao的模板:
- <#include "/java_copyright.include">
- <#assign className = table.className>
- <#assign classNameLower = className?uncap_first>
- package ${basepackage}.dao.${mpackage}.${table.classNameFirstLower};
- import java.math.BigDecimal;
- import java.util.List;
- import java.util.Map;
- import com.linkage.agri.dao.base.AbstractHibernateDAO;
- import com.linkage.agri.exception.DAOException;
- import ${basepackage}.pojo.${mpackage}.${classNameLower}.${className};
- <#include "/java_imports.include">
- public Class ${className}DAOImpl extends AbstractHibernateDAO implements ${className}DAO
- {
- /**
- * <query all>
- * @param paramMap
- * @param orderMap
- * @param pageNum
- * @param pageSize
- * @return
- * @throws DAOException
- */
- @SuppressWarnings
- public List<${className}> queryList${className}ByAttr(Map<String, Object> paramMap, Map<String, String> orderMap, int pageNum,
- int pageSize)
- throws DAOException
- {
- return super.listInstances(${className}.class, paramMap, orderMap, pageNum, pageSize);
- }
- /**
- *
- * <find one by id>
- * @param serial
- * @throws DAOException
- */
- public ${className} find${className}By${table.pkColumn.columnName}(${table.pkColumn.simpleJavaType} ${table.pkColumn.columnNameFirstLower})
- throws DAOException
- {
- return (${className})super.findById(${className}.class, ${table.pkColumn.columnNameFirstLower});
- }
- /**
- *
- * <save one>
- * @param ${table.classNameFirstLower}
- * @throws DAOException
- */
- public ${table.pkColumn.simpleJavaType} save${className}(${className} ${table.classNameFirstLower})
- throws DAOException
- {
- return (${table.pkColumn.simpleJavaType})super.saveInstance(${table.classNameFirstLower});
- }
- /**
- *
- * <update one>
- * @param ${table.classNameFirstLower}
- * @throws DAOException
- */
- public void update${className}(${className} ${table.classNameFirstLower})
- throws DAOException
- {
- super.updateInstance(${className});
- }
- /**
- * <check one is have?>
- * @param paramMap
- * @return
- * @throws DAOException
- */
- public boolean check${className}IsHaveByAttr(Map<String, Object> paramMap)
- throws DAOException
- {
- StringBuffer sqlBuffer = new StringBuffer();
- sqlBuffer.append("SELECT COUNT(*) FROM ${table.sqlName} T ");
- sqlBuffer.append("WHERE T.${table.pkColumn.sqlName} = ? ");
- BigDecimal big = (BigDecimal)super.findUniqueResultBySQLWithParams(sqlBuffer.toString(), paramMap.get("${table.pkColumn.columnNameFirstLower}"));
- return big.intValue() > 0 ? false : true;
- }
- /**
- * <update some>
- * @param ${table.classNameFirstLower}List
- * @return
- * @throws DAOException
- */
- public void update${className}Batch(List<${className}> ${table.classNameFirstLower}List)
- throws DAOException
- {
- super.updateBatchInstance(${table.classNameFirstLower}List);
- }
- /**
- *
- * <delete one>
- * @param ${table.classNameFirstLower}
- * @throws DAOException
- */
- public void delete${className}(${className} ${table.classNameFirstLower})
- throws DAOException
- {
- super.deleteInstance(${table.classNameFirstLower});
- }
- }
建立模板是能否解决自己问题的关键,在摸索出门道以后写模板变的十分简单。其实原理很简单,就是用一系列占位符来替换实际的变量值。
模板路径可以按照实际项目中的路径来拜访,生成器可以读取某个路径下所有模板进行生成,结果如下图:

接口和实现:

就说这么多吧,感兴趣的可以研究下这个工具的源码,也DIY出一套自己代码生成工具。不感兴趣的直接写模板就能用。
我只是走在路上,偶尔驻足观赏,偶尔回头看看。
告别无止境的增删改查:Java代码生成器的更多相关文章
- 告别无止境的增删改查--Java代码生成器
转自:http://www.cnblogs.com/zhuYears/archive/2012/02/29/2373491.html 告别无止境的增删改查--Java代码生成器 有感于马上要做个比较大 ...
- 仿联想商城laravel实战---5、无刷新的增删改查(动态页面更新的三种方式(html))
仿联想商城laravel实战---5.无刷新的增删改查(动态页面更新的三种方式(html)) 一.总结 一句话总结: 直接js增加删除修改html 控制器直接返回处理好的页面 用双向绑定插件比如vue ...
- salesforce 零基础学习(五十一)使用 Salesforce.com SOAP API 实现用户登录以及简单的增删改查(JAVA访问salesforce)
此篇请参看:https://resources.docs.salesforce.com/202/latest/en-us/sfdc/pdf/salesforce_developer_environme ...
- MongoDB学习-->命令行增删改查&JAVA驱动操作Mongodb
MongoDB 是一个基于分布式文件存储的数据库. 由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关 ...
- 5、Spring+Struts2+MyBatis+分页(mybatis无代理)增删改查
1.创建如下项目结构 2.在src下的com.entity包下创建Dept.java package com.entity; /** * 部门表 * @author Holly老师 * */ publ ...
- HBase 增删改查Java API
1. 创建NameSpaceAndTable package com.HbaseTest.hdfs; import java.io.IOException; import org.apache.had ...
- 增删改查-java(新手)
PreparedStatement: 方法: Connection: 方法: 实例: 1.查询: package cn.chuang.JdbcDome; import java.sql.*; pu ...
- mysql数据库的连接以及增删改查Java代码实现(转载)
每天叫醒自己的不是闹钟,而是梦想 数据库: create table t1(id int primary key not null auto_increment,name varchar(32),pa ...
- express无中间件的增删改查
index.js const express = require("express");导入express框架 const data = require("./data& ...
随机推荐
- 过拟合(Overfitting)和正规化(Regularization)
过拟合: Overfitting就是指Ein(在训练集上的错误率)变小,Eout(在整个数据集上的错误率)变大的过程 Underfitting是指Ein和Eout都变大的过程 从上边这个图中,虚线的左 ...
- linux c 打印彩色字符
#include <stdio.h> #include <string.h> int main(int argc, char **argv) { , j = , str_len ...
- SQLserver通过链接服务器连接oracle
在SQLserver中一直使用的是DTS抽取数据,但是DTS微软只支持到2008,到了2012后就没有这个工具了,现在需要在SQLserver跟Oracle中间建立一个通道,借助这个通道,将Oracl ...
- SVN四部曲之SVN使用详解进阶
SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很多不同的版本,这就需要程序员有效的管理代码,在需要的时候可以迅速,准确取出相应的版本. Subversion是什么? ...
- Python - python不是内部或外部命令
[方法一]我的电脑->属性->高级->环境变量->系统变量 在系统变量里找到PATH,双击PATH,在结尾加上 ";C:\Python26"(不要引号) ...
- Excel取消保护密码
Excel表被保护了, 如果没有密码, 可通过以下宏代码查看 (Office 2013已测) Option Explicit Public Sub AllInternalPasswords()' Br ...
- 常用的机器学习&数据挖掘知识点【转】
转自: [基础]常用的机器学习&数据挖掘知识点 Basis(基础): MSE(Mean Square Error 均方误差),LMS(LeastMean Square 最小均方),LSM(Le ...
- 【CodeForces】【148D】Bag of mice
概率DP kuangbin总结中的第9题 啊……题目给的数据只有白鼠和黑鼠的数量,所以我们只能在这个上面做(gao)文(D)章(P)了…… 明显可以用两种老鼠的数量来作为状态= = 我的WA做法: 令 ...
- js 判断是否为chrome浏览器
var isChrome =navigator.userAgent.indexOf("Chrome") !== -1 用 navigator.appVersion 不好使,因为al ...
- EBP的妙用[无法使用ESP定律时]
1.了解EBP寄存器 在寄存器里面有很多寄存器虽然他们的功能和使用没有任何的区别,但是在长期的编程和使用 中,在程序员习惯中已经默认的给每个寄存器赋上了特殊的含义,比如:EAX一般用来做返回值,ECX ...