文档章节

当小白遇到--代码生成器

z
 zxszxs
发布于 2017/08/11 18:32
字数 1059
阅读 89
收藏 3
点赞 0
评论 0

这两天刚刚接触了一个叫代码生成器的东西,太神奇了,以后不用写代码了吗?

呵呵呵......程序员不写代码干什么?

前言:

大家都知道,在做业务开发的时候,通常的模式都是如下过程:

  1. 先按业务需要建立好数据库表
  2. 按数据库表分别实现它们相关的 Entity , Dao , Service, Controller , Dao层等,解决数据的基本操作,如增删查改等基本的数据操作。
  3. ......

然而第二部分这些细活往往比较简单且没有挑战性,纯粹苦力活。能不能有一个模板,直接一键生成上面的一些基本的操作呢?

那是肯定的。

预备知识:

 实现思路:

首先我们请来了强大的模板引擎:FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件配置文件源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

然后在其基础上按数据库表的结构建立它们相关的 Entity , Dao , Service, Controller , Dao层等的模板。

通过数据库表和模板生成相应的Entity , Dao , Service, Controller , Dao层等。

代码实例:

以数据库表:test表为例:

CREATE TABLE `test`(
  `id` varchar(64) NOT NULL COMMENT'ID',
  `content` text NOT NULL COMMENT'描述',
  PRIMARY KEY (`id`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

将test表建立基础数据模板:test.yml

# 示例数据

author: "Cedar"
package: "com.zxs.application" #生成包名
domain: "test"
# 属性列表
fields:
    -
        description: "id"
        type: String
        java:
            name: id
            type: String
        db:
            name: id
            type: varchar
            length: 64
            notnull: true
        view:
            name: id
            input_type: text_area
        validator: {}
    -
        description: "描述"
        type: String # 业务类型, 还有 url,数字,ip地址,中国手机号码, 数据校验的第一项??
        java:
            name: content
            type: String
        db:
            name: content
            type: text
            notnull: true   # 是不是重复的?
        view:
            name: content # 可以用默认值
            input_type: simple_text       # input[text], input[email] ?? simple_text, email, url, select, radio
            search_type: simple_text_like       # 可以用默认, simple_text_like, simple_text_eq, simple_select, multiple_select
        validator:
            notblank: {}
    

基础代码模板:

  • Dao层:dao.template
package ${package}.dao;

import ${package}.Basedao;
import ${package}.entity.${domain?cap_first}Eentity;
@MybatisDao
public interface ${domain?cap_first}Dao extends BaseDao<${domain?cap_first}Eentity> {

}
  • Entity层:entity.template
package ${package}.entity;

/**
 * ${domain?cap_first}Entity
 */
public class ${domain?cap_first} {

<#list fields as field>
    private ${field.java.type} ${field.java.name};
</#list>

<#list fields as field>

    public ${field.java.type} get${field.java.name?cap_first}() {
        return this.${field.java.name};
    }

    public void set${field.java.name?cap_first}(${field.java.type} ${field.java.name}) {
        this.${field.java.name} = ${field.java.name};
    }
</#list>
}
  • Controller层:controller.template
package ${package}.web;

import ${package}.entity.${domain?cap_first}Eentity;
import ${package}.service.${domain?cap_first}Service;
import info.ideatower.infra.shared.query.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * ${domain?cap_first}
 */
@Controller
@RequestMapping("/${domain}")
public class ${domain?cap_first}Controller {

    @Autowired
    private ${domain?cap_first}Service ${domain}Service;

    /**
     * ${domain?cap_first}列表页
     * @param model
     * @return
     */
    @GetMapping(value = {"", "/list"})
    public String index(Model model) {
        Page page = this.${domain}Service.selectPage(Page.DEFAULT,null);
        model.addAttribute("page", page);
        return "/${domain}/list";
    }

    /**
     * ${domain?cap_first}创建页面
     * @return
     */
    @GetMapping("/create")
    public String create(Model model) {
        model.addAttribute(new ${domain?cap_first}());
        return "/${domain}/edit";
    }

    /**
     * ${domain?cap_first}创建操作
     * @param ${domain}
     * @return
     */
    @PostMapping("/create")
    public String createForm(${domain?cap_first}Eentity ${domain}Eentity) {
        this.${domain}Service.insert(${domain});
        return "redirect:/${domain}?repage";
    }

    /**
     * ${domain?cap_first}编辑页面
     * @param id ${domain?cap_first}标识
     * @param model
     * @return
     */
    @GetMapping("/{id}")
    public String edit(
            @PathVariable(value = "id", required = true) String id,
            Model model) {
        ${domain?cap_first}Eentity ${domain}Eentity = this.${domain}Service.selectById(id);
        model.addAttribute("${domain}", ${domain});
        return "/${domain}/edit";
    }

    /**
     * ${domain?cap_first}编辑
     * @param id ${domain?cap_first}标识
     * @param ${domain} ${domain?cap_first}数据
     * @return
     */
    @PostMapping("/{id}")
    public String editForm(
            @PathVariable(value = "id", required = true) String id,
            ${domain?cap_first}Eentity ${domain}Eentity) {
        this.${domain}Service.updateById(${domain});
        return "redirect:/${domain}?repage";
    }

    /**
     * ${domain?cap_first}删除
     * @param id
     * @return
     */
    @DeleteMapping("/{id}")
    public String remove(@PathVariable(value = "id", required = true) String id) {
        this.${domain}Service.deleteById(id);
        return "redirect:/${domain}?repage";
    }

}
  • service层:service.template
package ${package}.service;

import ${package}.dao.${domain?cap_first}Dao;
import ${package}.entity.${domain?cap_first}Eentity;
import ${package}.service.BaseService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional( readOnly = false)
public class ${domain?cap_first}Service extends BaseService<${domain?cap_first}Dao, ${domain?cap_first}Eentity> {

}

配置文件:base.yml


source:
     data: data
     template: template
dest: dest
encoding: UTF-8

# datasource
# path could specify both file path and directory path
#datasource:
#    type: "jdbc"
#    user: "simple.yml"
#    password: "xxx"
#    include: ['single', 'multiple']
#    exclude: [

# excel datasource
# datasource:
#    type: "excel"
#    map:
#        A: "erector"
#        B: "build"

datasource:
    type: "yaml"
    include: ["single_one"]

# for plenty
template:
    -
        file: entity
        to: "src/test/entity/${domain?cap_first}Entity.java"
    -
        file: controller
        to: "src/test/web/${domain?cap_first}Controller.java"
    -
        file: service
        to: "src/test/service/${domain?cap_first}Service.java"
    -
        file: dao.class
        to: "src/test/dao/${domain?cap_first}Dao.java"
    -
        file: mybatis.mapping.xml
        to: "src/test/mybatis/${domain?cap_first}Dao.xml"
#    -
#        file: single
#        type: all
#        to: demo.html

 

未完待续。。。。

相关大神博客:

【1】Freemarker官网 
【2】可用于企业级开发的JAVA代码生成器 
【3】 一个java代码生成器的简单实现

© 著作权归作者所有

共有 人打赏支持
z
粉丝 1
博文 25
码字总数 21328
作品 0
遵义
非Hibernate代码如何使用Hibernate的UUIDHexGenerator

手上有一个工程,是其他的公司开发的,使用的是Hibernate,数据库每个表的ID他都设定成了uuid生成器。 因为开发商的Hibernate写的相当糟糕,很多无意义的关联查询。现在想把这部分功能逐渐改...

逝水fox ⋅ 2012/10/24 ⋅ 2

Python生成器(Generator)详解

这篇文章主要介绍了Python生成器(Generator)详解,本文讲解了什么是生成器、简单生成器、带yield 语句的生成器、加强的生成器等内容,需要的朋友可以参考下 通过列表生成式,我们可以直接创建...

丰_申 ⋅ 2016/10/12 ⋅ 0

MyBatis 代码生成器--Mybatis-Generator

mybatis.generator 解决问题 mybatis.generator 后续简称 dalgen,解决mybatis代码自动生成的缺失. 对比其他代码生成工具 mybatis-generator-maven-plugin mybatis比较官方的代码生成器,生成...

匆匆里 ⋅ 2017/09/13 ⋅ 1

【探秘ES6】系列专栏(三):生成器

ES6作为新一代JavaScript标准,即将与广大前端开发者见面。为了让大家对ES6的诸多新特性有更深入的了解,Mozilla Web开发者博客推出了《ES6 In Depth》系列文章。CSDN已获授权,将持续对该系...

一配 ⋅ 2015/10/27 ⋅ 0

Tornado 异步协程coroutine原理

协程定义: 协程,又称微线程,纤程。英文名Coroutine。 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行...

cooffeelis ⋅ 2017/12/27 ⋅ 0

理解生成器之 yield

生成器,当调用一个带有yield 语句的函数时,就产生了一个生成器。生成器是一种可迭代的对象,当生成器调用next() 方法时,它会运行到yield 语句,并且将yield 语句的值返回,并且将函数的变...

hello_cjq ⋅ 2016/10/12 ⋅ 0

TensorFlow应用实战-14-编写训练的python文件

编写训练的python文件 获取训练数据 将数据进行标准化 tanh的取值范围是-1 到 1 像素值最大255 减去一半127.5 再除以 127.5 被限制到-1到1之间。 构造生成器和判别器 构建生成器和判别器组成...

天涯明月笙 ⋅ 06/12 ⋅ 0

从python协程理解tornado异步

博客原文地址:http://www.v2steve.com/2015/05/31/python/pytornadoasync/ 刚接触tornado时候最疑惑的问题就是tornado.gen.coroutine是怎么实现的。如何在代码中用同步格式实现异步效果。看...

__Steve__ ⋅ 2015/05/31 ⋅ 0

第十二次课:Python函数(三)

列表生成式 列表生成式是Python函数的高级特性,顾名思义就是用来创建列表(list)的生成式。 基础语法: [exp for iter_var in iterable] 如[x * x for x in range(1, 11)] 就是一个列表生成...

dyqd2011 ⋅ 2017/11/03 ⋅ 0

【探秘ES6】系列专栏(十):更深入了解生成器

ES6作为新一代JavaScript标准,已正式与广大前端开发者见面。为了让大家对ES6的诸多新特性有更深入的了解,Mozilla Web开发者博客推出了《ES6 In Depth》系列文章。CSDN已获授权,将持续对该...

一配 ⋅ 2015/11/13 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

vuex学习

1、getters基本用法: 在store.js里面用const声明我们的getters属性。 const getters={ count:function (state) { return state.count +=100; }} export default new Vuex.S......

大美琴 ⋅ 40分钟前 ⋅ 0

292. Nim Game - LeetCode

Question 292. Nim Game Solution 思路:试着列举一下,就能发现一个n只要不是4的倍数,就能赢。 n 是否能赢1 true2 true3 true4 false 不论删除几,对方都能一把赢5 t...

yysue ⋅ 52分钟前 ⋅ 0

G6 关系数据可视化图形库 简单使用

官网 https://antv.alipay.com/zh-cn/g6/1.x/index.html 效果 首先生成给定数目的小球,并设置随机的颜色 按照顺序,设置小球的角度以及坐标 设置定时器,每隔一定的时间修改小球的角度和坐标...

阿豪boy ⋅ 54分钟前 ⋅ 0

6.5 zip压缩工具 6.6 tar打包 6.7 打包并压缩

zip压缩工具 zip命令可以压缩目录和文件,-r 压缩目录。 zip使用方法 zip 1.txt.zip 1.txt //压缩文件 zip -r 123.zip 123/ //压缩目录 unzip 1.txt.zip //解压 unzip 123.zip -d /root/456...

Linux_老吴 ⋅ 今天 ⋅ 0

react-loadable使用跳坑

官方给react-loadable的定义是: A higher order component for loading components with dynamic imports. 动态路由示例 withLoadable.js import React from 'react'import Loadable fro......

pengqinmm ⋅ 今天 ⋅ 0

记录工作中遇到的坑

1、ios safari浏览器向下滚动会触发window resize事件

端木遗风 ⋅ 今天 ⋅ 0

桥接设计模式

1、概述: 将抽象部分与他的实现部分分离,这样抽象化与实现化解耦,使他们可以独立的变化 如何实现解耦的呢,就是通过提供抽象化和实现化之间的桥接结构 桥接模式将继承模式转化成关联关系,他降...

职业搬砖20年 ⋅ 今天 ⋅ 0

20.zip压缩 tar打包 打包并压缩

6月25日任务 6.5 zip压缩工具 6.6 tar打包 6.7 打包并压缩 6.5 zip压缩工具: zip支持压缩目录 zip压缩完之后原来的文件不删除 不同的文件内容其实压缩的效果不一样 文件内有很多重复的用xz压...

王鑫linux ⋅ 今天 ⋅ 0

double类型数据保留四位小数的另一种思路

来源:透析公式处理,有时候数据有很长的小数位,有的时候由在四位以内,如果用一般的处理方法,那么不足四位的小树会补充0到第四位,这样子有点画蛇添足的感觉,不太好看。所以要根据小数的...

young_chen ⋅ 今天 ⋅ 0

Django配置163邮箱出现 authentication failed(535)错误解决方法

最近用Django写某网站,当配置163邮箱设置完成后,出现535错误即:smtplib.SMTPAuthenticationError: (535, b'Error: authentication failed') Django初始配置邮箱设置 EMAIL_HOST = "smtp.1...

陈墨轩_CJX ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部