Java之利用Freemarker模板引擎实现代码生成器,提高效率

http://blog.csdn.net/huangwenyi1010/article/details/71249258

目录(?)[-]

  1. 开心一笑
  2. 视频教程
  3. 提出问题
  4. 解决问题
    1. 前言
    2. 技术选型
    3. 实现思路
      1. 首先假如在数据库中有一张表 ay_test
      2. 我们首先要获取数据库的连接这里我只贴出相关的代码
      3. 获取数据库表的元数据
      4. 最后根据元数据获取表字段注释等等生成相关的文件
    4. 代码实现
      1. Java代码实现
        1. FreeMarkerTemplateUtils工具类
        2. 实体类 ColumnClass
      2. freemarker 模板文件
        1. Modelftl模型模板
        2. DTOftl模板
        3. Serviceftl模板
        4. Interfaceftl 模板
        5. Respontoryftl 模板
        6. Mappterftl 模板
        7. Controllerftl 模板
      3. 读书感悟
      4. 经典故事
      5. 大神文章
      6. 其他

开心一笑

【1.你以为我会眼睁睁的看着你去送死?我会闭着眼睛。2.给你讲个故事,从前有个笨蛋,他非常笨,别人问他问题他只会回答“没有”,这个故事你听过吗?】

视频教程

大家好,我录制的视频《Java之优雅编程之道》已经在CSDN学院发布了,有兴趣的同学可以购买观看,相信大家一定会收获到很多知识的。谢谢大家的支持……

视频地址:http://edu.csdn.net/lecturer/994

提出问题

如何利用 Java + Freemarker 实现代码生成器???

解决问题

* 前言 *

做业务开发的时候,经常要根据建立好的数据库表,生成相关的 Model , DTO , Service, Controller , DAO 等等。包括基本的增删改查。而这些细活往往比较简单且没有挑战性,纯粹苦力活。因此,根据公司的框架,开发一个代码生成器是很有必要的。

这里: 
假如你有一定的java基础; 
假如你熟悉freemarker模板引擎; 
假如你熟悉MVC框架; 
假如你熟悉Spring Data 框架

* 技术选型 *

由于代码生成器是要生成很多文件的,包 Test.java , TestDTO.java ,TestController.java , TestServiceImpl.java , ITestService.java , TestDAO.java 等等这些文件。所有考虑用 freemarker 强大的模板引擎,制作相关的模板。

* 实现思路 *

首先,假如在数据库中有一张表 ay_test.

CREATE TABLE "public"."ay_test" (
    "id" varchar(32) COLLATE "default" NOT NULL,
    "name" varchar(10) COLLATE "default",
    "birth_date" timestamp(6),
    "remark" text COLLATE "default",
    CONSTRAINT "ay_test_pkey" PRIMARY KEY ("id")
)

我们首先要获取数据库的连接,这里我只贴出相关的代码。

private final String URL = "jdbc:postgresql://192.168.3.160:10655/cibpm";
private final String USER = "postgres";
private final String PASSWORD = "888888";
private final String DRIVER = "org.postgresql.Driver";

public Connection getConnection() throws Exception{
    Class.forName(DRIVER);
    Connection connection= DriverManager.getConnection(URL, USER, PASSWORD);
    return connection;
}

获取数据库表的元数据

private final String changeTableName = replaceUnderLineAndUpperCase(tableName);

Connection connection = getConnection();
DatabaseMetaData databaseMetaData = connection.getMetaData();
ResultSet resultSet = databaseMetaData.getColumns(null,"%", tableName,"%");

最后根据元数据获取表字段,注释等等,生成相关的文件

代码实现

Java代码实现

package com.evada.inno.pm.code.generate.util;
import com.evada.inno.pm.code.generate.model.ColumnClass;

import freemarker.template.Template;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 描述:代码生成器
 * Created by Ay on 2017/5/1.
 */
public class CodeGenerateUtils {

    private final String AUTHOR = "Ay";
    private final String CURRENT_DATE = "2017/05/03";
    private final String tableName = "tm_project_quality_problem";
    private final String packageName = "com.evada.pm.process.manage";
    private final String tableAnnotation = "质量问题";
    private final String URL = "jdbc:postgresql://192.168.3.160:10655/cibpm";
    private final String USER = "postgres";
    private final String PASSWORD = "888888";
    private final String DRIVER = "org.postgresql.Driver";
    private final String diskPath = "D://";
    private final String changeTableName = replaceUnderLineAndUpperCase(tableName);

