freemarker是一款模板引擎,一种基于模板和数据,并用来生成输出文本(HTML、配置文件,源代码等)的工具。
freemarker模板文件相关语法
1、输出基本数据类型或对象属性
${数据} 或者 ${对象.属性}
如:
${name}
${user.username}
2.输出集合
<#list userList as item>
${item.username}
</#list>
3.if判断
#list userList as item>
<#if item.username == 'U1'>
${item.username},
<#elseif item.username == 'U2'>
你好 ${item.username},
<#else >
hello ${item.username} 。
</#if>
</#list>
----------------------------------
<#list userList as item>
<#if item_has_next>
${item.username},
<#else >
${item.username}
</#if>
</#list>
4.当存在 '#{' 要保留时如需要转义
${r"#{"}
测试实例:
新建maven项目,pom添加freemarker的依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
模板文件hello.ftl
<html>
<HEAD>
<meta charset="UTF-8">
</HEAD>
<BODY>
hello ${name}
<br />
你好 ${user.username}
<br />
<#list userList as item>
${item.username}
</#list>
<br />
<#list userList as item>
<#if item.username == 'U1'>
${item.username},
<#elseif item.username == 'U2'>
你好 ${item.username},
<#else >
hello ${item.username} 。
</#if>
</#list>
<br />
<#list userList as item>
<#if item_has_next>
${item.username},
<#else >
${item.username}
</#if>
</#list>
</BODY>
</html>
User类:
package cn.code;
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
测试类:
package cn.code.test;
import cn.code.User;
import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Test {
public static void main(String[] args) throws Exception {
//创建configuration对象
Configuration configuration = new Configuration(Configuration.getVersion());
//设置模板所在路径
String path = "E:\\IdeaProjects\\generator-demo\\src\\main\\resources\\";
configuration.setDirectoryForTemplateLoading(new File(path));
//获取模板对应实例,hello.ftl为模板路径下的模板文件
Template template = configuration.getTemplate("hello.ftl");
//指定生成文件的保存路径
String savePath = "E:\\IdeaProjects\\generator-demo\\src\\main\\java\\cn\\code\\test\\hello.html";
FileOutputStream stream = new FileOutputStream(savePath);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(stream);
//组装数据
Map param = new HashMap();
User user = new User();
user.setUsername("Lily");
param.put("name","Tom");
//输出对象
param.put("user",user);
//输出集合
List<User> userList = new ArrayList<>();
User user1 = new User();
user1.setUsername("U1");
User user2 = new User();
user2.setUsername("U2");
User user3 = new User();
user3.setUsername("U3");
userList.add(user1);
userList.add(user2);
userList.add(user3);
param.put("userList",userList);
//传参,生成数据文件
template.process(param, outputStreamWriter);
}
}
<html>
<HEAD>
<meta charset="UTF-8">
</HEAD>
<BODY>
hello Tom
<br />
你好 Lily
<br />
U1
U2
U3
<br />
U1,
你好 U2,
hello U3 。
<br />
U1,
U2,
U3
</BODY>
</html>
生成pojo案例:
1、新建maven项目,pom添加freemarker与mysql连接的依赖,注意版本号要与自己安装的mysql版本一致
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
新增pojo模板文件
package cn.code.beans;
import java.io.Serializable;
public class ${table.className} implements Serializable {
<#list table.columns as column>
//${column.remarks}
private ${column.javaType} ${column.fieldName};
</#list>
<#list table.columns as column>
public void set${column.upperFieldName} (${column.javaType} ${column.fieldName} ){
this.${column.fieldName}=${column.fieldName};
}
public ${column.javaType} get${column.upperFieldName}(){
return this.${column.fieldName};
}
</#list>
}
新增数据库表名与列名的描述
package cn.code.module;
import java.util.ArrayList;
import java.util.List;
public class Table {
//数据库表名
private String tableName;
//表名对应的类名
private String className;
//表中的列,一对多
List<Column> columns = new ArrayList<>();
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public List<Column> getColumns() {
return columns;
}
public void setColumns(List<Column> columns) {
this.columns = columns;
}
}

