在web开发过程中,尤其是后台管理系统的开发中,少不了增删改成的基础操作,原来我自己的做法是一份一份的拷贝粘贴,然后修改其中的不同,然而这样既枯燥无味又浪费了大量的时间,所以根据自己项目结构的特点写了一个自动生成结构代码的工具jar包,可以根据数据库表直接生成相应数据库模型对象(DMO)以及对表的增删改查代码。

之前我考虑过多种自动生成代码的提供方式,比如web的方式,通过在页面文本框里面输入各种参数,比如模板文件地址,生成文件地址,数据库名,数据库用户名和密码等,点击生成按钮就可以生成源代码文件。但这样需要部署启动这个web程序。使用java的图形用户界面,但我对java图形的相关API并不了解,最后决定使用一个jar包的方式,方便简洁。

由于模板文件使用的是freemarker,数据库使用的是mysql,所以引入其他的两个jar文件。

如上图,AutoGenerationJavaCode.jar 是将原本工程里的 AutoGenerationJavaCode.java文件打包生成的,也是最终的形式。通过在AutoGenerationDemo类main函数中设置参数,直接调用即可自动生成代码。

配置好参数后在左图右键运行java程序即可生成右图代码文件:

     

调用如下:

 1 public class AutoGenerationDemo {
2
3 public static void main(String[] args) throws ClassNotFoundException, SQLException, IOException, TemplateException {
4 //数据库地址
5 String url = "jdbc:mysql://10.27.209.137:3306/sample";
6 //用户名
7 String name = "root";
8 //密码
9 String passWord = "root";
10 //驱动
11 String driver = "com.mysql.jdbc.Driver";
12 //表名
13 String tableName = "t_operate_log";
14 //模板路径
15 String templateDir = "F:\\template";
16 //生成文件路径
17 String autoGeneratedFile = "F:\\autoGenerated";
18 //实例化
19 AutoGenerationJavaCode autoGenerationJavaCode = new AutoGenerationJavaCode(url, name, passWord, driver,
20 tableName,autoGeneratedFile,templateDir);
21
22 //调用生成java代码方法
23 autoGenerationJavaCode.autoGenerationJavaCode();
24 }
25
26 }

在main方法中配置好所需参数,由于代码包含注释,不在赘述,调用jar包中 AutoGenerationJavaCode的autoGenerationJavaCode方法即可生成,控制台会打印文件生产完成

我的Web项目的结构采用的是三层结构,Controller层调用service层,从service层调用dao层(数据操作层),所以决定自己生成service层,dao层代码。其实质就是将模板文件中的变量进行替换。模板文件及对应生成的java代码如下:

                                    

          

    

jar包的源代码如下:

