JFinal使用技巧-Enjoy魔板代码生成器

^_^ 搞事情~ 要趁早!   demo生成器还不能满足你? 需要service 需要 Controller吗?

1~ 核心动力

package com.momathink.tpp;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import com.jfinal.kit.Kv;
import com.jfinal.kit.PathKit;
import com.jfinal.template.Engine;

/***
 * jfinal魔板引擎
 * @author dufuzhong
 */
public class JfEnjoy {

    /**
     * 根据具体魔板生成文件
     * @param templateFileName  模板文件名称
     * @param kv                渲染参数
     * @param filePath          输出目录
     * @return 
     */
    public boolean render(String templateFileName, Kv kv, StringBuilder filePath)  {
        BufferedWriter output = null;
        try {
            String baseTemplatePath = new StringBuilder(PathKit.getRootClassPath())
            .append("/")
            .append(PathKit.getPackagePath(this))
            .append("/tpl")
            .toString();
            
            File file = new File(filePath.toString());
            
            File path = new File(file.getParent());
            if ( ! path.exists() ) {
                path.mkdirs();
            }
            output = new BufferedWriter(new FileWriter(file));
            
            Engine.use()
            .setBaseTemplatePath(baseTemplatePath)
            .getTemplate(templateFileName)
            .render(kv, output);
            
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }finally{
            try { if( output != null ) output.close(); } catch (IOException e) {}
        }
    }
    
    /**
     * 根据自定义内容生成文件
     * @param data              自定义内容
     * @param filePath          输出目录
     * @return 
     */
    public boolean render(String data, StringBuilder filePath)  {
        BufferedWriter output = null;
        try {
            
            File file = new File(filePath.toString());
            
            File path = new File(file.getParent());
            if ( ! path.exists() ) {
                path.mkdirs();
            }
            output = new BufferedWriter(new FileWriter(file));
            
            output.write(data);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }finally{
            try { if( output != null ) output.close(); } catch (IOException e) {}
        }
    }

}


2~ 业务开跑

package com.momathink.tpp;

import java.util.List;

import javax.sql.DataSource;

import com.demo.common.model._JFinalDemoGenerator;
import com.jfinal.kit.Kv;
import com.jfinal.kit.PathKit;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.activerecord.generator.DataDictionaryGenerator;
import com.jfinal.plugin.activerecord.generator.MetaBuilder;
import com.jfinal.plugin.activerecord.generator.TableMeta;

/**
 * 代码生成器
 * @author dufuzhong
 */
public class JfGenerator {
    
    public static final JfGenerator me  = new JfGenerator();
    protected final JfEnjoy jfEngine    = new JfEnjoy();
    
    protected Kv tablemetaMap       = null;
    protected String packageBase    = "com.momathink";
    protected String srcFolder      = "src";
    protected String viewFolder     = "_view";
    protected String basePath       = "";
    
    public JfGenerator setPackageBase(String packageBase){
        this.packageBase = packageBase;
        return this;
    }
    
    public JfGenerator setBasePath(String basePath){
        this.basePath = basePath;
        return this;
    }
    
    public JfGenerator setSrcFolder(String srcFolder){
        this.srcFolder = srcFolder;
        return this;
    }
    
    public JfGenerator setViewFolder(String viewFolder){
        this.viewFolder = viewFolder;
        return this;
    }
    
    protected class DataGenerator extends DataDictionaryGenerator {
        public DataGenerator(DataSource dataSource, String dataDictionaryOutputDir) {
            super(dataSource, dataDictionaryOutputDir);
        }
        public void rebuildColumnMetas(List<TableMeta> tableMetas) {
            super.rebuildColumnMetas(tableMetas);
        }
    };
    