    public Connection getConnection() throws Exception{
        Class.forName(DRIVER);
        Connection connection= DriverManager.getConnection(URL, USER, PASSWORD);
        return connection;
    }

    public static void main(String[] args) throws Exception{
        CodeGenerateUtils codeGenerateUtils = new CodeGenerateUtils();
        codeGenerateUtils.generate();
    }

    public void generate() throws Exception{
        try {
            Connection connection = getConnection();
            DatabaseMetaData databaseMetaData = connection.getMetaData();
            ResultSet resultSet = databaseMetaData.getColumns(null,"%", tableName,"%");
            //生成Mapper文件
            generateMapperFile(resultSet);
            //生成Dao文件
            generateDaoFile(resultSet);
            //生成Repository文件
            generateRepositoryFile(resultSet);
            //生成服务层接口文件
            generateServiceInterfaceFile(resultSet);
            //生成服务实现层文件
            generateServiceImplFile(resultSet);
            //生成Controller层文件
            generateControllerFile(resultSet);
            //生成DTO文件
            generateDTOFile(resultSet);
            //生成Model文件
            generateModelFile(resultSet);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally{

        }
    }

    private void generateModelFile(ResultSet resultSet) throws Exception{

        final String suffix = ".java";
        final String path = diskPath + changeTableName + suffix;
        final String templateName = "Model.ftl";
        File mapperFile = new File(path);
        List<ColumnClass> columnClassList = new ArrayList<>();
        ColumnClass columnClass = null;
        while(resultSet.next()){
            //id字段略过
            if(resultSet.getString("COLUMN_NAME").equals("id")) continue;
            columnClass = new ColumnClass();
            //获取字段名称
            columnClass.setColumnName(resultSet.getString("COLUMN_NAME"));
            //获取字段类型
            columnClass.setColumnType(resultSet.getString("TYPE_NAME"));
            //转换字段名称,如 sys_name 变成 SysName
            columnClass.setChangeColumnName(replaceUnderLineAndUpperCase(resultSet.getString("COLUMN_NAME")));
            //字段在数据库的注释
            columnClass.setColumnComment(resultSet.getString("REMARKS"));
            columnClassList.add(columnClass);
        }
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("model_column",columnClassList);
        generateFileByTemplate(templateName,mapperFile,dataMap);

    }

    private void generateDTOFile(ResultSet resultSet) throws Exception{
        final String suffix = "DTO.java";
        final String path = "D://" + changeTableName + suffix;
        final String templateName = "DTO.ftl";
        File mapperFile = new File(path);
        Map<String,Object> dataMap = new HashMap<>();
        generateFileByTemplate(templateName,mapperFile,dataMap);
    }

    private void generateControllerFile(ResultSet resultSet) throws Exception{
        final String suffix = "Controller.java";
        final String path = diskPath + changeTableName + suffix;
        final String templateName = "Controller.ftl";
        File mapperFile = new File(path);
        Map<String,Object> dataMap = new HashMap<>();
        generateFileByTemplate(templateName,mapperFile,dataMap);
    }

    private void generateServiceImplFile(ResultSet resultSet) throws Exception{
        final String suffix = "ServiceImpl.java";
        final String path = diskPath + changeTableName + suffix;
        final String templateName = "ServiceImpl.ftl";
        File mapperFile = new File(path);
        Map<String,Object> dataMap = new HashMap<>();
        generateFileByTemplate(templateName,mapperFile,dataMap);
    }

    private void generateServiceInterfaceFile(ResultSet resultSet) throws Exception{
        final String prefix = "I";
        final String suffix = "Service.java";
        final String path = diskPath + prefix + changeTableName + suffix;
        final String templateName = "ServiceInterface.ftl";
        File mapperFile = new File(path);
        Map<String,Object> dataMap = new HashMap<>();
        generateFileByTemplate(templateName,mapperFile,dataMap);
    }

    private void generateRepositoryFile(ResultSet resultSet) throws Exception{
        final String suffix = "Repository.java";
        final String path = diskPath + changeTableName + suffix;
        final String templateName = "Repository.ftl";
        File mapperFile = new File(path);
        Map<String,Object> dataMap = new HashMap<>();
        generateFileByTemplate(templateName,mapperFile,dataMap);
    }

    private void generateDaoFile(ResultSet resultSet) throws Exception{
        final String suffix = "DAO.java";
        final String path = diskPath + changeTableName + suffix;
        final String templateName = "DAO.ftl";
        File mapperFile = new File(path);
        Map<String,Object> dataMap = new HashMap<>();
        generateFileByTemplate(templateName,mapperFile,dataMap);

    }

    private void generateMapperFile(ResultSet resultSet) throws Exception{
        final String suffix = "Mapper.xml";
        final String path = diskPath + changeTableName + suffix;
        final String templateName = "Mapper.ftl";
        File mapperFile = new File(path);
        Map<String,Object> dataMap = new HashMap<>();
        generateFileByTemplate(templateName,mapperFile,dataMap);

    }

    private void generateFileByTemplate(final String templateName,File file,Map<String,Object> dataMap) throws Exception{
        Template template = FreeMarkerTemplateUtils.getTemplate(templateName);
        FileOutputStream fos = new FileOutputStream(file);
        dataMap.put("table_name_small",tableName);
        dataMap.put("table_name",changeTableName);
        dataMap.put("author",AUTHOR);
        dataMap.put("date",CURRENT_DATE);
        dataMap.put("package_name",packageName);
        dataMap.put("table_annotation",tableAnnotation);
        Writer out = new BufferedWriter(new OutputStreamWriter(fos, "utf-8"),10240);
        template.process(dataMap,out);
    }

    public String replaceUnderLineAndUpperCase(String str){
        StringBuffer sb = new StringBuffer();
        sb.append(str);
        int count = sb.indexOf("_");
        while(count!=0){
            int num = sb.indexOf("_",count);
            count = num + 1;
            if(num != -1){
                char ss = sb.charAt(count);
                char ia = (char) (ss - 32);
                sb.replace(count , count + 1,ia + "");
            }
        }
        String result = sb.toString().replaceAll("_","");
        return StringUtils.capitalize(result);
    }

}
FreeMarkerTemplateUtils工具类

FreeMarkerTemplateUtils工具类用来配置模板所在的路径

package com.evada.inno.pm.code.generate.util;

import com.evada.inno.core.exception.BusinessException;
import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.NullCacheStorage;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;

import java.io.IOException;

/**
 * Created by Ay on 2016/7/27.
 */
public class FreeMarkerTemplateUtils {

