用Freemarker制作代码生成器生成mybatis.xml和java代码

一、外键对象简单封装

@Setter
@Getter
public class AssociationObject {
	private String property;
	private String columnPrefix;
	private String javaType;
}

二、类型的判断

            用来判断是否是java中的类型,若是java中的类型,则为不可能为是外键,若是自定义类型,则就该字段就是关联的外键。mybatis.xml生成文件中可以根据是否是外键生成关联查询。

public class JudgeType {
	public static boolean judgeType(String type) {
		String javaType = "";
		if (type.contains(".")) {
			//类型的截取
			int lastIndexOf = type.lastIndexOf(".");
			javaType = type.substring(lastIndexOf + 1);
		} else {
			javaType = type;
		}
		switch (javaType) {
		case "int":
			return true;
		case "Integer":
			return true;
		case "long":
			return true;
		case "Long":
			return true;
		case "double":
			return true;
		case "Double":
			return true;
		case "String":
			return true;
		case "BigDecimal":
			return true;
		case "Boolean":
			return true;
		case "boolean":
			return true;
		case "Date":
			return true;
		default:
			return false;
		}
	}
}

三、类型转换

        将java中的类型转换为数据中的类型,在执行create table的时候要用到。

/**
 * @version 创建时间:2017-1-22 下午7:25:25
 * @Description 描述:类型转换器,把mysql中的类型转为java中的类型
 */
public class TypeConverter {
	/**
	 * @param type
	 *            java中的类型
	 * @return mySql中的数据类型
	 * @Description 描述:把传进来的java类型,类型转换为数据库中的类型
	 */
	public static String javaType2MySqlType(Entry<String, String> entry) {
		String javaType = "";
		if (entry.getValue().contains(".")) {
			// 类型的截取
			int lastIndexOf = entry.getValue().lastIndexOf(".");
			javaType = entry.getValue().substring(lastIndexOf + 1);
		} else {
			javaType = entry.getValue();
		}

		switch (javaType) {

		case "String":
			return entry.getKey() + " VARCHAR(255) ,";

		case "byte[]":
			return entry.getKey() + " BLOB ,";

		case "int":
			return entry.getKey() + " INTEGER ,";

		case "Integer":
			return entry.getKey() + " INTEGER ,";

		case "Boolean":
			return entry.getKey() + " BIT ,";

		case "boolean":
			return entry.getKey() + " BIT ,";

		case "Long":
			return entry.getKey() + " BIGINT ,";

		case "long":
			return entry.getKey() + " BIGINT ,";

		case "float":
			return entry.getKey() + " FLOAT ,";

		case "Float":
			return entry.getKey() + " FLOAT ,";

		case "double":
			return entry.getKey() + " DOUBLE ,";

		case "Double":
			return entry.getKey() + " DOUBLE ,";

		case "BigDecimal":
			return entry.getKey() + " DECIMAL ,";

		case "Date":
			return entry.getKey() + " DATETIME,";

		default:
			return entry.getKey() + "_id Long,";
		}
	}

}

三、实体类相关信息封装

            在freemarker模板方法中行成mybatis.xml时要用到。

@Setter
@Getter
public class ClassInfo {
	private String basePackage; // 基本包
	private String bigClassName; // 大写类名
	private String smallClassName;// 首字母小写的类名
	private LinkedHashMap<String, String> fieldMap = new LinkedHashMap<>();
	private List<String> genericFieldList = new ArrayList<>();
	private LinkedHashMap<String, String> importFieldMap = new LinkedHashMap<>();
	private List<AssociationObject> association = new ArrayList<>();

	private String insert;
	private String delete;
	private String update;
	private String selectByPrimaryKey;
	private String selectAll;
	private String queryForCount;
	private String queryListData;
	private String limit;

	public ClassInfo(Class<?> clazz) throws Exception {
		String pkgName = clazz.getPackage().getName();
		this.basePackage = pkgName.substring(0, pkgName.lastIndexOf("."));
		this.bigClassName = clazz.getSimpleName();
		this.smallClassName = this.bigClassName.substring(0, 1).toLowerCase() + this.bigClassName.substring(1);
		this.getObjectFiled(clazz);
	}