package com.sun.autoGenerated;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map; import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException; public class AutoGenerationJavaCode { private String url;
private String name;
private String passWord;
private String driver;
private String sql;
private String tableName;
private String templateDir;
private String autoGeneratedFile;
private static String[][] fileNameArray = new String[5][2]; static {
fileNameArray[0][0] = "dmoTemplate.ftl";
fileNameArray[0][1] = "DMO.java"; fileNameArray[1][0] = "serviceTemplate.ftl";
fileNameArray[1][1] = "Service.java"; fileNameArray[2][0] = "serviceImplTemplate.ftl";
fileNameArray[2][1] = "ServiceImpl.java"; fileNameArray[3][0] = "daoTemplate.ftl";
fileNameArray[3][1] = "Dao.java"; fileNameArray[4][0] = "daoImplTemplate.ftl";
fileNameArray[4][1] = "DaoImpl.java";
} public AutoGenerationJavaCode(String url, String name, String passWord, String driver, String tableName,
String autoGeneratedFile,String templateDir) {
this.url = url;
this.name = name;
this.passWord = passWord;
this.driver = driver;
this.sql = "select * from " + tableName;
this.tableName = tableName;
this.templateDir = templateDir;
this.autoGeneratedFile = autoGeneratedFile;
} public void autoGenerationJavaCode() throws IOException, TemplateException, ClassNotFoundException,
SQLException {
Configuration cfg = new Configuration();
cfg.setDefaultEncoding("utf-8"); String className = dealTableName(); String fileName = dealClassName(className);
Map<String, Object> columnMap = getColumn();
//设置模板文件路径
cfg.setDirectoryForTemplateLoading(new File(templateDir)); Map<String, Object> rootMap = new HashMap<String, Object>();
rootMap.put("className", className);
rootMap.put("columnMap", columnMap);
File dir = new File(autoGeneratedFile + "\\");
//检查目录是否存在,不存在则创建
if (!dir.exists()) {
dir.mkdir();
}
for (int i = 0; i < fileNameArray.length; i++) { Template temp = cfg.getTemplate(fileNameArray[i][0]); File docFile = new File(autoGeneratedFile + "\\" + fileName + fileNameArray[i][1]); Writer docout = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));
//输出文件
temp.process(rootMap, docout);
}
System.out.println("==============文件生产成功==============="); } //获取数据库表字段名放入map中
public Map<String, Object> getColumn() throws ClassNotFoundException, SQLException {
Connection conn;
PreparedStatement pStemt = null;
Class.forName(driver);
conn = DriverManager.getConnection(url, name, passWord);
pStemt = conn.prepareStatement(sql);
ResultSetMetaData rsmd = pStemt.getMetaData(); Map<String, Object> columnMap = new HashMap<String, Object>();
int size = rsmd.getColumnCount();
for (int i = 0; i < size; i++) {
String columnName = dealColumnName(rsmd, i);
columnMap.put(columnName, columnName);
}
conn.close();
return columnMap;
} //将表名转换为DMO的字段名,比如 operate_type 转换后为 operateType
private String dealColumnName(ResultSetMetaData rsmd, int i) throws SQLException {
String columnName = rsmd.getColumnName(i + 1).toLowerCase();
String charAfterLine = String.valueOf(columnName.charAt((columnName.indexOf("_") + 1)));
String convertedChar = charAfterLine.toUpperCase();
columnName = columnName.replace("_" + charAfterLine, convertedChar);
return columnName;
} //将表名转换为类型类名 比如 t_operate_log 转换后为 operateLog ,类名首字母应为大写,这里在freemarker的模板里直接转换
private String dealTableName() {
String className = tableName.toLowerCase().substring(tableName.indexOf("_") + 1);
String charAfterLine = String.valueOf(className.charAt((className.indexOf("_") + 1)));
String convertedChar = charAfterLine.toUpperCase();
className = className.replace("_" + charAfterLine, convertedChar);
return className;
} //将类名转换为文件名,java公共类名与其文件名应该相同,这里将首字母转换为大写 如operateLog 转换后为 OperateLog
private String dealClassName(String className) {
String first = className.substring(0, 1).toUpperCase();
String rest = className.substring(1, className.length());
String fileName = new StringBuffer(first).append(rest).toString();
return fileName;
} }

源码下载:http://files.cnblogs.com/files/jarman/sourceCode.zip