    public TableMeta getTableMeta(String tableName){
        if( tablemetaMap == null ){
            
            DataSource dataSource = _JFinalDemoGenerator.getDataSource();
            
            MetaBuilder metaBuilder = new MetaBuilder(dataSource);
            metaBuilder.setDialect(new MysqlDialect());
            //metaBuilder.addExcludedTable(_JFinalDemoGenerator.excludedTable);
            List<TableMeta> tableMetas = metaBuilder.build();
            new DataGenerator(dataSource, null).rebuildColumnMetas(tableMetas);
            
            if (tableMetas.size() == 0) {
                System.out.println("TableMeta 数量为 0,不生成任何文件");
                return null;
            }
            Kv kv = Kv.create();
            for (TableMeta tableMeta : tableMetas) {
                kv.set(tableMeta.name, tableMeta);
            }
            tablemetaMap = kv;
        }
        return (TableMeta) tablemetaMap.get(tableName);
    }
    
    /**
     * 生成手脚架代码
     */
    public JfGenerator allRender(String className, String tableName) {
        return javaRender(className, tableName).htmlRender(className, tableName);
    }
    
    /**
     * java 代码生成
     * */
    public JfGenerator javaRender(String className, String tableName) {
        //刷新 映射对象
        _JFinalDemoGenerator.main(null);
        
        controller(className);
        validator(className);
        service(className , tableName);
        return this;
    }
    
    private String toClassNameSmall(String className) {
        return new StringBuffer(className.substring(0, 1).toLowerCase()).append(className.substring(1)).toString();
    }
    
    private String toPackages(String className) {
        return new StringBuffer(packageBase).append(".").append(basePath)
                .append(".").append(className.toLowerCase()).toString();
    }
    
    /**
     * 生成Controller
     * @param className         类名称
     */
    public void controller(String className){
        String packages = toPackages(className);
        
        String classNameSmall = toClassNameSmall(className);
        
        jfEngine.render("/java/controller.html", 
                Kv.by("package", packages)
                .set("className", className)
                .set("classNameSmall", classNameSmall)
                .set("basePath", basePath )
                , 
                new StringBuilder()
                .append(System.getProperty("user.dir"))
                .append("/")
                .append(srcFolder)
                .append("/")
                .append(packages.replace(".", "/"))
                .append("/")
                .append(className)
                .append("Controller.java")
                );
    }
    
    /**
     * 生成validator
     * @param className         类名称
     */
    public void validator(String className){
        String packages = toPackages(className);
        
        String classNameSmall = toClassNameSmall(className);
        
        jfEngine.render("/java/validator.html", 
                Kv.by("package", packages)
                .set("className", className)
                .set("classNameSmall", classNameSmall)
                , 
                new StringBuilder()
                .append(System.getProperty("user.dir"))
                .append("/")
                .append(srcFolder)
                .append("/")
                .append(packages.replace(".", "/"))
                .append("/")
                .append(className)
                .append("Validator.java")
                );
    }
    
    /**
     * 生成Service
     * @param className         类名称
     * @param tableName         表名
     */
    public void service(String className, String tableName){
        String packages = toPackages(className);

        String classNameSmall = toClassNameSmall(className);
        
        jfEngine.render("/java/service.html", 
                Kv.by("package", packages)
                .set("className", className)
                .set("classNameSmall", classNameSmall)
                .set("tableName", tableName)
                , 
                new StringBuilder()
                .append(System.getProperty("user.dir"))
                .append("/")
                .append(srcFolder)
                .append("/")
                .append(packages.replace(".", "/"))
                .append("/")
                .append(className)
                .append("Service.java")
                );
    }
    
    /**
     * @param className 
     * @param tableName 
     * */
    public JfGenerator htmlRender(String className, String tableName){
        TableMeta tablemeta = getTableMeta(tableName);
        
        htmlList(className, tablemeta);
        
        return this;
    }
    
    //页面的生成一般定制比较多..就来个简单的吧
    
    public void htmlList(String className, TableMeta tablemeta){
        String packages = toPackages(className);
        String classNameSmall = toClassNameSmall(className);
        String basePathUrl = basePath.replace('.', '/');
        
        jfEngine.render("/html/list.html", 
                Kv.by("tablemeta", tablemeta)
                .set("package", packages)
                .set("className", className)
                .set("classNameSmall", classNameSmall)
                .set("basePath", basePathUrl )
                , 
                new StringBuilder()
                .append(PathKit.getWebRootPath())
                .append("/")
                .append(viewFolder)
                .append("/")
                .append(basePathUrl)
                .append("/")
                .append(classNameSmall)
                .append("/")
                .append(classNameSmall)
                .append("List.html")
                );
    }
    