	public void getObjectFiled(Class<?> clazz) throws Exception {
		// 创建父类对象
		Object currentObject = clazz.getDeclaredConstructor().newInstance();
		if (currentObject instanceof BaseDomain) {
			Field[] fields = clazz.getDeclaredFields();
			for (Field field : fields) {
				// java中的修饰码 如public 1 private 2 protect 4 static 8
				if (field.getModifiers() < 8) {
					// 集合类型的不添加
					if (!field.getType().getName().endsWith("List") && !field.getType().getName().endsWith("Map")) {
						this.fieldMap.put(field.getName(), field.getType().getName());
					}
				}
			}
			// 递归调用父类中的方法
			getObjectFiled(clazz.getSuperclass());
		}
	}
}


四、代码生成器MyGenerator具体实现

           详情可以参考ftl入门到放弃。

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import freemarker.template.Configuration;
import freemarker.template.Template;

/**
 * @version 创建时间:2017-2-22 下午11:21:27
 * @Description 描述:Mybatis代码生成器
 */
public class MyGenerator {
	private static final int FEILDL_ENGTH = 1;// 统一定义截取字符串的长度为多少字母

	public static void main(String[] args) throws Exception {

		ClassInfo info = new ClassInfo(BlogType.class);

		// 创建表
		createTable(info);

		// 生成xml文件
		createMyBatisXML(info, "Mapper.xml", "src/main/java/{0}/mapper/{1}Mapper.xml");

		// mapper接口
		createMapper(info, "Mapper.java", "src/main/java/{0}/mapper/{1}Mapper.java");

		// 生成QueryOBject
		createQueryObject(info, "QueryObject.java", "src/main/java/{0}/query/{1}QueryObject.java");

		// 生成Service接口
		createService(info, "IService.java", "src/main/java/{0}/service/I{1}Service.java");

		// 生成Service实现类
		createServiceImpl(info, "ServiceImpl.java", "src/main/java/{0}/service/impl/{1}ServiceImpl.java");
	}

