Automate CRUD Code Generation for SpringBoot Projects – Boost Development Speed
This article introduces a SpringBoot‑based code generation tool that automatically creates entity classes, DAO interfaces, service implementations, and controller code from database tables, explains its design principles, demonstrates usage with screenshots, and provides a comprehensive set of customizable templates and dynamic parameters for developers.
Origin
While working on a project that required creating more than 20 database tables, I realized that manually writing entity classes, CRUD interfaces, and SQL code consumes about two hours per table, totaling over 40 hours for the whole set.
To save time, I built a tool that automatically generates all the necessary business code.
The tool is now available online at https://utilsbox.cn/?app=bizcode and its source code is open‑sourced on GitHub: https://github.com/GooseCoding/utilsbox .
Usage Demo
Assume we need to create a "product" table. After entering the table name and its Chinese description, we add the fields just like in any database client. Clicking “One‑Click Generate Code” produces the SQL for table creation, CRUD SQL, the entity class, DAO interface, service class, and controller.
The generated code can be copied into the project, and after a few import statements the basic CRUD operations are ready for the front‑end.
If a table already exists, the tool can parse its CREATE TABLE SQL. Paste the SQL into the text box, click “Identify”, fill the Chinese name, and generate the corresponding business code instantly.
General Thoughts
The tool works well for my own projects, but to serve a broader audience it needs more configurability because different companies have different project structures and coding conventions.
Therefore I added a template configuration feature that lets users add, delete, or edit code templates for each layer.
Design
The generation principle is simple: a template with placeholders and a set of dynamic parameters. Users define templates, insert placeholders like
$table_name$or
$field_type_java$, and the tool replaces them with actual values.
In theory any language can be supported by providing appropriate templates.
<code>/**
* $table_desc$Model模型
* Created by 创建人 on $current_time$.
*/
public class $table_name_hump_A$Model extends ToString {
}
</code>Placeholders such as
$table_desc$(table Chinese name),
$current_time$(generation time), and
$table_name_hump_A$(table name in PascalCase) are replaced during generation.
Code Template References
Below are the default templates shipped with the tool. Users can import, export, and share them.
CREATE TABLE SQL Template
<code>CREATE TABLE `$table_name$` (
$create_table_field_list$
PRIMARY KEY (`$primary_key$`)
) ENGINE=$db_engine$ DEFAULT CHARSET=$db_encoded$;
</code>Entity Class Template
<code>/**
* $table_desc$DTO模型
* Created by 创建人 on $current_time$.
*/
public class $table_name_hump_A$DO {
$member_param_list$
$get_set_method_list$
}
</code>DAO Interface Template (DB Layer)
<code>import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* $table_desc$DB接口
* Created by 创建人 on $current_time$
*/
@Mapper
public interface $table_name_hump_A$DAO {
int insert($table_name_hump_A$DO data);
int update($table_name_hump_A$DO data);
List<$table_name_hump_A$DO> pageQuery(Map param);
Long pageQueryCount(Map param);
$table_name_hump_A$DO queryById(@Param("$primary_key_hump$") $primary_key_type_java$ $primary_key_hump$);
$table_name_hump_A$DO queryByIdLock(@Param("$primary_key_hump$") $primary_key_type_java$ $primary_key_hump$);
}
</code>CRUD XML Mapper Template
<code><?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="com.xxx.$table_name_hump_A$DAO">
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO $table_name$($insert_field_name_list$) VALUES ($insert_field_value_list$);
</insert>
<update id="update">
UPDATE $table_name$ SET $update_field_list$ WHERE $primary_key$ = #{ $primary_key_hump$ };
</update>
<select id="pageQuery" resultType="com.xxx.$table_name_hump_A$DO">
SELECT $select_field_list$ FROM $table_name$ WHERE 1=1 $where_field_list$
ORDER BY $primary_key$ DESC
<if test="pageIndex != null and pageSize != null">
LIMIT #{offset},#{rows}
</if>
</select>
<select id="pageQueryCount" resultType="java.lang.Long">
SELECT COUNT(1) as total FROM $table_name$ WHERE 1=1 $where_field_list$
</select>
<select id="queryById" resultType="com.xxx.$table_name_hump_A$DO">
SELECT $select_field_list$ FROM $table_name$ WHERE $primary_key$ = #{ $primary_key_hump$ };
</select>
<select id="queryByIdLock" resultType="com.xxx.$table_name_hump_A$DO">
SELECT $select_field_list$ FROM $table_name$ WHERE $primary_key$ = #{ $primary_key_hump$ } FOR UPDATE;
</select>
</mapper>
</code>Model Converter Template
<code>import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
/**
* $table_desc$模型转换器
* Created by 创建人 on $current_time$
*/
public class $table_name_hump_A$Converter {
public static $table_name_hump_A$DO toDo($table_name_hump_A$DTO source) {
$table_name_hump_A$DO target = new $table_name_hump_A$DO();
$converter_source_to_target_params_list$
return target;
}
public static $table_name_hump_A$DTO toDto($table_name_hump_A$DO source) {
$table_name_hump_A$DTO target = new $table_name_hump_A$DTO();
$converter_source_to_target_params_list$
return target;
}
public static List<$table_name_hump_A$DTO> toDtoList(List<$table_name_hump_A$DO> data) {
if (CollectionUtils.isEmpty(data)) { return null; }
List<$table_name_hump_A$DTO> list = new ArrayList<>();
for ($table_name_hump_A$DO item : data) { list.add($table_name_hump_A$Converter.toDto(item)); }
return list;
}
}
</code>Service Implementation Template
<code>import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
/**
* $table_desc$业务实现
* Created by 创建人 on $current_time$
*/
@Service
public class $table_name_hump_A$ServiceImpl implements $table_name_hump_A$Service {
private static final Logger LOGGER = LoggerFactory.getLogger($table_name_hump_A$ServiceImpl.class);
@Resource
private $table_name_hump_A$DAO $table_name_hump$DAO;
@Override
public CommonResult create(JSONObject request) {
CommonAssert.isNoEmptyObj(request, "请求参数不可空");
$table_name_hump_A$DTO dto = JSON.toJavaObject(request, $table_name_hump_A$DTO.class);
$biz_check_required_params$
$table_name_hump_A$DO dataDo = $table_name_hump_A$Converter.toDo(dto);
int count = $table_name_hump$DAO.insert(dataDo);
CommonAssert.isTrue(count > 0, "创建失败,请重试");
return new CommonResult(dataDo.get$primary_key_hump_A$());
}
// modify, pageQuery, queryById methods omitted for brevity
}
</code>Controller Template
<code>import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* $table_desc$HTTP请求控制器
* Created by 创建人 on $current_time$.
*/
@CrossOrigin
@RestController
@RequestMapping("/$table_name_hump$/")
public class $table_name_hump_A$Controller {
private static final Logger LOGGER = LoggerFactory.getLogger($table_name_hump_A$Controller.class);
@Resource
private $table_name_hump_A$Service $table_name_hump$Service;
@RequestMapping(value="create.json", method={RequestMethod.GET, RequestMethod.POST})
@ResponseBody
public Object create(@RequestBody JSONObject request) {
return CommonTemplate.run(LOGGER, new CommonTemplate() {
@Override
protected Object business() { return $table_name_hump$Service.create(request); }
}, request);
}
// modify, pageQuery, queryById methods omitted for brevity
}
</code>Dynamic Parameters
The tool defines a set of placeholders such as
$table_name$(raw table name),
$table_name_hump$(camelCase),
$table_name_hump_A$(PascalCase),
$field_type_java$(mapped Java type),
$current_time$, and many others that are substituted during generation.
Dynamic Code Blocks
Users can define custom code blocks that use placeholders; the tool expands them for each field. Examples include member variable lists, getter/setter methods, model conversion statements, and required‑field validation snippets.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.