代码生成器

上一篇,我们使用了Mybatis的插件,这一篇,我们自己做一个代码生成器。

上一篇链接:Mybatis三剑客插件–实现分页

为什么自己做个代码生成器?
Mybatis自带的自动生成代码,不能自定义,比如各种命名没法改,比如不能生成controller、service、jsp。
在这里插入图片描述
代码生成器的原理:
(1)编写一个模板,比如要生成XXXService.java,service里面所有代码讲模块部分全部用占位符/变量名代替。比如MenuService改成${modelClass}Service。

(2)使用模板引擎,向模板中传递需要的占位符数据,比如${modelClass},这次要生成Menu,就传Menu,下次要建good,就传Good,就可以生成出来不同的模块,但代码只写了模板里面的这一遍。

(3)通过模板引擎,将替换好的占位符的模板输出为具体的MenuService.java、MenuController.java甚至是menu.jsp.

开发过程:

1.引入jar包
Velocity-1.7.jar : 模板引擎。
commons的2个jar包 :是模板引擎依赖了人家的类。
Guava-27.1-jre.jar :是对字段名的转换,比如good_name字段,在java类的属性叫goodName,当setGoodName时又变成首字母都大写:GoodName,这个jar可以方便转换。

2.新建类com.zq.code.CodeBuilder,要有main方法,需要单独运行生成代码文件。不走spring框架
(a)编写模板引擎调用代码

		//new一下他的模版引擎
		VelocityEngine ve = new VelocityEngine();
		//设置模版和输出的代码文件的编码方式
		Properties p = new Properties();
		p.setProperty(Velocity.ENCODING_DEFAULT, "UTF-8");
		p.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
		p.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8");
		ve.init(p);//引擎初始化

(b)编写引擎代码

//引入一个模版,通过模版路径
		Template serviceVm = ve.getTemplate("/WebContent/WEB-INF/vm/service.vm");

(c)引入模版
在WEB-INF下建立一个文件夹vm,在vm文件夹下建立一个文件service.vm。

import java.util.List;

import com.github.pagehelper.PageInfo;
import com.zq.model.${modelClass};

public interface ${modelClass}Service {
	/**
	 * 带有分页的列表查询
	 * @param pageNum
	 * @param pageSize
	 * @param ${modelClass}
	 * @return
	 */
	public PageInfo<${modelClass}> list(Integer pageNum,Integer pageSize,${modelClass} ${modelName});
	/**
	 * 没有分也得列表查询
	 * @param pageNum
	 * @param pageSize
	 * @param ${modelClass}
	 * @return
	 */
	public List<${modelClass}> list(${modelClass} ${modelName});
	public void create(${modelClass} ${modelName});
	public void update(${modelClass} ${modelName});
	public void delete(Integer id);
	public ${modelClass} findById(Integer id);
}

(d)继续完成CodeBuilder.java
完整的代码:

package com.zq.code;

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Properties;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;

public class CodeBuilder {

	public static void main(String[] args) {
		//new一下他的模版引擎
		VelocityEngine ve = new VelocityEngine();
		//设置模版和输出的代码文件的编码方式
		Properties p = new Properties();
		p.setProperty(Velocity.ENCODING_DEFAULT, "UTF-8");
		p.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
		p.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8");
		ve.init(p);//引擎初始化
		
		//引入一个模版,通过模版路径
		Template serviceVm = ve.getTemplate("/WebContent/WEB-INF/vm/service.vm");
		
		//定义占位符变量,给个值
		String modelClass = "Menu";
		String modelName = "menu";
		//生成的代码放置的目录==项目目录
		String rootPath = "C:/Users/Administrator/Desktop/shop/";//项目所在目录,按情况更改
		//变量放到上下文对象里
		VelocityContext ctx = new VelocityContext();
		ctx.put("modelClass", modelClass);
		ctx.put("modelName", modelName);
		
		//将占位符数据和模版合并,输出代码文件
		merge(serviceVm,ctx,rootPath + "src/com/zq/service/" + modelClass + "Service.java");
		System.out.println("success");
	}

	private static void merge(Template template,VelocityContext ctx,String path){
		PrintWriter writer = null;
		try{
			writer = new PrintWriter(path);
			//合并数据和模版,输出文件
			template.merge(ctx, writer);
			writer.flush();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			writer.close();
		}
	}
}

(e)在vm文件夹下新建一个serviceImpl.vm

package com.zq.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zq.dao.${modelClass}Dao;
import com.zq.model.${modelClass};

@Service
public class ${modelClass}ServiceImpl implements ${modelClass}Service {
	