    private FreeMarkerTemplateUtils(){}
    private static final Configuration CONFIGURATION = new Configuration(Configuration.VERSION_2_3_22);

    static{
        //这里比较重要,用来指定加载模板所在的路径
        CONFIGURATION.setTemplateLoader(new ClassTemplateLoader(FreeMarkerTemplateUtils.class, "/templates"));
        CONFIGURATION.setDefaultEncoding("UTF-8");
        CONFIGURATION.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        CONFIGURATION.setCacheStorage(NullCacheStorage.INSTANCE);
    }

    public static Template getTemplate(String templateName) throws IOException {
        try {
            return CONFIGURATION.getTemplate(templateName);
        } catch (IOException e) {
            throw e;
        }
    }

    public static void clearCache() {
        CONFIGURATION.clearTemplateCache();
    }
}
实体类 ColumnClass

ColumnClass 用来封装 数据库表元数据的信息,如字段名称,字段类型,字段注释等等。

package com.evada.inno.pm.code.generate.model;

/**
 * 数据库字段封装类
 * Created by Ay on 2017/5/3.
 */
public class ColumnClass {

    /** 数据库字段名称 **/
    private String columnName;
    /** 数据库字段类型 **/
    private String columnType;
    /** 数据库字段首字母小写且去掉下划线字符串 **/
    private String changeColumnName;
    /** 数据库字段注释 **/
    private String columnComment;

    public String getColumnComment() {
        return columnComment;
    }

    public void setColumnComment(String columnComment) {
        this.columnComment = columnComment;
    }

    public String getColumnName() {
        return columnName;
    }

    public void setColumnName(String columnName) {
        this.columnName = columnName;
    }

    public String getColumnType() {
        return columnType;
    }

    public void setColumnType(String columnType) {
        this.columnType = columnType;
    }

    public String getChangeColumnName() {
        return changeColumnName;
    }

