通过代码生成器自动化构建数据层与接口层
为了提升开发效率并告别重复的 CRUD(增删改查)代码编写,我们可以利用 Java 反射机制构建一套轻量级的代码生成方案。该方案仅需定义实体类,即可自动生成 MyBatis Mapper XML、Dao 接口、Service 层逻辑、Controller 层代码以及基础的 DDL 建表语句。
核心设计思路
通过读取实体类(Entity)的字段类型、注解信息及类注释,利用字符串构建器(StringBuilder)生成对应格式的 Java 源文件和 XML 映射文件,并直接落盘到指定项目目录中。
自动化 Mapper 映射生成
以下代码示例展示了如何解析类结构并生成 MyBatis 映射文件:
public class MapperCodeGen {
public static String buildMapperXml(Class<?> entityClass) {
StringBuilder builder = new StringBuilder();
builder.append("<mapper namespace=\"").append(entityClass.getName()).append("\">\n");
// 生成 ResultMap 和基础 SQL 片段
// ... (此处省略解析 Field 的逻辑)
builder.append(" <insert id=\"save\"> INSERT INTO ... </insert>\n");
builder.append("</mapper>");
return builder.toString();
}
}
构建 BaseDao 泛型基类
所有 Dao 层通过继承 BaseDao<T> 来复用基础 CRUD 方法,利用 Spring 的 SqlSessionTemplate 执行 SQL:
public abstract class DataAccessBase<T> {
@Autowired
private SqlSessionTemplate sqlSession;
public int insert(T record) {
String statement = getNamespace() + ".save";
return sqlSession.insert(statement, record);
}
// 获取当前类对应的 Mapper 命名空间
protected abstract String getNamespace();
}
数据库 Schema 生成器
利用 Java 反射提取字段上的 Hibernate Validator 注解(如 @Length, @NotBlank),自动推断 SQL 数据类型及约束:
public class DdlGenerator {
public static String generateTableSql(Class<?> clazz) {
StringBuilder sb = new StringBuilder("CREATE TABLE " + toUnderline(clazz.getSimpleName()) + " (\n");
for (Field field : clazz.getDeclaredFields()) {
String type = field.getType().getSimpleName();
String column = toUnderline(field.getName());
sb.append(" ").append(column).append(" ").append(mapSqlType(type));
// 解析注解添加非空约束
if (field.isAnnotationPresent(NotBlank.class)) {
sb.append(" NOT NULL");
}
sb.append(",\n");
}
return sb.append(" PRIMARY KEY (id)\n)").toString();
}
}
开发建议与最佳实践
- 增量生成保护:在生成文件前进行存在性检查(File.exists()),避免直接覆盖已编写的业务逻辑。
- 元数据驱动:高度依赖实体类的注释(用于生成文档和数据库注释)及注解(用于生成字段约束),请务必保证实体类定义的完整性。
- 扩展性:文中仅演示了基本的增删改查实现,复杂业务逻辑建议通过扩展
BaseService并在生成的类中重写或调用super方法来实现。 - 工程路径:生成器会自动定位
src/main/java和src/main/resources目录,确保编译环境路径配置准确。