	@Autowired
	private ${modelClass}Dao ${modelClass}Dao;

	@Override
	public PageInfo<${modelClass}> list(Integer pageNum,Integer pageSize,${modelClass} ${modelName}) {
		PageHelper.startPage(pageNum, pageSize);
		List<${modelClass}> list =  ${modelClass}Dao.list(${modelClass});
		PageInfo<${modelClass}> pageInfo = new PageInfo<${modelClass}>(list);
		
		return pageInfo;
	}
	
	@Override
	public List<${modelClass}> list(${modelClass} ${modelName}) {
		List<${modelClass}> list =  ${modelName}Dao.list(${modelClass});
		return pageInfo;
	}

	@Override
	public void create(${modelClass} ${modelName}) {
		if(${modelName}.getId()!=null && ${modelName}.getId()!=0){
			//修改
			${modelName}Dao.update(${modelName});
		}else{
			//新增操作
			${modelName}Dao.create(${modelName});
		}
	}

	@Override
	public void update(${modelClass} ${modelName}) {
		${modelName}Dao.update(${modelName});
	}

	@Override
	public void delete(Integer id) {
		${modelName}Dao.delete(id);
	}


	@Override
	public ${modelClass} findById(Integer id) {
		return ${modelClass}Dao.findById(id);
	}
	
}

(f)在CodeBuilder.java下,完成service实现类的代码

//service实现类的
		Template serviceImplVm = ve.getTemplate("/WebContent/WEB-INF/vm/serviceImpl.vm");
		merge(serviceImplVm,ctx,rootPath + "src/com/zq/service/" + modelClass + "ServiceImpl.java");

(g)完成dao.vm

package com.zq.dao;

import java.util.List;

import com.github.pagehelper.PageInfo;
import com.zq.model.${modelClass};

public interface ${modelClass}Dao {

	/**
	 * 没有分也得列表查询
	 * @param pageNum
	 * @param pageSize
	 * @param ${modelClass}
	 * @return
	 */
	public List<${modelClass}> list(${modelClass} ${modelName});
	public void create(${modelClass} ${modelName});
	public void update(${modelClass} ${modelName});
	public void delete(Integer id);
	public ${modelClass} findById(Integer id);
}

(h)在CodeBuilder.java下,完成dao的代码

		//dao的
		Template daoVm = ve.getTemplate("/WebContent/WEB-INF/vm/dao.vm");
		merge(daoVm,ctx,rootPath + "src/com/zq/dao/" + modelClass + "Dao.java");
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
由《Ext JS源码分析与开发实例宝典》作者:彭仁夔团队开发而成 根据数据模型(如数据库、PDM等)可以生成直接运行的SSH项目,初始化数据库数据等。在当前的模板中生成完善的CRUD操作,生成验证,根据不同的类型生成富文本,日历、树表结构等,并且还能生成完善强大的的实现权限系统。 功能之强大用了就知道! 两年前,我负责指导Java方向实训,在最后评审准备过程,.Net组负责人要求Java和.Net的归结一起统一评审,Java指导老师们的第一反应是Java和.Net开始怎么能相提并论? 为什么不能并论?是因为Java开发阳春白雪?在我们的潜意识中,Java开发就是让程序员(学生)一行一行地编写代码,编写HTML、CSS等,而.Net开发只要把控件拖到页面上即可,Java开发的效率一定比.Net低很多很多。 那么能不能提高Java的开发效率呢?作者经过分析并总结思考,发现业务系统有一定的共性所有操作,即增删改查,既然有共性,那么能不能抽象出来? 可以思考一下,通过继承、组件化等重用设计方式是可以抽象代码的共性,但是不同表(实体)增删改查的内容是不同的,通过泛型也很难抽象出来的。如对于A表的查询和对于B表的查询都需要使用到SQL语句,怎么去剥离出来? 此时,我们就需要采用另外一种方式,把它们抽象出来更高层级的模板,然后把不同数据传入该模板的占位符,这样就变成不同的代码,这种方式就是代码生成技术。 在软件的设计过程中,代码生成及重用设计仿若陌路人,互相排斥。重用设计中很多的共性是不能抽象出来的,而一味追求生成,造成大量的雷同代码,是重用设计人员或真正开发人员最不能容忍的事件。 如果把它们两个结合起来,那就是完全不同的效果,首先通过重用设计抽象其能抽象的代码,其不能抽象的共性通过生成技术生成,开发效率就会成倍增加。以前我们都是在X或y轴上分别进行,其最大的点也不过是线,如果两者结合起来,其变成一个平面,把我们的重用从点提高到面。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值