	@SuppressWarnings("deprecation")
	private static Configuration config = new Configuration();
	static {
		try {
			config.setDirectoryForTemplateLoading(new File("templates"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void createQueryObject(ClassInfo info, String templateFile, String targetFile) throws Exception {
		createFile(info, templateFile, targetFile);
		System.out.println("生成" + info.getBigClassName() + "QueryObject");
	}

	public static void createMapper(ClassInfo info, String templateFile, String targetFile) throws Exception {
		createFile(info, templateFile, targetFile);
		System.out.println("生成" + info.getBigClassName() + "Mapper接口");
	}

	public static void createService(ClassInfo info, String templateFile, String targetFile) throws Exception {
		createFile(info, templateFile, targetFile);
		System.out.println("生成I" + info.getBigClassName() + "Service接口");
	}

	public static void createServiceImpl(ClassInfo info, String templateFile, String targetFile) throws Exception {
		createFile(info, templateFile, targetFile);
		System.out.println("生成" + info.getBigClassName() + "ServiceImpl实现");
	}

	public static void createController(ClassInfo info, String templateFile, String targetFile) throws Exception {
		createFile(info, templateFile, targetFile);
		System.out.println("生成" + info.getBigClassName() + "Controller文件");
	}

	// 数据库表的创建
	public static void createTable(ClassInfo info) throws SQLException {
		StringBuilder sql = new StringBuilder();
		sql.append("CREATE TABLE ").append(info.getBigClassName());
		LinkedHashMap<String, String> propertys = info.getFieldMap();
		ListIterator<Map.Entry<String, String>> list = new ArrayList<Map.Entry<String, String>>(propertys.entrySet())
				.listIterator(propertys.size());
		sql.append(" ( ");
		while (list.hasPrevious()) {
			Map.Entry<String, String> entry = list.previous();
			if ("id".equals(entry.getKey())) {
				// 主键拼接
				sql.append("id " + "BIGINT PRIMARY KEY auto_increment ,");
			} else {
				// 非主键拼接
				sql.append(TypeConverter.javaType2MySqlType(entry));
			}
		}
		sql.append(" ); ");
		sql.deleteCharAt(sql.lastIndexOf(","));
		// 创建连接
		Connection con = JDBCUtil.getConnection();
		PreparedStatement ps = con.prepareStatement(sql.toString());
		boolean result = ps.execute();
		if (result) {
			throw new RuntimeException("创建表" + info.getBigClassName() + "异常!!!");
		} else {
			System.out.println("创建表" + info.getBigClassName() + "成功!");
		}

	}

	// 其他java文件的创建
	private static void createFile(ClassInfo info, String templateFile, String targetFile) throws Exception {
		// System.out.println(MessageFormat.format("你好{0},明天去{1}", "小强","打球"));
		Template template = config.getTemplate(templateFile);
		targetFile = MessageFormat.format(targetFile, info.getBasePackage().replace(".", "/"), info.getBigClassName());
		System.out.println(templateFile);
		System.out.println(targetFile);
		File file = new File(targetFile);
		// 如果文件存在则报错,不会覆盖以前的文件
		if (file.exists()) {
			throw new RuntimeException(file.getName() + "已经存在!");
		}
		File parentFile = file.getParentFile();
		// 创建文件目录
		if (!parentFile.exists()) {
			parentFile.mkdirs();
		}
		template.process(info, new FileWriter(file));
	}

	// Mybatis文件的创建
	private static void createMyBatisXML(ClassInfo info, String templateFile, String targetFile) throws Exception {

		LinkedHashMap<String, String> propertys = info.getFieldMap();
		LinkedHashMap<String, String> importFieldMap = info.getImportFieldMap();
		List<String> genericFieldList = info.getGenericFieldList();
		List<AssociationObject> association = info.getAssociation();
		StringBuilder insert1 = new StringBuilder().append("insert into " + info.getBigClassName() + "  (");
		StringBuilder insert2 = new StringBuilder().append("  values( ");

		StringBuilder delete = new StringBuilder().append("delete from " + info.getBigClassName() + " where id =#{id}");

		StringBuilder update = new StringBuilder().append("update " + info.getBigClassName() + " set ");

		StringBuilder selectselectByPrimaryKey = new StringBuilder().append("select ");

		ListIterator<Map.Entry<String, String>> list = new ArrayList<Map.Entry<String, String>>(propertys.entrySet())
				.listIterator(propertys.size());
		while (list.hasPrevious()) {

			String key = list.previous().getKey();

			System.out.println(key);
			String value = propertys.get(key);
			if (JudgeType.judgeType(value)) {
				// 插入时不需要主键
				if (!key.equals("id")) {
					genericFieldList.add(key);
					insert1.append(" " + key + " ,");
					insert2.append(" #{" + key + "} ,");
					update.append(" " + key + "=#{" + key + "}, ");
				}
				selectselectByPrimaryKey
						.append(info.getSmallClassName().subSequence(0, MyGenerator.FEILDL_ENGTH) + "." + key + ", ");
			} else {
				// 外键关联的相关属性
				AssociationObject associationObject = new AssociationObject();
				associationObject.setColumnPrefix(key.substring(0, MyGenerator.FEILDL_ENGTH) + "_");
				associationObject.setProperty(key);
				associationObject.setJavaType(value);
				association.add(associationObject);
				insert1.append(" " + key + "_id ,");
				insert2.append(" #{" + key + ".id} ,");

				update.append(" " + key + "_id=#{" + key + ".id}, ");
				int index = value.lastIndexOf(".");
				value = value.substring(index + 1);

				importFieldMap.put(key, value);

			}
		}
		int index = insert1.lastIndexOf(",");
		String str1 = insert1.substring(0, index) + " )";
		index = insert2.lastIndexOf(",");
		String str2 = insert2.substring(0, index) + " )";
		// 增加
		info.setInsert(str1 + str2);
		System.out.println("增加操作  " + str1 + str2);

		// 删除
		info.setDelete(delete.toString());
		System.out.println("删除操作  " + delete.toString());

		index = update.lastIndexOf(",");
		String subUpdate = update.substring(0, index);
		subUpdate = subUpdate + " where id=#{id}";
		// 更改操作
		info.setUpdate(subUpdate);
		System.out.println("更改操作  " + subUpdate);
		// 判断是否有外键
		if (importFieldMap.size() <= 0) {
			index = selectselectByPrimaryKey.lastIndexOf(",");
			String str = selectselectByPrimaryKey.substring(0, index);

			// 条数的查询
			String queryForCount = "select count(" + info.getSmallClassName().substring(0, MyGenerator.FEILDL_ENGTH)
					+ ".id" + ") from " + info.getBigClassName() + " "
					+ info.getSmallClassName().substring(0, MyGenerator.FEILDL_ENGTH);
			info.setQueryForCount(queryForCount);
			System.out.println("查询条数  " + queryForCount);

			// 查询结果集
			info.setQueryListData(str + " from " + info.getSmallClassName() + " "
					+ info.getSmallClassName().substring(0, MyGenerator.FEILDL_ENGTH));
			System.out.println("查询所有  " + str + " from " + info.getSmallClassName() + " "
					+ info.getSmallClassName().substring(0, MyGenerator.FEILDL_ENGTH));
			// 分页相关
			info.setLimit("limit #{currentPage},#{pageSize}");

			str = str + " from " + info.getSmallClassName() + " where "
					+ info.getSmallClassName().substring(0, MyGenerator.FEILDL_ENGTH) + ".id=#{id}";

			// 根据主键的查询
			info.setSelectByPrimaryKey(str);
			System.out.println("主键查询  " + str);

		} else {
			Set<Entry<String, String>> entrySet = importFieldMap.entrySet();
			for (Entry<String, String> entry : entrySet) {
				selectselectByPrimaryKey.append(entry.getKey().substring(0, MyGenerator.FEILDL_ENGTH) + ".id as "
						+ entry.getKey().substring(0, MyGenerator.FEILDL_ENGTH) + "_id ,");
			}
			index = selectselectByPrimaryKey.lastIndexOf(",");
			String str = selectselectByPrimaryKey.substring(0, index);
			str = str + " from " + info.getBigClassName() + "  "
					+ info.getSmallClassName().substring(0, MyGenerator.FEILDL_ENGTH);
			for (Entry<String, String> entry : entrySet) {
				str = str + " left join " + entry.getValue() + " "
						+ entry.getKey().substring(0, MyGenerator.FEILDL_ENGTH) + " on " + "("
						+ info.getSmallClassName().substring(0, MyGenerator.FEILDL_ENGTH) + "." + entry.getKey()
						+ "_id=" + entry.getKey().substring(0, MyGenerator.FEILDL_ENGTH) + ".id)";
			}

			String queryForCount = "select count(" + info.getSmallClassName().substring(0, MyGenerator.FEILDL_ENGTH)
					+ ".id" + ") from " + info.getBigClassName() + " "
					+ info.getSmallClassName().substring(0, MyGenerator.FEILDL_ENGTH);
			info.setQueryForCount(queryForCount);
			System.out.println("查询条数  " + queryForCount);

			// 查询结果集
			info.setQueryListData(str);
			System.out.println("查询所有  " + str);
			// 分页相关
			info.setLimit("limit #{start},#{pageSize}");

			str = str + " where " + info.getSmallClassName().substring(0, MyGenerator.FEILDL_ENGTH) + ".id=#{id}";

			// 根据主键的查询
			info.setSelectByPrimaryKey(str);
			System.out.println("主键查询  " + str);
		}

		Template template = config.getTemplate(templateFile);
		targetFile = MessageFormat.format(targetFile, info.getBasePackage().replace(".", "/"), info.getBigClassName());
		File file = new File(targetFile);
		File parentFile = file.getParentFile();
		// 创建文件目录
		if (!parentFile.exists()) {
			parentFile.mkdirs();
		}
		// 生成xml文件
		template.process(info, new FileWriter(file));
	}
}

五、模板示意图

 


IService.java文件模板:

package ${basePackage}.service;

import java.util.List;

import ${basePackage}.page.PageResult;
import ${basePackage}.domain.${bigClassName};
import ${basePackage}.query.${bigClassName}QueryObject;

public interface I${bigClassName}Service {

	void insert(${bigClassName} ${smallClassName});

	void delete(${bigClassName} ${smallClassName});

	${bigClassName} select(${bigClassName} ${smallClassName});

	void update(${bigClassName} ${smallClassName});

	PageResult query(${bigClassName}QueryObject qo);

	List<${bigClassName}> queryForList(${bigClassName}QueryObject qo);

}


Mapper.java接口模板:

package ${basePackage}.mapper;

import java.util.List;

import ${basePackage}.domain.${bigClassName};
import ${basePackage}.query.${bigClassName}QueryObject;

public interface ${bigClassName}Mapper {
	
	void insert(${bigClassName} ${smallClassName});

	void delete(${bigClassName} ${smallClassName});

	void update(${bigClassName} ${smallClassName});
	
	${bigClassName} select(${bigClassName} ${smallClassName});
	
	int queryTotalCount(${bigClassName}QueryObject qo);

	List<${bigClassName}> queryListData(${bigClassName}QueryObject qo);
}

Mapper.xml模板:

<?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="${basePackage}.mapper.${bigClassName}Mapper">
	<resultMap id="${smallClassName}ResultMap" type="${basePackage}.domain.${bigClassName}">
		<id column="id" property="id" jdbcType="BIGINT" />
		<#list genericFieldList as genericField>
		<result column="${genericField}" property="${genericField}" />
		</#list>
		<#list association as item>
		<association property="${item.property}" columnPrefix="${item.columnPrefix}"
			javaType="${item.javaType}">
			<!-- 对象的关联 -->
			<id property="id" column="id"></id>
		</association>
		</#list>

	</resultMap>

	<insert id="insert" useGeneratedKeys="true" keyProperty="id">
		${insert}
	</insert>

	<delete id="delete">
		${delete}
	</delete>

	<update id="update">
		${update}
	</update>

	<select id="select" resultMap="${smallClassName}ResultMap">
		${selectByPrimaryKey}
	</select>

	<select id="queryTotalCount" resultType="int">
		${queryForCount}
	</select>

	<select id="queryListData" resultMap="${smallClassName}ResultMap">
		${queryListData}
		<if test="pageSize>=0">
			${limit}
		</if>
	</select>

</mapper>

QueryObject.java模板代码:

package ${basePackage}.query;

import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
public class ${bigClassName}QueryObject extends QueryObject {

}

ServiceImpl.java模板代码:

package ${basePackage}.service.impl;

import java.util.List;

import ${basePackage}.page.PageResult;

import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import ${basePackage}.domain.${bigClassName};
import ${basePackage}.mapper.${bigClassName}Mapper;
import ${basePackage}.query.${bigClassName}QueryObject;
import ${basePackage}.service.I${bigClassName}Service;


@Service
public class ${bigClassName}ServiceImpl implements I${bigClassName}Service {

	@Autowired
	private ${bigClassName}Mapper ${smallClassName}Mapper;

	@Override
	public void insert(${bigClassName} ${smallClassName}) {

		${smallClassName}Mapper.insert(${smallClassName});
	}
	
	@Override
	public void delete(${bigClassName} ${smallClassName}){
		
		${smallClassName}Mapper.delete(${smallClassName});
	}
	
	@Override
	public void update(${bigClassName} ${smallClassName}) {
		this.${smallClassName}Mapper.update(${smallClassName});
	}
    

	@Override
	public ${bigClassName} select(${bigClassName} ${smallClassName}) {
		return this.${smallClassName}Mapper.select(${smallClassName});
	}

	@Override
	public PageResult query(${bigClassName}QueryObject qo) {
		
		int count = ${smallClassName}Mapper.queryTotalCount(qo);
		
		if (count > 0) {
			List<${bigClassName}> list = ${smallClassName}Mapper.queryListData(qo);
			return new PageResult(qo.getCurrentPage(), qo.getPageSize(), count, list);
		}
		return PageResult.empty(qo.getPageSize());
	}

	@Override
	public List<${bigClassName}> queryForList(${bigClassName}QueryObject qo) {
		return ${smallClassName}Mapper.queryListData(qo);
	}
}

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值