package cn.code.module;
public class Column {
//列名
private String columnName;
//列名对应的属性名
private String fieldName;
//首字母大写的属性名
private String upperFieldName;
//列类型,数据库类型
private String columnType;
//列类型对应的java类型
private String javaType;
//备注
private String remarks;
public String getRemarks() {
return remarks;
}
public void setRemarks(String remarks) {
this.remarks = remarks;
}
public String getColumnName() {
return columnName;
}
public void setColumnName(String columnName) {
this.columnName = columnName;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public String getUpperFieldName() {
return upperFieldName;
}
public void setUpperFieldName(String upperFieldName) {
this.upperFieldName = upperFieldName;
}
public String getColumnType() {
return columnType;
}
public void setColumnType(String columnType) {
this.columnType = columnType;
}
public String getJavaType() {
return javaType;
}
public void setJavaType(String javaType) {
this.javaType = javaType;
}
}

数据库相关配置文件database.properties,
注意mysql 8x以上,driver的值,url后面添加 &serverTimezone=GMT ,不然会报异常
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT
user=root
password=root
相关工具类PropertiesUtils.java
package cn.code.util;
import java.io.InputStreamReader;
import java.util.Properties;
public class PropertiesUtils {
private static Properties props;
/**
* 加载配置文件
*
* @param fileName
*/
private static void readProperties(String fileName) {
try {
props = new Properties();
InputStreamReader inputStream = new InputStreamReader(PropertiesUtils.class.getClassLoader().getResourceAsStream(fileName), "UTF-8");
props.load(inputStream);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根据key读取对应的value
*
* @param key
* @return
*/
public static String get(String fileName,String key) {
readProperties(fileName);
//System.out.println(props.getProperty(key));
return props.getProperty(key);
}
}

package cn.code.util;
public class StringUtils {
//根据数据库列类型返回相应的java类型
public static String switchType(String columnName) {
String javaType = null;
switch (columnName) {
case "VARCHAR":
javaType = "String";
break;
case "INT":
javaType = "Integer";
break;
case "DATETIME":
javaType = "Date";
break;
default:
javaType = "String";
}
return javaType;
}
/**
* 字符串首字母大写
*
* @param str
* @return
*/
public static String captureName(String str) {
return String.valueOf(str.charAt(0)).toUpperCase() + str.substring(1);
}
/**
* 去除下划线,下划线后的首字母大写
*
* @param str
* @return
*/
public static String putOffUnderline(String str) {
int idx = str.indexOf("_");
if (idx == -1) return str;
String s1 = str.replaceFirst("_", "");
String s2 = s1.substring(0, idx) + String.valueOf(s1.charAt(idx)).toUpperCase() + s1.substring(idx + 1);
/* String[] strings = str.split("_");
for (int i = 0; i < strings.length; i++) {
if (i == 0)
ret += strings[i];
else
ret += String.valueOf(strings[i].charAt(0)).toUpperCase() + strings[i].substring(1);
}*/
return putOffUnderline(s2);
}
public static void main(String[] args) {
System.out.println(putOffUnderline("tb_test_a"));
}
}

数据库连接与获取表名,与表名对应的列名TableUtils
package cn.code.util;
import cn.code.module.Column;
import cn.code.module.Table;
import cn.code.util.PropertiesUtils;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class TableUtils {
private static String DBDRIVER = PropertiesUtils.get("database.properties", "driver");
private static String DBURL = PropertiesUtils.get("database.properties", "url");
private static String DBUSER = PropertiesUtils.get("database.properties", "user");
private static String DBPASS = PropertiesUtils.get("database.properties", "password");
private static Connection connection;
private static DatabaseMetaData dbmd;
static {
try {
//连接数据库
Class.forName(DBDRIVER);
connection = DriverManager.getConnection(DBURL, DBUSER, DBPASS);
//获取metaData
dbmd = connection.getMetaData();
} catch (Exception e) {
e.printStackTrace();
}
}
public static List<Table> getTable() {
List<Table> tableList = new ArrayList<>();
//获取数据库连接
try {
//获取所有表名的结果集
ResultSet rs = dbmd.getTables(null, null, null, new String[]{"TABLE"});
//遍历结果集
while (rs.next()) {
Table table = new Table();//tb_test_a -> TbTestA
String tableName = rs.getString("TABLE_NAME");
table.setTableName(tableName);
table.setClassName(StringUtils.captureName(StringUtils.putOffUnderline(tableName)));
table.setColumns(getColumns(tableName));
tableList.add(table);
}
} catch (Exception e) {
e.printStackTrace();
}
return tableList;
}
public static List<Column> getColumns(String tableName) {
List<Column> columnList = new ArrayList<>();
try {
ResultSet rs = dbmd.getColumns(null, "%", tableName, "%");
while (rs.next()) {
Column column = new Column();
String columnName = rs.getString("COLUMN_NAME");
String columnType = rs.getString("TYPE_NAME");
String remarks = rs.getString("REMARKS");
column.setColumnName(columnName);
column.setColumnType(columnType);
column.setRemarks(remarks);
column.setFieldName(columnName);
column.setUpperFieldName(StringUtils.captureName(columnName));
column.setJavaType(StringUtils.switchType(columnType));
columnList.add(column);
}
} catch (Exception e) {
e.printStackTrace();
}
return columnList;
}
public static void main(String[] args) {
//getTable();
//getColumns("tb_test_b");
//测试
List<Table> tableList = getTable();
for (Table table: tableList) {
System.out.println(table.getTableName());
}
}
}
freemarker环境初始化
package cn.code;
import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Generator {
private Configuration configuration;
//完成环境初始化
public void init(String path) throws Exception {
configuration = new Configuration(freemarker.template.Configuration.getVersion());
//设置模板所在路径
configuration.setDirectoryForTemplateLoading(new File(path));
}
public void process(String tempName, String savePath, Map<String, Object> param) throws Exception {
//获取模板对应实例
Template template = configuration.getTemplate(tempName);
//初始化保存路径
FileOutputStream stream = new FileOutputStream(savePath);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(stream);
//传参,生成数据
template.process(param, outputStreamWriter);
}
}
传送从数据库读取的数据并生成pojo
package cn.code.ssm;
import cn.code.Generator;
import cn.code.module.Table;
import cn.code.util.TableUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ModuleHandler {
private Generator generator = new Generator();
private String templatePath = this.getClass().getClassLoader().getResource("").getPath()+"\\module\\";
private String savePath = "E:\\IdeaProjects\\generator-demo\\src\\main\\java\\cn\\code\\beans";
public void exectue() throws Exception {
//获取table对应的实例
List<Table> tableList = TableUtils.getTable();
Map<String,Object> param = new HashMap<>();
for (Table table:tableList){
param.put("table",table);
generator.init(templatePath);
generator.process("module.ftl",savePath+"\\"+table.getClassName()+".java",param);
}
}
public static void main(String[] args) throws Exception {
ModuleHandler moduleHandler = new ModuleHandler();
moduleHandler.exectue();
}
}
生成的pojo