    public void setChangeColumnName(String changeColumnName) {
        this.changeColumnName = changeColumnName;
    }
}

freemarker 模板文件

Freemarker的模板文件,后缀都是以ftl结尾的。

Model.ftl模型模板

Model.ftl可以生成字段的属性,并且可以生成字段属性对应的 set 和 get 方法,包括字段在数据库中对应的注释,以及一些该引入的包和类注释。

package ${package_name}.model;
import com.evada.inno.common.domain.BaseModel;
import com.evada.inno.common.listener.ICreateListenable;
import com.evada.inno.common.listener.IDeleteListenable;
import com.evada.inno.common.listener.IModifyListenable;
import org.hibernate.annotations.Where;
import javax.persistence.*;
import java.util.Date;

/**
* 描述:${table_annotation}模型
* @author ${author}
* @date ${date}
*/
@Entity
@Table(name="${table_name_small}")
@Where(clause = "status > ‘0‘")
@Inheritance(strategy= InheritanceType.SINGLE_TABLE)
public class ${table_name} extends BaseModel implements ICreateListenable,IModifyListenable,IDeleteListenable {

    <#if model_column?exists>
        <#list model_column as model>
    /**
    *${model.columnComment!}
    */
    <#if (model.columnType = ‘varchar‘ || model.columnType = ‘text‘)>
    @Column(name = "${model.columnName}",columnDefinition = "VARCHAR")
    private String ${model.changeColumnName?uncap_first};

    </#if>
    <#if model.columnType = ‘timestamp‘ >
    @Column(name = "${model.columnName}",columnDefinition = "TIMESTAMP")
    private Date ${model.changeColumnName?uncap_first};

    </#if>
        </#list>
    </#if>

<#if model_column?exists>
<#list model_column as model>
<#if (model.columnType = ‘varchar‘ || model.columnType = ‘text‘)>
    public String get${model.changeColumnName}() {
        return this.${model.changeColumnName?uncap_first};
    }

    public void set${model.changeColumnName}(String ${model.changeColumnName?uncap_first}) {
        this.${model.changeColumnName?uncap_first} = ${model.changeColumnName?uncap_first};
    }

</#if>
<#if model.columnType = ‘timestamp‘ >
    public Date get${model.changeColumnName}() {
        return this.${model.changeColumnName?uncap_first};
    }

    public void set${model.changeColumnName}(Date ${model.changeColumnName?uncap_first}) {
        this.${model.changeColumnName?uncap_first} = ${model.changeColumnName?uncap_first};
    }

</#if>
</#list>
</#if>

}
DTO.ftl模板

DTO.ftl 文件用来生产 DTO 值对象,该对象继承 Model.ftl 文件中的对象。

package ${package_name}.dto;

import ${package_name}.model.${table_name};

/**
* 描述:${table_annotation}DTO
* @author ${author}
* @date ${date}
*/
public class ${table_name}DTO extends ${table_name}{

}
Service.ftl模板

Service.ftl 模板用来生成服务层实现类,在模板中已经添加了增 ,删,改,查等方法,同时可以注入DAO和repository 到service中,一旦文件生成,就不需要我们去写了,很方便,提高开发的效率。

package ${package_name}.service.impl;
import com.evada.inno.core.service.impl.BaseServiceImpl;
import ${package_name}.model.${table_name};
import ${package_name}.repository.${table_name}Repository;
import ${package_name}.service.I${table_name}Service;
import ${package_name}.repository.mybatis.${table_name}DAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ${package_name}.dto.${table_name}DTO;
import org.apache.commons.beanutils.BeanUtils;
import com.evada.inno.core.enums.StatusEnum;

/**
* 描述:${table_annotation} 服务实现层
* @author ${author}
* @date ${date}
*/
@Service
public class ${table_name}ServiceImpl extends BaseServiceImpl<${table_name}, String> implements I${table_name}Service {

    @Autowired
    private ${table_name}DAO ${table_name?uncap_first}DAO;

    @Autowired
    private ${table_name}Repository ${table_name?uncap_first}Repository;

    @Override
    public ${table_name}DTO findDTOById(String id) throws Exception {
        ${table_name}DTO ${table_name?uncap_first}DTO = ${table_name?uncap_first}DAO.findDTOById(id);
        return ${table_name?uncap_first}DTO;
    }