(转)freemakeer初入门的更多相关文章

  1. SpringBoot 初入门

    SpringBoot 初入门 关于介绍什么之类的就不讲了,主要做一下学习记录. 1. 启动方式 IDEA 启动 命令行启动: mvn spring-boot:run 部署到服务器启动: 先进行打包, ...

  2. Nginx - Windows下Nginx初入门

    公司刚使用nginx,预先学习下.鉴于机器没有Linux环境,在Windows熟悉下. 下载 目前(2015-07-11),nginx的稳定版本是1.8.0,在官网下载先,windows版的nginx ...

  3. 坚持自学的第二天,bootstrap初入门

    前言 昨天,初步学完了jekyll目录结构与Liquid语法的应用与认识. 日志 今天刚入门,做了一个bootstrap导航栏,但是选中状态不行,找了JS中写好的API,写法与视频中讲的有点不一样,但 ...

  4. SQL学习笔记——SQL初入门,Ubuntu下MySQL的安装

          刚开始接触sql,于是准备在Ubuntu下学习sql,就跟着itercast的sql教程开始入门了. 下面只是我个人的记录,高手请绕道: 一. 在安装之前,我们可以用下面这个命令通过开放端 ...

  5. day 50 AJAX 初入门

    前情提要: jq 学不好,ajax   难用好, 食用先请先确保最起码的jq 能会用 https://www.cnblogs.com/baili-luoyun/p/10473518.html  jq ...

  6. Nginx - Windows下Nginx初入门,附CentOS下Nginx的安装

    公司刚使用nginx,预先学习下.鉴于机器没有Linux环境,在Windows熟悉下. 下载 目前(2015-07-11),nginx的稳定版本是1.8.0,在官网下载先,windows版的nginx ...

  7. Android零基础入门第73节:Activity初入门,创建和配置如此简单

    Activity是Android应用的重要组成单元之一,也是Android应用最常见的组件之一.前面看到的示例通常都只包含一个Activity或一个AppCompatActivity,但在实际应用中这 ...

  8. Java:Web Service初入门

    前言 Web Service技术在我第一次接触,又没有实际使用时完全不理解这是什么.以为是一种类似Spring,Shiro的编程框架.后来渐渐理解,WS(即Web Service缩写)是一种通用的接口 ...

  9. ionic 初入门

    ionic ionic 是webapp开发的一个框架 安装 npm install -g cordova ionic ;  我这两个分开装,因为ionic模块拖不下来,所以只好等待时机.这时候科学上网 ...

随机推荐

  1. AsyncTask下载JSON

    public class HttpUtils { // 从网络url上下载字符串 public static String getHttpStr(String url) { HttpClient ht ...

  2. 模拟 ZOJ 3878 Convert QWERTY to Dvorak

    题目传送门 /* 模拟:手敲map一一映射,累! 除了忘记读入字符串不能用gets用getline外还是很顺利的AC了:) */ #include <cstdio> #include &l ...

  3. 判断 ACdream 1202 Integer in C++

    题目传送门 /* 分情况讨论,在long long范围里可以直接比较 sscanf 直接读到n中去 */ #include <cstdio> #include <iostream&g ...

  4. 【python游戏编程之旅】第四篇---pygame中加载位图与常用的数学函数。

    本系列博客介绍以python+pygame库进行小游戏的开发.有写的不对之处还望各位海涵. 在上一篇博客中,我们学习了pygame事件与设备轮询.http://www.cnblogs.com/msxh ...

  5. TYVJ P1024 外星人的密码数字

    做题记录:2016-08-16 20:09:30 描述     XXXX年突然有外星人造访,但大家语言不通,不过科学家们经过研究发现外星人用26个英文字母组成的单词中最长不降子序列的长度来表述数字,且 ...

  6. 【wikioi】1217 借教室

    题目链接http://www.wikioi.com/problem/1217/ 算法:二分答案(线段树可过wikioi数据) 二分:http://www.wikioi.com/solution/lis ...

  7. WebRTC手记之WebRtcVideoEngine2模块

    转载请注明出处:http://www.cnblogs.com/fangkm/p/4401143.html 终于讲到视频数据的编码发送模块了,不容易.总体来说也看了不少时间WebRTC的源码了,最大的感 ...

  8. 转载--thinkphp框架的路径问题 - 总结

    转自:http://blog.sina.com.cn/s/blog_827ddd950100ulyv.html TP中有不少路径的便捷使用方法,比如模板中使用的__URL__,__ACTION__等, ...

  9. android之OptionsMenu

    首先编写res/layout/Activity_main.xml 代码如下: <LinearLayout xmlns:android="http://schemas.android.c ...

  10. unauthenticated user reading from net

    今天有台数据库异常,登录服务器后执行show processlist,发现大量的 unauthenticated user 状态.如下: 于是第一时间想到DNS反向解析的问题,于是看看是否关闭DNS解 ...