    // ... 继续扩展吧~
    
    
}


3~  爽的不要不要~ 放两三个模版事例吧...  我这边的模版和业务关联的比较多了, 几乎没什么通用的了,,,, 自己业务扩展吧~

图片.png

package #(package);

import com.jfinal.aop.Before;
import com.jfinal.core.Controller;
import com.demo.common.model.#(className);

/**
 * #(className) 管理    
 * 描述:
 * 
 */
public class #(className)Controller extends Controller {

    //private static final Log log = Log.getLog(#(className)Controller.class);
    
    static #(className)Service srv = #(className)Service.me;
    
    /**
     * 列表
     * /#(basePath)/#(classNameSmall)/list
     */
    public void list() {
        setAttr("page", srv.paginate(getParaToInt("p", 1), 40));
        render("#(classNameSmall)List.html");
    }
    
    /**
     * 准备添加
     * /#(basePath)/#(classNameSmall)/add
     */
    public void add() {
        render("#(classNameSmall)Add.html");
    }
    
    /**
     * 保存
     * /#(basePath)/#(classNameSmall)/save
     */
    @Before({#(className)Validator.class})
    public void save() {
        srv.save(getModel(#(className).class));
        renderJson("isOk", true);
    }

    /**
     * 准备更新
     * /#(basePath)/#(classNameSmall)/edit
     */
    public void edit() {
        #(className) #(classNameSmall) = srv.findById(getParaToInt("id"));
        setAttr("#(classNameSmall)", #(classNameSmall));
        render("#(classNameSmall)Edit.html");
    }

    /**
     * 更新
     * /#(basePath)/#(classNameSmall)/update
     */
    @Before(#(className)Validator.class)
    public void update() {
        srv.update(getModel(#(className).class));
        renderJson("isOk", true);
    }

    /**
     * 查看
     * /#(basePath)/#(classNameSmall)/view
     */
    public void view() {
        #(className) #(classNameSmall) = srv.findById(getParaToInt("id"));
        setAttr("#(classNameSmall)", #(classNameSmall));
        render("#(classNameSmall)View.html");
    }
     
    /**
     * 删除
     * /#(basePath)/#(classNameSmall)/delete
     */
    public void delete() {
        srv.delete(getParaToInt("id"));
        renderJson("isOk", true);
    }
    
}
package #(package);

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.demo.common.model.#(className);

/**
 * #(className) 管理    
 * 描述:
 */
public class #(className)Service {

    //private static final Log log = Log.getLog(#(className)Service.class);
    
    public static final #(className)Service me = new #(className)Service();
    private final #(className) dao = new #(className)().dao();
    
    
    /**
    * 列表-分页
    */
    public Page<#(className)> paginate(int pageNumber, int pageSize) {
        return dao.paginate(pageNumber, pageSize, "SELECT * ", "FROM #(tableName)");
    }
    
    /**
    * 保存
    */
    public void save(#(className) #(classNameSmall)) {
        #(classNameSmall).save();
    }
    
    /**
    * 更新
    */
    public void update(#(className) #(classNameSmall)) {
        #(classNameSmall).update();
    }
    
    /**
    * 查询
    */
    public #(className) findById(int #(classNameSmall)Id) {
        return dao.findFirst("select * from #(tableName) where id=?", #(classNameSmall)Id);
    }
    
    /**
    * 删除
    */
    public void delete(int #(classNameSmall)Id) {
        Db.update("delete from #(tableName) where id=?", #(classNameSmall)Id);
    }
    
    
}

// 其他模版就不放了, 自己扩展吧~~

再放个页面的吧 , 比较有代表性

/tpl/html/list.html

#("#")@adminLayout()
#("#")define main()
<div class="admin-content-box">
    <!-- 列表 -->
    <div class="jf-admin-panel-box">
        <div>
            <button class="layui-btn" onclick="showFancyBox('/#(basePath)/#(classNameSmall)/add">添加#(tablemeta.remarks)</button>
        </div>
        <table class="layui-table" lay-skin="line">
          <thead>
            <tr>
               #for(x : tablemeta.columnMetas)
              <th>#(x.remarks)</th>
            #end
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
           #("#")for(x : page.list)
            <tr>
                #for(x : tablemeta.columnMetas)
                  <td>#("#")(x.#(x.name))</td>
                  #end
              <td>
                    <span onclick="showFancyBox('/#(basePath)/#(classNameSmall)/view?id=#("#")(x.id)')">查看</span>
                    <span onclick="showFancyBox('/#(basePath)/#(classNameSmall)/edit?id=#("#")(x.id)')">更新</span>
                    <span onclick="showFancyBox('/#(basePath)/#(classNameSmall)/delete?id=#("#")(x.id)')">删除</span>
              </td>
            </tr>
           #("#")end
          </tbody>
        </table>

        #("#")@paginate(accountPage.pageNumber, accountPage.totalPage, "/#(basePath)/#(classNameSmall)/list?p=")

    </div>

</div>
#("#")end

#("#")define css()

#("#")end

#("#")define js()

    <script type="text/javascript">

    </script>
#("#")end


这个功能包建在外面, 再Build Path进去, 算是可插拔哦~
图片.png

码云:
https://git.oschina.net/bean80/tpp.git


评论区

杜福忠

2017-08-04 00:27

public class _TppTest {

public static void main(String[] args) {

String className = "Blog";
String tableName = "blog";

JfGenerator.me
.setPackageBase("com")
.setBasePath("demo")
//.setViewFolder("")
.javaRender(className, tableName)
.htmlRender(className, tableName);

System.out.println("---------OK-刷新一下项目吧---------");
}

}

极客

2017-08-04 09:26

支持大神

嘉佑丶

2017-08-04 10:06

很会搞事情嘛 6666

l745230

2017-08-04 10:21

这个好,支持下

海哥

2017-08-04 10:55

支持大神,好东西。

JFinal

2017-08-04 11:11

这种生成代码的方法太爽了,这些代码可以直接搞一个开源项目出来了,分分钟的事啊

JFinal

2017-08-04 11:13

此外模板文件可以与项目一起打包在 jar 之中,用一下 Enjoy 3.2 的这个用法:
engine.setSourceFactory(new ClassPathSourceFactory())

这个配置可以让你的程序去 class path 与 jar 包之中去找模板文件,十分的爽

XiaoFei

2017-08-04 11:17

牛人,支持

append

2017-08-04 11:17

6的一匹

jiren

2017-08-04 11:18

社区有你,更美好

puyu

2017-08-04 11:19

赞一个。

jounzhang

2017-08-04 11:19

超赞

不知所以

2017-08-04 11:20

必须赞一波

jiren

2017-08-04 11:25

做成开源工程吧.

zzhkiller

2017-08-04 11:25

哥 你会玩

马小酱

2017-08-04 17:12

大神好

EayonChioa

2017-08-05 23:22

给你82分,其它的给你666!

tywo45

2017-08-06 09:51

你这么牛,你老婆知道吗?

弯道加速跑

2017-08-06 13:44

mark一下备用

Irin.Chan

2017-08-06 17:47

赞一个, 基于JFinal Template的代码生成器,在3.0开始就写了,用到现在,从model、service、controller到页面html、还有js都是一键生成。
Enjoy单独出来,现在可以到处用,一个字爽。

凉凉凉凉凉

2017-08-07 09:46

抱大腿了。。

laolang

2017-08-10 09:14

这技能,太牛了!

mscedifier

2017-08-10 11:02

好东西 必须顶。。。

高达1234

2017-08-15 08:54

写模板用的什么语法?beetl吗?

杜福忠

2017-08-15 13:42