    @Override
    public ${table_name}DTO create${table_name}(${table_name}DTO ${table_name?uncap_first}DTO) throws Exception {
        ${table_name} ${table_name?uncap_first} = new ${table_name}();
        BeanUtils.copyProperties(${table_name?uncap_first},${table_name?uncap_first}DTO);
        ${table_name?uncap_first}.setStatus(StatusEnum.ENABLE.toString());
        ${table_name?uncap_first} = ${table_name?uncap_first}Repository.saveAndFlush(${table_name?uncap_first});
        return this.findDTOById(${table_name?uncap_first}.getId());
    }

    @Override
    public ${table_name}DTO update${table_name}(${table_name}DTO ${table_name?uncap_first}DTO)throws Exception {
        ${table_name} ${table_name?uncap_first} = new ${table_name}();
        BeanUtils.copyProperties(${table_name?uncap_first},${table_name?uncap_first}DTO);
        ${table_name?uncap_first} = ${table_name?uncap_first}Repository.saveAndFlush(${table_name?uncap_first});
        return this.findDTOById(${table_name?uncap_first}.getId());
    }
Interface.ftl 模板

Interface.ftl 用来生成服务层接口,接口中定义了增,删,改,查等接口。

package ${package_name}.service;
import com.evada.inno.core.service.IBaseService;
import ${package_name}.model.${table_name};
import ${package_name}.dto.${table_name}DTO;
/**
* 描述:${table_annotation} 服务实现层接口
* @author ${author}
* @date ${date}
*/
public interface I${table_name}Service extends IBaseService<${table_name},String> {

    /**
    * 描述:根据Id获取DTO
    * @param id
    */
    ${table_name}DTO findDTOById(String id)throws Exception;

    ${table_name}DTO create${table_name}(${table_name}DTO ${table_name?uncap_first}DTO) throws Exception;

    void delete${table_name}(String id) throws Exception;

    ${table_name}DTO update${table_name}(${table_name}DTO ${table_name?uncap_first}DTO) throws Exception;

}
Respontory.ftl 模板

Respontory.ftl 用来生成 Repository 文件,这一块是 Spring Data的内容,可能不同的公司,使用的框架不一样。

package ${package_name}.repository;
import com.evada.inno.core.repository.BaseJpaRepository;
import ${package_name}.model.${table_name};

/**
* 描述:${table_annotation} Repository接口
* @author ${author}
* @date ${date}
*/
public interface ${table_name}Repository extends BaseJpaRepository<${table_name}, String> {

}
Mappter.ftl 模板

Mappter.ftl 用来生成 MyBatis 使用到的 mappter 文件,在文件中,定义了查询的sql语句。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="${package_name}.repository.mybatis.${table_name}DAO">

    <resultMap id="${table_name}DTOResultMap" type="${package_name}.dto.${table_name}DTO"></resultMap>

    <sql id="findDtoSql">
        select * from (
        select * from  ${table_name_small} temp
        ) t
    </sql>

