@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 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 fieldMap = new LinkedHashMap<>();
private List genericFieldList = new ArrayList<>();
private LinkedHashMap importFieldMap = new LinkedHashMap<>();
private List 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());
}
}
}
详情可以参考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 propertys = info.getFieldMap();
ListIterator> list = new ArrayList>(propertys.entrySet())
.listIterator(propertys.size());
sql.append(" ( ");
while (list.hasPrevious()) {
Map.Entry 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 propertys = info.getFieldMap();
LinkedHashMap importFieldMap = info.getImportFieldMap();
List genericFieldList = info.getGenericFieldList();
List 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> list = new ArrayList>(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> entrySet = importFieldMap.entrySet();
for (Entry 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 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);
}
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);
}
<#list genericFieldList as genericField>
#list>
<#list association as item>
#list>
${insert}
${delete}
${update}
package ${basePackage}.query;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
public class ${bigClassName}QueryObject extends QueryObject {
}
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);
}
}