    <select id="findDTOById" parameterType="String" resultMap="${table_name}DTOResultMap">
        <include refid="findDtoSql"></include>
        <where>
            and t.id = ${r‘#{id}‘}
        </where>
    </select>

    <select id="find${table_name}Page" parameterType="${package_name}.dto.${table_name}DTO" resultMap="${table_name}DTOResultMap">
        <include refid="findDtoSql" />
        <where>

        </where>
    </select>

</mapper>
Controller.ftl 模板

Controller.ftl 文件用来生成控制层类,类中已经帮我们生成了,增,删,改,查等路由。同时可以注入接口道控制层中。

package ${package_name}.controller;
import com.evada.inno.core.annotation.Rest;
import ${package_name}.service.I${table_name}Service;
import ${package_name}.model.${table_name};
import ${package_name}.dto.${table_name}DTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.http.MediaType;
import com.evada.inno.common.domain.ResultData;
import com.evada.inno.core.util.AssertUtils;

/**
* 描述:${table_annotation}控制层
* @author ${author}
* @date ${date}
*/
@Rest(${table_name}.class)
public class ${table_name}Controller {

    @Autowired
    private I${table_name}Service ${table_name?uncap_first}Service;

    /**
    * 描述:根据Id 查询
    * @param id  ${table_annotation}id
    */
    @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResultData findById(@PathVariable("id") String id)throws Exception {
        ${table_name}DTO ${table_name?uncap_first}DTO = ${table_name?uncap_first}Service.findDTOById(id);
        AssertUtils.checkResourceFound(${table_name?uncap_first}DTO);
        return new ResultData(${table_name}DTO.class, ${table_name?uncap_first}DTO);
    }

    /**
    * 描述:创建${table_annotation}
    * @param ${table_name?uncap_first}DTO  ${table_annotation}DTO
    */
    @RequestMapping(value = "", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResultData create(@RequestBody ${table_name}DTO ${table_name?uncap_first}DTO) throws Exception {
        return new ResultData(${table_name}.class,${table_name?uncap_first}Service.create${table_name}(${table_name?uncap_first}DTO));
    }

    /**
    * 描述:删除${table_annotation}
    * @param id ${table_annotation}id
    */
    @RequestMapping(value = "/{id}/bulk", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public void deleteById(@PathVariable("id") String id) throws Exception {
        ${table_name?uncap_first}Service.deleteById(id);
    }

    /**
    * 描述:更新${table_annotation}
    * @param id ${table_annotation}id
    */
    @RequestMapping(value = "/{id}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResultData update${table_name}(@PathVariable("id") String id,@RequestBody ${table_name}DTO ${table_name?uncap_first}DTO) throws Exception {
        ${table_name?uncap_first}DTO.setId(id);
        return new ResultData(${table_name}.class,${table_name?uncap_first}Service.update${table_name}(${table_name?uncap_first}DTO));
    }

}

通过上面的代码生成,我们就可以把生成的文件复制到相关的目录,重新启动系统,这样,基本的增,删,改,查就实现了。

读书感悟

来自东野圭吾《信》

  • “大多数人都想置身于远离罪犯的地方。和犯罪者,特别是犯下抢劫杀人这样恶心犯罪的人,哪怕是间接的关系也不想有。因为稍微有点什么关系,没准也会被卷入莫名其妙的事情中去。排斥犯罪者或是与其近似的人,是非常正当的行为,也可以说是正当防卫的本能。”
  • 犯罪者必须要有这样的思想准备,就是自己犯罪的同时也抹杀了自己亲属在社会上的存在。
  • 所谓偏见,就是不平等看待,其产生的根源就在于人的自私本性。这里的不平等看待,其实可以视为一种处理各种社会关系时的态度平衡缺失,而总是向有利于自己的一方倾斜,除非不同的立场之间不存在厉害冲突。一般情况下,人都是首先从自己的角度来看问题,而不会力图站在他人的立场来考量,完全意义上的中立是不可能的,由己及人是必然的思维定势,偏见遂自然而生。

经典故事

  
【一只小青蛙厌倦了常年生活的小水沟——水沟的水越来越少,它已经没有什么食物了。小青蛙每天都不停地蹦,想要逃离这个地方。而它的同伴整日懒洋洋地蹲在浑浊的水洼里,说:“现在不是还饿不死 
吗?你着什么急?”终于有一天,小青蛙纵身一跃,跳进了旁边的一个大河塘,那里面有很多好吃的,它可以自由游弋。小青蛙呱呱地呼唤自己的伙伴:“你快过来吧,这边简直是天堂!”但是它的同伴说:“我在这里已经习惯了,我从小就生活在这里,懒得动了!” 不久,水沟里的水干了,小青蛙的同伴活活饿死了。】

大神文章

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

其他

如果有带给你一丝丝小快乐,就让快乐继续传递下去,欢迎点赞、顶、欢迎留下宝贵的意见、多谢支持!

原文地址:https://www.cnblogs.com/weixupeng/p/8600957.html

时间: 2024-08-27 08:37:51

Java之利用Freemarker模板引擎实现代码生成器,提高效率的相关文章

Spring Boot? 使用freemarker模板引擎渲染web视图

效果图 代码 package com.wls.integrateplugs.hello.controller; /** * Created by wls on 2017/8/24. */ import java.util.Locale; import java.util.UUID; import javax.servlet.http.HttpSession; import com.sun.org.apache.regexp.internal.RE; import org.springframew

SpringBoot获取Freemarker模板引擎,生成HTML代码

今天用Ajax异步添加评论,加载Freemarker模板引擎,生成模板模块 1.新建Freemarker模板 <li id="${comment.oId}"> <div> <div class="avatar tooltipped tooltipped-n" aria-label="${comment.commentName}" style="background-image: url(${comment.

##Freemarker模板引擎的分享

网页静态化技术 -Freemarker 原因:在我们开发过程中,一般会大量的网页静态化部分的解决问题,例如新闻网站的那些静态新闻,再比如我们大型的电商项目,每个商品的详情页,都是一些静态资源,如果每次用户访问都要去数据库中访问,那么无疑会造成高并发的现象,而且造成资源的浪费. 技术:网页静态化技术和缓存技术的共同点都是为了减轻数据库的访问压力,但是具体的应用场景不同,缓存比较适合小规模的数据,而网页静态化比较适合大规模且相对变化不太频繁的数据.另外网页静态化还有利于SEO. 另外我们如果将网页以

Spring Boot 揭秘与实战(七) 实用技术篇 - FreeMarker 模板引擎

文章目录 1. FreeMaker 代替 JSP 作为页面渲染 2. 生成静态文件 3. 扩展阅读 4. 源代码 Spring Boot 提供了很多模板引擎的支持,例如 FreeMarker.Thymeleaf.这篇,我们看下 Spring Boot 如何集成和使用 FreeMarker. Spring Boot 中使用 FreeMarker 模板非常简单方便.如果想要使用FreeMarker 模板引擎,首先,修改 POM 文件,添加依赖. FreeMaker 代替 JSP 作为页面渲染 <de

Spring MVC 学习总结(七)——FreeMarker模板引擎与动态页面静态化

模板引擎可以让程序实现界面与数据分离,业务代码与逻辑代码的分离,这就提升了开发效率,良好的设计也使得代码复用变得更加容易.一般的模板引擎都包含一个模板解析器和一套标记语言,好的模板引擎有简洁的语法规则.强大的功能.高效的渲染效率.详尽的帮助说明与不断的更新与维护.常见的前端模板引擎有: 常用的java后台模板引擎:jsp.FreeMarker.Velocity等. 请不要迷恋速度,为了推广的测试可能是片面的,好的模板引擎经得起时间考验,建议大家选择成熟的.常用的模板引擎.另外不管前后端的模板引擎

freemarker模板引擎 常用标签

freemarker正常生成HTML的模板引擎,公司需求将书籍来源的数据发放到不同的渠道,每个渠道生成特定的模板,这样数据自动生成相应的格式,主要是生成xml格式,所以根据网上的Demo改成了对应项目测试的Demo.--------------------此为背景. 正常的模板文件.flt的,但是发现改成.xml格式的也完全没有问题,我表示非常高兴,哇卡卡卡~ 网上有很多标签大全,我就捡我用过的标签写:(不断的补充ing...) 1.<#if></#if> <#elseif&

SpringMVC的架设,使用Freemarker模板引擎

自行编译完spring4.0后,要架设以Freemaker为模板引擎的网站,同时还要整合Hibernate3.6.这当然要用Spring的MVC架构.我希望是注解模式完成,经过几次查询和修改,终于架设完成,现记录一下,以备后面使用. 准备工作:自行编译Spring4,也可以网上下载已经编译好的包:下载Hibernate3.6:下载各类依赖包,以下为我列出的各类依赖包: antlr-2.7.6.jar aopalliance-1.0.jar aspectj.jar c3p0-0.9.1.2.jar

FreeMarker模板引擎基础知识

FreeMarker基础简介 FreeMarker是一款模板引擎:一种基于模板,用来生成输出文本的通用工具.它是为java程序员提供的一个开发包或者说是库类,一般的用法就是Java程序通过SQL查询到数据,FreeMarker使用模板生成文件页面来显示已经准备好的数据.也就是 输出= 模板+数据模型. FreeMarker支持的数据类型有: 标量 字符串 数字 布尔值 日期 容器 哈希表 系列 集 子程序 方法和函数 用户自定义指令(比如宏) 其他 节点 模板(FTL编程)是由如下部分混合而成的

使用freemarker模板引擎生成word文档的开发步骤

1.准备模板文档,如果word文档中有表格,只保留表头和第一行数据:2.定义变量,将word文档中的变量用${var_name}替换:3.生成xml文件,将替换变量符后的word文档另存为xml文件:4.格式化xml文件,使用工具(XmlFormat.exe),自动生成格式化后的xml文件:5.美化xml文件,${}中的内容仅保留变量名:6.表格,将表格中的行数据用相应的变量替换,在第一行数据的收尾加标签:<#list tbl1 as tbl1></#list> ,注意:表格可嵌套