EasyCode là một plugin mạnh mẽ dành cho IntelliJ IDEA, giúp tự động hóa quá trình phát sinh mã boilerplate (như Entity, Mapper, Service, Controller) từ cấu trúc cơ sở dữ liệu. Việc sử dụng các mẫu chuẩn hóa trong EasyCode có thể tiết kiệm đáng kể thời gian và đảm bảo tính nhất quán trong dự án. Bài viết này sẽ hướng dẫn bạn cách thiết lập và sử dụng các mẫu EasyCode để phát sinh mã Java.
Chuẩn bị ban đầu
Đảm bảo rằng bạn đã cài đặt plugin EasyCode trong IntelliJ IDEA.
Phương pháp 1: Nhập Cấu hình Có Sẵn (Được khuyến nghị)
EasyCode hỗ trợ nhập trực tiếp tệp cấu hình EasyCodeConfig.json để chia sẻ các mẫu. Bạn có thể sao chép nội dung JSON dưới đây và lưu thành tệp EasyCodeConfig.json, sau đó nhập vào cài đặt EasyCode của mình. Quá trình nhập được thực hiện qua giao diện cấu hình EasyCode.
Nội dung tệp EasyCodeConfig.json:
{
"author" : "Cong cu phat trien",
"version" : "1.2.8",
"userSecure" : "",
"currTypeMapperGroupName" : "Default",
"currTemplateGroupName" : "Default",
"currColumnConfigGroupName" : "Default",
"currGlobalConfigGroupName" : "Default",
"typeMapper" : {
"Default" : {
"name" : "Default",
"elementList" : [ {
"matchType" : "REGEX",
"columnType" : "varchar(\\(\\d+\\))?",
"javaType" : "java.lang.String"
}, {
"matchType" : "REGEX",
"columnType" : "char(\\(\\d+\\))?",
"javaType" : "java.lang.String"
}, {
"matchType" : "REGEX",
"columnType" : "(tiny|medium|long)*text",
"javaType" : "java.lang.String"
}, {
"matchType" : "REGEX",
"columnType" : "decimal(\\(\\d+,\\d+\\))?",
"javaType" : "java.lang.Double"
}, {
"matchType" : "ORDINARY",
"columnType" : "integer",
"javaType" : "java.lang.Integer"
}, {
"matchType" : "REGEX",
"columnType" : "(tiny|small|medium)*int(\\(\\d+\\))?",
"javaType" : "java.lang.Integer"
}, {
"matchType" : "ORDINARY",
"columnType" : "int4",
"javaType" : "java.lang.Integer"
}, {
"matchType" : "ORDINARY",
"columnType" : "int8",
"javaType" : "java.lang.Long"
}, {
"matchType" : "REGEX",
"columnType" : "bigint(\\(\\d+\\))?",
"javaType" : "java.lang.Long"
}, {
"matchType" : "ORDINARY",
"columnType" : "date",
"javaType" : "java.util.Date"
}, {
"matchType" : "ORDINARY",
"columnType" : "datetime",
"javaType" : "java.util.Date"
}, {
"matchType" : "ORDINARY",
"columnType" : "timestamp",
"javaType" : "java.util.Date"
}, {
"matchType" : "ORDINARY",
"columnType" : "time",
"javaType" : "java.time.LocalTime"
}, {
"matchType" : "ORDINARY",
"columnType" : "boolean",
"javaType" : "java.lang.Boolean"
}, {
"matchType" : "ORDINARY",
"columnType" : "double",
"javaType" : "java.lang.Double"
} ]
}
},
"template" : {
"Default" : {
"name" : "Default",
"elementList" : [ {
"name" : "controller.java.vm",
"code" : "## Định nghĩa biến ban đầu\n#set($tenController = $tool.append($tableInfo.name, \"Controller\"))\n## Thiết lập callback\n$!callback.setFileName($tool.append($tenController, \".java\"))\n$!callback.setSavePath($tool.append($tableInfo.savePath, \"/controller\"))\n## Lấy khóa chính\n#if(!$tableInfo.pkColumn.isEmpty())\n #set($pk = $tableInfo.pkColumn.get(0))\n#end\n\n#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}controller;\n\nimport $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};\nimport $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service;\nimport org.springframework.web.bind.annotation.*;\nimport javax.annotation.Resource;\n\n/**\n * Lớp điều khiển cho bảng $!{tableInfo.comment}($!{tableInfo.name})\n *\n * @author $!author\n * @since $!time.currTime()\n */\n@RestController\n@RequestMapping(\"/$!tool.firstLowerCase($tableInfo.name)\")\npublic class $!{tenController} {\n /**\n * Đối tượng dịch vụ\n */\n @Resource\n private $!{tableInfo.name}Service $!tool.firstLowerCase($tableInfo.name)Service;\n\n /**\n * Truy vấn tất cả dữ liệu\n *\n * @param $!{tool.firstLowerCase($tableInfo.name)} Đối tượng thực thể để lọc\n * @return Danh sách các đối tượng thực thể\n */\n @PostMapping(\"/retrieveAll\")\n public ApiResponse retrieveAll(@RequestBody $!{tableInfo.name} $!{tool.firstLowerCase($tableInfo.name)}) {\n return ApiResponse.success(this.$!{tool.firstLowerCase($tableInfo.name)}Service.queryList($!{tool.firstLowerCase($tableInfo.name)}));\n }\n \n /**\n * Truy vấn một đối tượng theo ID chính\n *\n * @param id Khóa chính\n * @return Dữ liệu của một đối tượng\n */\n @GetMapping(\"{id}\")\n public ApiResponse retrieveById(@PathVariable(\"id\") $!pk.shortType id) {\n return ApiResponse.success(this.$!{tool.firstLowerCase($tableInfo.name)}Service.queryById(id));\n }\n\n /**\n * Thêm mới hoặc cập nhật dữ liệu\n *\n * @param $!{tool.firstLowerCase($tableInfo.name)} Thực thể\n * @return Kết quả boolean\n */\n @PostMapping(\"/saveOrUpdate\")\n public ApiResponse saveOrUpdate(@RequestBody $!{tableInfo.name} $!{tool.firstLowerCase($tableInfo.name)}) {\n return ApiResponse.success(this.$!{tool.firstLowerCase($tableInfo.name)}Service.saveOrUpdate($!{tool.firstLowerCase($tableInfo.name)}));\n }\n \n /**\n * Thêm mới dữ liệu\n *\n * @param $!{tool.firstLowerCase($tableInfo.name)} Thực thể\n * @return Kết quả thêm mới\n */\n @PostMapping(\"/add\")\n public ApiResponse addRecord(@RequestBody $!{tableInfo.name} $!{tool.firstLowerCase($tableInfo.name)}) {\n return ApiResponse.success(this.$!{tool.firstLowerCase($tableInfo.name)}Service.insert($!{tool.firstLowerCase($tableInfo.name)}));\n }\n\n /**\n * Chỉnh sửa dữ liệu\n *\n * @param $!{tool.firstLowerCase($tableInfo.name)} Thực thể\n * @return Kết quả chỉnh sửa\n */\n @PutMapping(\"/update\")\n public ApiResponse updateRecord(@RequestBody $!{tableInfo.name} $!{tool.firstLowerCase($tableInfo.name)}) {\n return ApiResponse.success(this.$!{tool.firstLowerCase($tableInfo.name)}Service.update($!{tool.firstLowerCase($tableInfo.name)}));\n }\n\n /**\n * Xóa dữ liệu theo ID\n *\n * @param id Khóa chính\n * @return Kết quả xóa\n */\n @DeleteMapping(\"/removeById\")\n public ApiResponse removeById($!pk.shortType id) {\n return ApiResponse.success(this.$!{tool.firstLowerCase($tableInfo.name)}Service.deleteById(id));\n }\n\n /**\n * Xóa hàng loạt dữ liệu theo ID\n *\n * @param ids Tập hợp các khóa chính (chuỗi ngăn cách bởi dấu phẩy)\n * @return Kết quả xóa hàng loạt\n */\n @DeleteMapping(\"/removeBatchByIds\")\n public ApiResponse removeBatchByIds(@RequestParam String ids) {\n return ApiResponse.success(this.$!{tool.firstLowerCase($tableInfo.name)}Service.deleteBatchByIds(ids));\n }\n}\n\n"
}, {
"name" : "debug.json.vm",
"code" : "// Không ghi kết quả phát sinh vào tệp\n$!callback.setWriteFile(false)\n\n// Gỡ lỗi đối tượng bảng gốc\n$!tool.debug($tableInfo.obj)\n\n// Gỡ lỗi đối tượng cột gốc\n$!tool.debug($tableInfo.fullColumn.get(0).obj)\n\n// Gỡ lỗi kiểu cột gốc\n$!tool.debug($tableInfo.fullColumn.get(0).obj.dataType)\n\n// Lấy trường từ kiểu cột gốc\nsqlType = $!tool.getField($tableInfo.fullColumn.get(0).obj.dataType, \"typeName\")\n\n// Thực thi phương thức từ kiểu cột gốc\nsqlTypeLen = $!tableInfo.fullColumn.get(0).obj.dataType.getLength()\n"
}, {
"name" : "entity.java.vm",
"code" : "## Nhập định nghĩa macro\n$!{define.vm}\n\n## Sử dụng macro để thiết lập callback (vị trí lưu và phần mở rộng tệp)\n#save(\"/entity\", \".java\")\n\n## Sử dụng macro để thiết lập hậu tố gói\n#setPackageSuffix(\"entity\")\n## Định dạng tên bảng (đảm bảo định dạng gạch dưới chữ thường)\n## Sử dụng biến toàn cục để nhập gói mặc định\n$!{autoImport.vm}\nimport com.baomidou.mybatisplus.annotation.IdType;\nimport com.baomidou.mybatisplus.annotation.TableId;\nimport com.baomidou.mybatisplus.annotation.TableName;\nimport lombok.Data;\nimport lombok.experimental.Accessors;\nimport java.io.Serializable;\n\n## Sử dụng macro để triển khai thông tin chú thích lớp\n#tableComment(\"lớp thực thể\")\n@TableName(value = \"$!{tableInfo.obj.name}\")\n@Data\n@Accessors(chain = true)\npublic class $!{tableInfo.name} implements Serializable {\n\n /**\n * ID tuần tự hóa\n */\n private static final long serialVersionUID = $!tool.serial();\n \n#foreach($column in $tableInfo.fullColumn)\n #if(${column.comment})\n \n /**\n * ${column.comment}\n */\n #end\n #if(${column.name} == \"id\")\n @TableId(type = IdType.AUTO)\n #end\n private $!{tool.getClsNameByFullName($column.type)} $!{column.name};\n#end\n\n}\n\n"
}, {
"name" : "mapper.xml.vm",
"code" : "## Nhập hỗ trợ Mybatis\n$!{mybatisSupport.vm}\n\n## Thiết lập tên lưu và vị trí lưu\n$!callback.setFileName($tool.append($!{tableInfo.name}, \"Mapper.xml\"))\n$!callback.setSavePath($tool.append($modulePath, \"/src/main/resources/mapper\"))\n\n## Lấy khóa chính\n#if(!$tableInfo.pkColumn.isEmpty())\n #set($pk = $tableInfo.pkColumn.get(0))\n#end\n\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<mapper namespace=\"$!{tableInfo.savePackageName}.mapper.$!{tableInfo.name}Mapper\">\n\n <resultMap type=\"$!{tableInfo.savePackageName}.entity.$!{tableInfo.name}\" id=\"$!{tableInfo.name}Map\">\n#foreach($column in $tableInfo.fullColumn)\n <result property=\"$!column.name\" column=\"$!column.obj.name\" jdbcType=\"$!column.ext.jdbcType\"/>\n#end\n </resultMap>\n\n <sql id=\"Base_Column_List\" >\n #allSqlColumn() \n </sql>\n <!-- Truy vấn tất cả -->\n <select id=\"queryList\" resultMap=\"$!{tableInfo.name}Map\">\n select\n <include refid=\"Base_Column_List\"></include>\n from $!tableInfo.obj.name\n <where>\n#foreach($column in $tableInfo.fullColumn)\n <if test=\"$!column.name != null#if($column.type.equals(\"java.lang.String\")) and $!column.name != ''#end\">\n and $!column.obj.name = #{$!column.name}\n </if>\n#end\n </where>\n </select>\n \n <!-- Truy vấn một đối tượng -->\n <select id=\"queryById\" resultMap=\"$!{tableInfo.name}Map\">\n select\n <include refid=\"Base_Column_List\"></include>\n from $!tableInfo.obj.name\n where $!pk.obj.name = #{$!pk.name}\n </select>\n\n <!-- Truy vấn dữ liệu theo số hàng chỉ định -->\n <select id=\"queryAllByLimit\" resultMap=\"$!{tableInfo.name}Map\">\n select\n <include refid=\"Base_Column_List\"></include>\n from $!tableInfo.obj.name\n <where>\n#foreach($column in $tableInfo.fullColumn)\n <if test=\"$!column.name != null#if($column.type.equals(\"java.lang.String\")) and $!column.name != ''#end\">\n and $!column.obj.name = #{$!column.name}\n </if>\n#end\n </where>\n limit #{pageable.offset}, #{pageable.pageSize}\n </select>\n\n <!-- Đếm tổng số hàng -->\n <select id=\"count\" resultType=\"java.lang.Long\">\n select count(1)\n from $!tableInfo.obj.name\n <where>\n#foreach($column in $tableInfo.fullColumn)\n <if test=\"$!column.name != null#if($column.type.equals(\"java.lang.String\")) and $!column.name != ''#end\">\n and $!column.obj.name = #{$!column.name}\n </if>\n#end\n </where>\n </select>\n\n <!-- Thêm tất cả các cột -->\n <insert id=\"insert\" keyProperty=\"$!pk.name\" useGeneratedKeys=\"true\">\n insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($foreach.hasNext), #end#end)\n values (#foreach($column in $tableInfo.otherColumn)#{$!{column.name}}#if($foreach.hasNext), #end#end)\n </insert>\n\n <insert id=\"insertBatch\" keyProperty=\"$!pk.name\" useGeneratedKeys=\"true\">\n insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($foreach.hasNext), #end#end)\n values\n <foreach collection=\"entities\" item=\"entity\" separator=\",\">\n (#foreach($column in $tableInfo.otherColumn)#{entity.$!{column.name}}#if($foreach.hasNext), #end#end)\n </foreach>\n </insert>\n\n <insert id=\"insertOrUpdateBatch\" keyProperty=\"$!pk.name\" useGeneratedKeys=\"true\">\n insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($foreach.hasNext), #end#end)\n values\n <foreach collection=\"entities\" item=\"entity\" separator=\",\">\n (#foreach($column in $tableInfo.otherColumn)#{entity.$!{column.name}}#if($foreach.hasNext), #end#end)\n </foreach>\n on duplicate key update\n #foreach($column in $tableInfo.otherColumn)$!column.obj.name = values($!column.obj.name)#if($foreach.hasNext),\n #end#end\n\n </insert>\n\n <!-- Cập nhật dữ liệu bằng khóa chính -->\n <update id=\"update\">\n update $!{tableInfo.obj.name}\n <set>\n#foreach($column in $tableInfo.otherColumn)\n <if test=\"$!column.name != null#if($column.type.equals(\"java.lang.String\")) and $!column.name != ''#end\">\n $!column.obj.name = #{$!column.name},\n </if>\n#end\n </set>\n where $!pk.obj.name = #{$!pk.name}\n </update>\n\n <!-- Xóa bằng khóa chính -->\n <delete id=\"deleteById\">\n delete from $!{tableInfo.obj.name} where $!pk.obj.name = #{$!pk.name}\n </delete>\n\n</mapper>\n\n"
}, {
"name" : "service.java.vm",
"code" : "## Định nghĩa biến ban đầu\n#set($tenService = $tool.append($tableInfo.name, \"Service\"))\n## Thiết lập callback\n$!callback.setFileName($tool.append($tenService, \".java\"))\n$!callback.setSavePath($tool.append($tableInfo.savePath, \"/service\"))\n\n## Lấy khóa chính\n#if(!$tableInfo.pkColumn.isEmpty())\n #set($pk = $tableInfo.pkColumn.get(0))\n#end\n\n#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service;\n\nimport $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};\nimport com.baomidou.mybatisplus.extension.service.IService;\nimport java.util.List;\n\n/**\n * Giao diện dịch vụ cho bảng $!{tableInfo.comment}($!{tableInfo.name})\n *\n * @author $!author\n * @since $!time.currTime()\n */\npublic interface $!{tenService} extends IService<$!{tableInfo.name}>{\n\n /**\n * Truy vấn tất cả dữ liệu theo các tiêu chí đã cho\n *\n * @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể làm tham số truy vấn\n * @return Danh sách các đối tượng thực thể\n */\n List<$!{tableInfo.name}> queryList($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));\n \n /**\n * Truy vấn một đối tượng theo ID\n *\n * @param $!pk.name Khóa chính\n * @return Đối tượng thực thể\n */\n $!{tableInfo.name} queryById($!pk.shortType $!pk.name);\n\n /**\n * Thêm mới một bản ghi dữ liệu\n *\n * @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể\n * @return Đối tượng thực thể sau khi thêm mới\n */\n $!{tableInfo.name} insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));\n\n /**\n * Cập nhật một bản ghi dữ liệu\n *\n * @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể\n * @return Đối tượng thực thể sau khi cập nhật\n */\n $!{tableInfo.name} update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));\n\n /**\n * Xóa dữ liệu theo ID chính\n *\n * @param $!pk.name Khóa chính\n * @return True nếu thành công, false nếu thất bại\n */\n boolean deleteById($!pk.shortType $!pk.name);\n\n /**\n * Xóa hàng loạt dữ liệu theo các ID chính\n *\n * @param ids Chuỗi các ID chính (ngăn cách bằng dấu phẩy)\n * @return True nếu thành công, false nếu thất bại\n */\n boolean deleteBatchByIds(String ids);\n}\n"
}, {
"name" : "serviceImpl.java.vm",
"code" : "## Định nghĩa biến ban đầu\n#set($tenServiceImpl = $tool.append($tableInfo.name, \"ServiceImpl\"))\n## Thiết lập callback\n$!callback.setFileName($tool.append($tenServiceImpl, \".java\"))\n$!callback.setSavePath($tool.append($tableInfo.savePath, \"/service/impl\"))\n\n## Lấy khóa chính\n#if(!$tableInfo.pkColumn.isEmpty())\n #set($pk = $tableInfo.pkColumn.get(0))\n#end\n\n#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service.impl;\n\nimport $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};\nimport $!{tableInfo.savePackageName}.mapper.$!{tableInfo.name}Mapper;\nimport $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service;\nimport org.springframework.stereotype.Service;\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.stream.Collectors;\nimport javax.annotation.Resource;\n\n/**\n * Lớp triển khai dịch vụ cho bảng $!{tableInfo.comment}($!{tableInfo.name})\n *\n * @author $!author\n * @since $!time.currTime()\n */\n@Service(\"$!tool.firstLowerCase($!{tableInfo.name})Service\")\npublic class $!{tenServiceImpl} extends ServiceImpl<$!{tableInfo.name}Mapper, $!{tableInfo.name}> implements $!{tableInfo.name}Service {\n @Resource\n private $!{tableInfo.name}Mapper $!tool.firstLowerCase($!{tableInfo.name})Mapper;\n\n /**\n * Truy vấn tất cả dữ liệu theo các tiêu chí đã cho\n *\n * @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể để lọc\n * @return Danh sách các đối tượng thực thể\n */\n @Override\n public List<$!{tableInfo.name}> queryList($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {\n return this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.queryList($!tool.firstLowerCase($!{tableInfo.name}));\n }\n \n /**\n * Truy vấn một đối tượng theo ID\n *\n * @param $!pk.name Khóa chính\n * @return Đối tượng thực thể\n */\n @Override\n public $!{tableInfo.name} queryById($!pk.shortType $!pk.name) {\n return this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.queryById($!pk.name);\n }\n\n /**\n * Thêm mới một bản ghi dữ liệu\n *\n * @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể\n * @return Đối tượng thực thể sau khi thêm mới\n */\n @Override\n public $!{tableInfo.name} insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {\n this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.insert($!tool.firstLowerCase($!{tableInfo.name}));\n return $!tool.firstLowerCase($!{tableInfo.name});\n }\n\n /**\n * Cập nhật một bản ghi dữ liệu\n *\n * @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể\n * @return Đối tượng thực thể sau khi cập nhật\n */\n @Override\n public $!{tableInfo.name} update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {\n this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.update($!tool.firstLowerCase($!{tableInfo.name}));\n return this.queryById($!{tool.firstLowerCase($!{tableInfo.name})}.get$!tool.firstUpperCase($pk.name)());\n }\n\n /**\n * Xóa dữ liệu theo ID chính\n *\n * @param $!pk.name Khóa chính\n * @return True nếu thành công, false nếu thất bại\n */\n @Override\n public boolean deleteById($!pk.shortType $!pk.name) {\n return this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.deleteById($!pk.name) > 0;\n }\n \n /**\n * Xóa hàng loạt dữ liệu theo các ID chính\n *\n * @param ids Chuỗi các ID chính (ngăn cách bằng dấu phẩy)\n * @return True nếu thành công, false nếu thất bại\n */\n @Override\n public boolean deleteBatchByIds(String ids) {\n List<$!pk.shortType> idList = Arrays.stream(ids.split(\",\")).map($!pk.shortType::new).collect(Collectors.toList());\n return this.removeBatchByIds(idList);\n }\n}\n"
}, {
"name" : "mapper.java.vm",
"code" : "## Định nghĩa biến ban đầu\n#set($tenMapper = $tool.append($tableInfo.name, \"Mapper\"))\n## Thiết lập callback\n$!callback.setFileName($tool.append($tenMapper, \".java\"))\n$!callback.setSavePath($tool.append($tableInfo.savePath, \"/mapper\"))\n\n## Lấy khóa chính\n#if(!$tableInfo.pkColumn.isEmpty())\n #set($pk = $tableInfo.pkColumn.get(0))\n#end\n\n#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}mapper;\n\nimport $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};\nimport org.apache.ibatis.annotations.Param;\nimport org.apache.ibatis.annotations.Mapper;\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport java.util.List;\n\n/**\n * Lớp truy cập cơ sở dữ liệu cho bảng $!{tableInfo.comment}($!{tableInfo.name})\n *\n * @author $!author\n * @since $!time.currTime()\n */\n@Mapper\npublic interface $!{tenMapper} extends BaseMapper<$!{tableInfo.name}>{\n\n /**\n * Truy vấn tất cả dữ liệu theo các tiêu chí đã cho\n *\n * @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể làm tham số truy vấn\n * @return Danh sách các đối tượng thực thể\n */\n List<$!{tableInfo.name}> queryList($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));\n \n /**\n * Truy vấn một đối tượng theo ID\n *\n * @param $!pk.name Khóa chính\n * @return Đối tượng thực thể\n */\n $!{tableInfo.name} queryById($!pk.shortType $!pk.name);\n \n /**\n * Đếm tổng số hàng\n *\n * @param $!tool.firstLowerCase($!{tableInfo.name}) Điều kiện truy vấn\n * @return Tổng số hàng\n */\n long count($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));\n\n /**\n * Thêm mới một bản ghi dữ liệu\n *\n * @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể\n * @return Số hàng bị ảnh hưởng\n */\n int insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));\n\n /**\n * Thêm mới hàng loạt dữ liệu (phương thức foreach gốc của MyBatis)\n *\n * @param entities List<$!{tableInfo.name}> Danh sách đối tượng thực thể\n * @return Số hàng bị ảnh hưởng\n */\n int insertBatch(@Param(\"entities\") List<$!{tableInfo.name}> entities);\n\n /**\n * Thêm mới hoặc cập nhật hàng loạt dữ liệu theo khóa chính (phương thức foreach gốc của MyBatis)\n *\n * @param entities List<$!{tableInfo.name}> Danh sách đối tượng thực thể\n * @return Số hàng bị ảnh hưởng\n * @throws org.springframework.jdbc.BadSqlGrammarException Nếu tham số đầu vào là List rỗng, sẽ ném ngoại lệ SQL syntax error, vui lòng tự kiểm tra tham số đầu vào\n */\n int insertOrUpdateBatch(@Param(\"entities\") List<$!{tableInfo.name}> entities);\n\n /**\n * Cập nhật dữ liệu\n *\n * @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể\n * @return Số hàng bị ảnh hưởng\n */\n int update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));\n\n /**\n * Xóa dữ liệu theo ID chính\n *\n * @param $!pk.name Khóa chính\n * @return Số hàng bị ảnh hưởng\n */\n int deleteById($!pk.shortType $!pk.name);\n\n}\n\n"
} ]
}
},
"columnConfig" : {
"Default" : {
"name" : "Default",
"elementList" : [ {
"title" : "disable",
"type" : "BOOLEAN",
"selectValue" : ""
}, {
"title" : "support",
"type" : "SELECT",
"selectValue" : "add,edit,query,del,ui"
} ]
}
},
"globalConfig" : {
"Default" : {
"name" : "Default",
"elementList" : [ {
"name" : "autoImport.vm",
"value" : "## Tự động nhập gói (chỉ nhập các gói cần thiết cho thuộc tính thực thể, thường dùng cho lớp thực thể)\n#foreach($import in $importList)\nimport $!import;\n#end"
}, {
"name" : "define.vm",
"value" : "## (Định nghĩa macro Velocity)\n\n## Định nghĩa macro để thiết lập hậu tố tên bảng, cách gọi: #setTableSuffix(\"Test\")\n#macro(setTableSuffix $suffix)\n #set($tableName = $!tool.append($tableInfo.name, $suffix))\n#end\n\n## Định nghĩa macro để thiết lập hậu tố tên gói, cách gọi: #setPackageSuffix(\"Test\")\n#macro(setPackageSuffix $suffix)\n#if($suffix!=\"\")package #end#if($tableInfo.savePackageName!=\"\")$!{tableInfo.savePackageName}.#{end}$!suffix;\n#end\n\n## Định nghĩa macro để đơn giản hóa đường dẫn lưu và tên tệp, cách gọi: #save(\"/entity\", \".java\")\n#macro(save $path $fileName)\n $!callback.setSavePath($tool.append($tableInfo.savePath, $path))\n $!callback.setFileName($tool.append($tableInfo.name, $fileName))\n#end\n\n## Định nghĩa macro để triển khai thông tin chú thích bảng, cách gọi: #tableComment(\"Thông tin chú thích\")\n#macro(tableComment $desc)\n/**\n * $!{tableInfo.comment}($!{tableInfo.name})$desc\n *\n * @author $!author\n * @since $!time.currTime()\n */\n#end\n\n## Định nghĩa macro cho phương thức GET, SET, cách gọi: #getSetMethod($column)\n#macro(getSetMethod $column)\n\n public $!{tool.getClsNameByFullName($column.type)} get$!{tool.firstUpperCase($column.name)}() {\n return $!{column.name};\n }\n\n public void set$!{tool.firstUpperCase($column.name)}($!{tool.getClsNameByFullName($column.type)} $!{column.name}) {\n this.$!{column.name} = $!{column.name};\n }\n#end"
}, {
"name" : "init.vm",
"value" : "## Khu vực khởi tạo\n\n## Bỏ tiền tố \"book_\" khỏi tên bảng\n$!tableInfo.setName($tool.getClassName($tableInfo.obj.name.replaceFirst(\"book_\",\"\")))\n\n## Theo hướng dẫn phát triển của Alibaba, các biến kiểu boolean trong lớp POJO không nên có tiền tố \"is\", nếu không một số framework có thể gây lỗi tuần tự hóa\n#foreach($column in $tableInfo.fullColumn)\n#if($column.name.startsWith(\"is\") && $column.type.equals(\"java.lang.Boolean\"))\n $!column.setName($tool.firstLowerCase($column.name.substring(2)))\n#end\n#end\n\n## Triển khai loại trừ cột động\n#set($temp = $tool.newHashSet(\"testCreateTime\", \"otherColumn\"))\n#foreach($item in $temp)\n #set($newList = $tool.newArrayList())\n #foreach($column in $tableInfo.fullColumn)\n #if($column.name!=$item)\n ## Khi gọi phương thức có giá trị trả về, sử dụng $tool.call để loại bỏ giá trị trả về\n $tool.call($newList.add($column))\n #end\n #end\n ## Lưu lại\n $tableInfo.setFullColumn($newList)\n#end\n\n## Thay đổi importList\n#set($temp = $tool.newHashSet())\n#foreach($column in $tableInfo.fullColumn)\n #if(!$column.type.startsWith(\"java.lang.\"))\n ## Khi gọi phương thức có giá trị trả về, sử dụng $tool.call để loại bỏ giá trị trả về\n $tool.call($temp.add($column.type))\n #end\n#end\n## Ghi đè\n#set($importList = $temp)"
}, {
"name" : "mybatisSupport.vm",
"value" : "## Hỗ trợ Mybatis, chủ yếu được sử dụng để phát sinh tệp xml\n#foreach($column in $tableInfo.fullColumn)\n ## Lưu kiểu cột\n $tool.call($column.ext.put(\"sqlType\", $tool.getField($column.obj.dataType, \"typeName\")))\n #if($tool.newHashSet(\"java.lang.String\").contains($column.type))\n #set($jdbcType=\"VARCHAR\")\n #elseif($tool.newHashSet(\"java.lang.Boolean\", \"boolean\").contains($column.type))\n #set($jdbcType=\"BOOLEAN\")\n #elseif($tool.newHashSet(\"java.lang.Byte\", \"byte\").contains($column.type))\n #set($jdbcType=\"BYTE\")\n #elseif($tool.newHashSet(\"java.lang.Integer\", \"int\", \"java.lang.Short\", \"short\").contains($column.type))\n #set($jdbcType=\"INTEGER\")\n #elseif($tool.newHashSet(\"java.lang.Long\", \"long\").contains($column.type))\n #set($jdbcType=\"INTEGER\")\n #elseif($tool.newHashSet(\"java.lang.Float\", \"float\", \"java.lang.Double\", \"double\").contains($column.type))\n #set($jdbcType=\"NUMERIC\")\n #elseif($tool.newHashSet(\"java.util.Date\", \"java.sql.Timestamp\", \"java.time.Instant\", \"java.time.LocalDateTime\", \"java.time.OffsetDateTime\", \"\tjava.time.ZonedDateTime\").contains($column.type))\n #set($jdbcType=\"TIMESTAMP\")\n #elseif($tool.newHashSet(\"java.sql.Date\", \"java.time.LocalDate\").contains($column.type))\n #set($jdbcType=\"DATE\") ## Đã sửa từ TIMESTAMP sang DATE cho LocalDate và java.sql.Date\n #else\n ## Các kiểu khác\n #set($jdbcType=\"VARCHAR\")\n #end\n $tool.call($column.ext.put(\"jdbcType\", $jdbcType))\n#end\n\n## Định nghĩa macro, truy vấn tất cả các cột\n#macro(allSqlColumn)#foreach($column in $tableInfo.fullColumn)$column.obj.name#if($foreach.hasNext), #end#end#end\n"
} ]
}
}
}
Phương pháp 2: Tự Tạo Mẫu Thủ Công
Nếu bạn muốn kiểm soát chi tiết hơn hoặc chỉ cần một số mẫu nhất định, bạn có thể tạo chúng thủ công trong cài đặt EasyCode.
entity.java.vm
## Nhập định nghĩa macro
$!{define.vm}
## Thiết lập vị trí và phần mở rộng tệp lưu
#save("/entity", ".java")
## Thiết lập hậu tố gói
#setPackageSuffix("entity")
## Tự động nhập gói mặc định
$!{autoImport.vm}
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
## Chú thích lớp thực thể
#tableComment("lớp thực thể")
@TableName(value = "$!{tableInfo.obj.name}")
@Data
@Accessors(chain = true)
public class $!{tableInfo.name} implements Serializable {
/**
* ID tuần tự hóa
*/
private static final long serialVersionUID = $!tool.serial();
#foreach($column in $tableInfo.fullColumn)
#if(${column.comment})
/**
* ${column.comment}
*/
#end
#if(${column.name} == "id")
@TableId(type = IdType.AUTO)
#end
private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
#end
}
controller.java.vm
## Định nghĩa tên lớp điều khiển
#set($tenController = $tool.append($tableInfo.name, "Controller"))
## Thiết lập tên tệp và đường dẫn lưu
$!callback.setFileName($tool.append($tenController, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/controller"))
## Lấy thông tin khóa chính
#if(!$tableInfo.pkColumn.isEmpty())
#set($pk = $tableInfo.pkColumn.get(0))
#end
#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}controller;
import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
import $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* REST Controller cho bảng $!{tableInfo.comment} ($!{tableInfo.name})
*
* @author $!author
* @since $!time.currTime()
*/
@RestController
@RequestMapping("/api/$!tool.firstLowerCase($tableInfo.name)")
public class $!{tenController} {
/**
* Tham chiếu đến đối tượng dịch vụ
*/
@Resource
private $!{tableInfo.name}Service $!tool.firstLowerCase($tableInfo.name)Service;
/**
* Lấy tất cả các bản ghi, có thể kèm theo điều kiện lọc
*
* @param $!{tool.firstLowerCase($tableInfo.name)} Đối tượng thực thể chứa các tiêu chí lọc
* @return Kết quả API chứa danh sách các bản ghi
*/
@GetMapping
public ApiResponse getAllRecords($!{tableInfo.name} $!{tool.firstLowerCase($tableInfo.name)}) {
List<$!{tableInfo.name}> records = this.$!{tool.firstLowerCase($tableInfo.name)}Service.queryList($!{tool.firstLowerCase($tableInfo.name)});
return ApiResponse.success(records);
}
/**
* Lấy một bản ghi theo ID
*
* @param id Khóa chính của bản ghi
* @return Kết quả API chứa bản ghi duy nhất
*/
@GetMapping(\"{id}\")
public ApiResponse getRecordById(@PathVariable(\"id\") $!pk.shortType id) {
$!{tableInfo.name} record = this.$!{tool.firstLowerCase($tableInfo.name)}Service.queryById(id);
return ApiResponse.success(record);
}
/**
* Thêm một bản ghi mới
*
* @param $!{tool.firstLowerCase($tableInfo.name)} Đối tượng thực thể để thêm
* @return Kết quả API chứa bản ghi đã thêm
*/
@PostMapping
public ApiResponse createRecord(@RequestBody $!{tableInfo.name} $!{tool.firstLowerCase($tableInfo.name)}) {
$!{tableInfo.name} createdRecord = this.$!{tool.firstLowerCase($tableInfo.name)}Service.insert($!{tool.firstLowerCase($tableInfo.name)});
return ApiResponse.success(createdRecord);
}
/**
* Cập nhật một bản ghi hiện có
*
* @param $!{tool.firstLowerCase($tableInfo.name)} Đối tượng thực thể với dữ liệu cập nhật
* @return Kết quả API chứa bản ghi đã cập nhật
*/
@PutMapping
public ApiResponse updateRecord(@RequestBody $!{tableInfo.name} $!{tool.firstLowerCase($tableInfo.name)}) {
$!{tableInfo.name} updatedRecord = this.$!{tool.firstLowerCase($tableInfo.name)}Service.update($!{tool.firstLowerCase($tableInfo.name)});
return ApiResponse.success(updatedRecord);
}
/**
* Xóa một bản ghi theo ID
*
* @param id Khóa chính của bản ghi cần xóa
* @return Kết quả API cho biết thao tác xóa có thành công không
*/
@DeleteMapping(\"{id}\")
public ApiResponse deleteRecord(@PathVariable(\"id\") $!pk.shortType id) {
boolean deleted = this.$!{tool.firstLowerCase($tableInfo.name)}Service.deleteById(id);
return deleted ? ApiResponse.success("Xóa thành công") : ApiResponse.error("Xóa thất bại");
}
}
service.java.vm
## Định nghĩa tên giao diện dịch vụ
#set($tenService = $tool.append($tableInfo.name, "Service"))
## Thiết lập tên tệp và đường dẫn lưu
$!callback.setFileName($tool.append($tenService, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/service"))
## Lấy thông tin khóa chính
#if(!$tableInfo.pkColumn.isEmpty())
#set($pk = $tableInfo.pkColumn.get(0))
#end
#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service;\n
import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* Giao diện dịch vụ cho bảng $!{tableInfo.comment} ($!{tableInfo.name})
*
* @author $!author
* @since $!time.currTime()
*/
public interface $!{tenService} extends IService<$!{tableInfo.name}> {
/**
* Truy vấn danh sách các đối tượng thực thể dựa trên tiêu chí
*
* @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể chứa điều kiện truy vấn
* @return Danh sách các đối tượng thực thể
*/
List<$!{tableInfo.name}> queryList($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));
/**
* Truy vấn một đối tượng thực thể theo ID
*
* @param $!pk.name Khóa chính của đối tượng
* @return Đối tượng thực thể tìm được, hoặc null nếu không tồn tại
*/
$!{tableInfo.name} queryById($!pk.shortType $!pk.name);
/**
* Thêm mới một đối tượng thực thể vào cơ sở dữ liệu
*
* @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể cần thêm
* @return Đối tượng thực thể sau khi thêm (có thể đã được cập nhật ID)
*/
$!{tableInfo.name} insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));
/**
* Cập nhật một đối tượng thực thể hiện có
*
* @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể với các trường đã cập nhật
* @return Đối tượng thực thể sau khi cập nhật
*/
$!{tableInfo.name} update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));
/**
* Xóa một đối tượng thực thể theo ID chính
*
* @param $!pk.name Khóa chính của đối tượng cần xóa
* @return true nếu xóa thành công, false nếu thất bại
*/
boolean deleteById($!pk.shortType $!pk.name);
/**
* Xóa hàng loạt các đối tượng thực thể theo danh sách ID
*
* @param ids Chuỗi các ID (ngăn cách bằng dấu phẩy)
* @return true nếu xóa hàng loạt thành công, false nếu thất bại
*/
boolean deleteBatchByIds(String ids);
}
serviceImpl.java.vm
## Định nghĩa tên lớp triển khai dịch vụ
#set($tenServiceImpl = $tool.append($tableInfo.name, "ServiceImpl"))
## Thiết lập tên tệp và đường dẫn lưu
$!callback.setFileName($tool.append($tenServiceImpl, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/service/impl"))
## Lấy thông tin khóa chính
#if(!$tableInfo.pkColumn.isEmpty())
#set($pk = $tableInfo.pkColumn.get(0))
#end
#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service.impl;\n
import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};\n
import $!{tableInfo.savePackageName}.mapper.$!{tableInfo.name}Mapper;\n
import $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service;\n
import org.springframework.stereotype.Service;\n
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\n
import java.util.Arrays;\n
import java.util.List;\n
import java.util.stream.Collectors;\n
import javax.annotation.Resource;\n
/**
* Triển khai giao diện dịch vụ cho bảng $!{tableInfo.comment} ($!{tableInfo.name})
*
* @author $!author
* @since $!time.currTime()
*/
@Service(\"$!tool.firstLowerCase($!{tableInfo.name})Service\")
public class $!{tenServiceImpl} extends ServiceImpl<$!{tableInfo.name}Mapper, $!{tableInfo.name}> implements $!{tableInfo.name}Service {
@Resource
private $!{tableInfo.name}Mapper $!tool.firstLowerCase($!{tableInfo.name})Mapper;
/**
* Truy vấn danh sách các đối tượng thực thể dựa trên tiêu chí
*
* @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể chứa điều kiện truy vấn
* @return Danh sách các đối tượng thực thể
*/
@Override
public List<$!{tableInfo.name}> queryList($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {
return this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.queryList($!tool.firstLowerCase($!{tableInfo.name}));
}
/**
* Truy vấn một đối tượng thực thể theo ID
*
* @param $!pk.name Khóa chính của đối tượng
* @return Đối tượng thực thể tìm được, hoặc null nếu không tồn tại
*/
@Override
public $!{tableInfo.name} queryById($!pk.shortType $!pk.name) {
return this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.queryById($!pk.name);
}
/**
* Thêm mới một đối tượng thực thể vào cơ sở dữ liệu
*
* @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể cần thêm
* @return Đối tượng thực thể sau khi thêm (có thể đã được cập nhật ID)
*/
@Override
public $!{tableInfo.name} insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {
this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.insert($!tool.firstLowerCase($!{tableInfo.name}));
return $!tool.firstLowerCase($!{tableInfo.name});
}
/**
* Cập nhật một đối tượng thực thể hiện có
*
* @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể với các trường đã cập nhật
* @return Đối tượng thực thể sau khi cập nhật
*/
@Override
public $!{tableInfo.name} update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {
this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.update($!tool.firstLowerCase($!{tableInfo.name}));
return this.queryById($!{tool.firstLowerCase($!{tableInfo.name})}.get$!tool.firstUpperCase($pk.name)());
}
/**
* Xóa một đối tượng thực thể theo ID chính
*
* @param $!pk.name Khóa chính của đối tượng cần xóa
* @return true nếu xóa thành công, false nếu thất bại
*/
@Override
public boolean deleteById($!pk.shortType $!pk.name) {
return this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.deleteById($!pk.name) > 0;
}
/**
* Xóa hàng loạt các đối tượng thực thể theo danh sách ID
*
* @param ids Chuỗi các ID (ngăn cách bằng dấu phẩy)
* @return true nếu xóa hàng loạt thành công, false nếu thất bại
*/
@Override
public boolean deleteBatchByIds(String ids) {
List<$!pk.shortType> idList = Arrays.stream(ids.split(\",\")).map($!pk.shortType::new).collect(Collectors.toList());
return this.removeBatchByIds(idList);
}
}
mapper.java.vm
## Định nghĩa tên giao diện Mapper
#set($tenMapper = $tool.append($tableInfo.name, "Mapper"))
## Thiết lập tên tệp và đường dẫn lưu
$!callback.setFileName($tool.append($tenMapper, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/mapper"))
## Lấy thông tin khóa chính
#if(!$tableInfo.pkColumn.isEmpty())
#set($pk = $tableInfo.pkColumn.get(0))
#end
#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}mapper;\n
import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};\n
import org.apache.ibatis.annotations.Param;\n
import org.apache.ibatis.annotations.Mapper;\n
import com.baomidou.mybatisplus.core.mapper.BaseMapper;\n
import java.util.List;\n
/**
* Giao diện truy cập cơ sở dữ liệu (Mapper) cho bảng $!{tableInfo.comment} ($!{tableInfo.name})
*
* @author $!author
* @since $!time.currTime()
*/
@Mapper
public interface $!{tenMapper} extends BaseMapper<$!{tableInfo.name}> {
/**
* Truy vấn danh sách các đối tượng thực thể dựa trên tiêu chí
*
* @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể chứa điều kiện truy vấn
* @return Danh sách các đối tượng thực thể
*/
List<$!{tableInfo.name}> queryList($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));
/**
* Truy vấn một đối tượng thực thể theo ID
*
* @param $!pk.name Khóa chính của đối tượng
* @return Đối tượng thực thể tìm được, hoặc null nếu không tồn tại
*/
$!{tableInfo.name} queryById($!pk.shortType $!pk.name);
/**
* Đếm tổng số hàng dựa trên điều kiện truy vấn
*
* @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể chứa điều kiện truy vấn
* @return Tổng số hàng
*/
long count($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));
/**
* Thêm mới một đối tượng thực thể vào cơ sở dữ liệu
*
* @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể cần thêm
* @return Số hàng bị ảnh hưởng
*/
int insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));
/**
* Thêm mới hàng loạt đối tượng thực thể
*
* @param entities Danh sách các đối tượng thực thể cần thêm
* @return Số hàng bị ảnh hưởng
*/
int insertBatch(@Param(\"entities\") List<$!{tableInfo.name}> entities);
/**
* Thêm mới hoặc cập nhật hàng loạt đối tượng thực thể (dựa trên khóa chính)
*
* @param entities Danh sách các đối tượng thực thể cần thêm/cập nhật
* @return Số hàng bị ảnh hưởng
* @throws org.springframework.jdbc.BadSqlGrammarException Ngoại lệ nếu tham số đầu vào là List rỗng
*/
int insertOrUpdateBatch(@Param(\"entities\") List<$!{tableInfo.name}> entities);\n
/**
* Cập nhật một đối tượng thực thể hiện có
*
* @param $!tool.firstLowerCase($!{tableInfo.name}) Đối tượng thực thể với các trường đã cập nhật
* @return Số hàng bị ảnh hưởng
*/
int update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));
/**
* Xóa một đối tượng thực thể theo ID chính
*
* @param $!pk.name Khóa chính của đối tượng cần xóa
* @return Số hàng bị ảnh hưởng
*/
int deleteById($!pk.shortType $!pk.name);\n
}
mapper.xml.vm
## Nhập hỗ trợ Mybatis
$!{mybatisSupport.vm}
## Thiết lập tên tệp và đường dẫn lưu cho XML Mapper
$!callback.setFileName($tool.append($!{tableInfo.name}, "Mapper.xml"))
$!callback.setSavePath($tool.append($modulePath, "/src/main/resources/mapper"))
## Lấy thông tin khóa chính
#if(!$tableInfo.pkColumn.isEmpty())
#set($pk = $tableInfo.pkColumn.get(0))
#end
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<mapper namespace=\"$!{tableInfo.savePackageName}.mapper.$!{tableInfo.name}Mapper\">\n
<resultMap type=\"$!{tableInfo.savePackageName}.entity.$!{tableInfo.name}\" id=\"$!{tableInfo.name}Map\">\n
#foreach($column in $tableInfo.fullColumn)\n
<result property=\"$!column.name\" column=\"$!column.obj.name\" jdbcType=\"$!column.ext.jdbcType\"/>\n
#end\n
</resultMap>\n
<sql id=\"Base_Column_List\" >\n
#allSqlColumn() \n
</sql>\n
<!-- Truy vấn tất cả các bản ghi -->\n
<select id=\"queryList\" resultMap=\"$!{tableInfo.name}Map\">\n
select\n
<include refid=\"Base_Column_List\"></include>\n
from $!tableInfo.obj.name\n
<where>\n
#foreach($column in $tableInfo.fullColumn)\n
<if test=\"$!column.name != null#if($column.type.equals(\"java.lang.String\")) and $!column.name != ''#end\">\n
and $!column.obj.name = #{$!column.name}\n
</if>\n
#end\n
</where>\n
</select>\n
<!-- Truy vấn một bản ghi theo ID -->\n
<select id=\"queryById\" resultMap=\"$!{tableInfo.name}Map\">\n
select\n
<include refid=\"Base_Column_List\"></include>\n
from $!tableInfo.obj.name\n
where $!pk.obj.name = #{$!pk.name}\n
</select>\n
<!-- Truy vấn dữ liệu theo số hàng giới hạn -->\n
<select id=\"queryAllByLimit\" resultMap=\"$!{tableInfo.name}Map\">\n
select\n
<include refid=\"Base_Column_List\"></include>\n
from $!tableInfo.obj.name\n
<where>\n
#foreach($column in $tableInfo.fullColumn)\n
<if test=\"$!column.name != null#if($column.type.equals(\"java.lang.String\")) and $!column.name != ''#end\">\n
and $!column.obj.name = #{$!column.name}\n
</if>\n
#end\n
</where>\n
limit #{pageable.offset}, #{pageable.pageSize}\n
</select>\n
<!-- Đếm tổng số hàng -->\n
<select id=\"count\" resultType=\"java.lang.Long\">\n
select count(1)\n
from $!tableInfo.obj.name\n
<where>\n
#foreach($column in $tableInfo.fullColumn)\n
<if test=\"$!column.name != null#if($column.type.equals(\"java.lang.String\")) and $!column.name != ''#end\">\n
and $!column.obj.name = #{$!column.name}\n
</if>\n
#end\n
</where>\n
</select>\n
<!-- Thêm mới tất cả các cột -->\n
<insert id=\"insert\" keyProperty=\"$!pk.name\" useGeneratedKeys=\"true\">\n
insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($foreach.hasNext), #end#end)\n
values (#foreach($column in $tableInfo.otherColumn)#{$!{column.name}}#if($foreach.hasNext), #end#end)\n
</insert>\n
<insert id=\"insertBatch\" keyProperty=\"$!pk.name\" useGeneratedKeys=\"true\">\n
insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($foreach.hasNext), #end#end)\n
values\n
<foreach collection=\"entities\" item=\"entity\" separator=\",\">\n
(#foreach($column in $tableInfo.otherColumn)#{entity.$!{column.name}}#if($foreach.hasNext), #end#end)\n
</foreach>\n
</insert>\n
<insert id=\"insertOrUpdateBatch\" keyProperty=\"$!pk.name\" useGeneratedKeys=\"true\">\n
insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($foreach.hasNext), #end#end)\n
values\n
<foreach collection=\"entities\" item=\"entity\" separator=\",\">\n
(#foreach($column in $tableInfo.otherColumn)#{entity.$!{column.name}}#if($foreach.hasNext), #end#end)\n
</foreach>\n
on duplicate key update\n
#foreach($column in $tableInfo.otherColumn)$!column.obj.name = values($!column.obj.name)#if($foreach.hasNext),\n
#end#end\n
</insert>\n
<!-- Cập nhật dữ liệu bằng khóa chính -->\n
<update id=\"update\">\n
update $!{tableInfo.obj.name}\n
<set>\n
#foreach($column in $tableInfo.otherColumn)\n
<if test=\"$!column.name != null#if($column.type.equals(\"java.lang.String\")) and $!column.name != ''#end\">\n
$!column.obj.name = #{$!column.name},\n
</if>\n
#end\n
</set>\n
where $!pk.obj.name = #{$!pk.name}\n
</update>\n
<!-- Xóa bằng khóa chính -->\n
<delete id=\"deleteById\">\n
delete from $!{tableInfo.obj.name} where $!pk.obj.name = #{$!pk.name}\n
</delete>\n
</mapper>\n
Hướng dẫn Phát Sinh Mã
Sau khi đã cấu hình các mẫu theo một trong hai phương pháp trên, bạn có thể dễ dàng phát sinh mã:
- Mở cửa sổ cơ sở dữ liệu (Database window) trong IntelliJ IDEA.
- Chọn bảng mà bạn muốn phát sinh mã.
- Nhấp chuột phải vào bảng đã chọn và chọn
EasyCode -> Generate Code. - Trong hộp thoại phát sinh mã, chọn các mẫu bạn muốn sử dụng (ví dụ: Entity, Controller, Service, ServiceImpl, Mapper, Mapper XML).
- Nhấp vào nút
OKđể phát sinh mã.
Mã nguồn lớp ApiResponse
Để đảm bảo phản hồi API thống nhất, các mẫu Controller đã được cấu hình để sử dụng lớp ApiResponse tùy chỉnh. Dưới đây là mã nguồn của lớp này:
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* Lớp phản hồi API thống nhất
*/
public class ApiResponse implements Serializable {
private static final long serialVersionUID = 1L;
// Các hằng số cho nhãn trường trong phản hồi
private static final String KEY_THANH_CONG = "success";
private static final String KEY_MA_PHAN_HOI = "code";
private static final String KEY_THONG_DIEP = "message";
private static final String KEY_DU_LIEU = "data";
// Các mã trạng thái HTTP tùy chỉnh
private static class MaTrangThaiHTTP {
public static final int OK = 200; // Thành công
public static final int LOI_CLIENT = 400; // Lỗi từ phía client (Bad Request)
public static final int LOI_SERVER = 500; // Lỗi từ phía server (Internal Server Error)
}
private boolean success;
private int code;
private String message;
private Object data;
private Map<String, Object> additionalInfo; // Để mở rộng nếu cần
// Constructor riêng tư, khuyến khích sử dụng các phương thức factory tĩnh
private ApiResponse(boolean success, int code, String message, Object data) {
this.success = success;
this.code = code;
this.message = message;
this.data = data;
}
// Các phương thức factory tĩnh để tạo đối tượng ApiResponse
/**
* Trả về phản hồi thành công mặc định.
* @return Đối tượng ApiResponse thành công
*/
public static ApiResponse thanhCong() {
return thanhCong("Thao tác thành công", null);
}
/**
* Trả về phản hồi thành công với dữ liệu.
* @param duLieu Dữ liệu trả về
* @return Đối tượng ApiResponse thành công
*/
public static ApiResponse thanhCong(Object duLieu) {
return thanhCong("Thao tác thành công", duLieu);
}
/**
* Trả về phản hồi thành công với thông điệp tùy chỉnh.
* @param thongDiep Thông điệp thành công
* @return Đối tượng ApiResponse thành công
*/
public static ApiResponse thanhCong(String thongDiep) {
return thanhCong(thongDiep, null);
}
/**
* Trả về phản hồi thành công với thông điệp và dữ liệu tùy chỉnh.
* @param thongDiep Thông điệp thành công
* @param duLieu Dữ liệu trả về
* @return Đối tượng ApiResponse thành công
*/
public static ApiResponse thanhCong(String thongDiep, Object duLieu) {
return new ApiResponse(true, MaTrangThaiHTTP.OK, thongDiep, duLieu);
}
/**
* Trả về phản hồi cảnh báo với thông điệp.
* @param thongDiep Thông điệp cảnh báo
* @return Đối tượng ApiResponse cảnh báo
*/
public static ApiResponse canhBao(String thongDiep) {
return canhBao(thongDiep, null);
}
/**
* Trả về phản hồi cảnh báo với thông điệp và dữ liệu.
* @param thongDiep Thông điệp cảnh báo
* @param duLieu Dữ liệu trả về
* @return Đối tượng ApiResponse cảnh báo
*/
public static ApiResponse canhBao(String thongDiep, Object duLieu) {
return new ApiResponse(false, MaTrangThaiHTTP.LOI_CLIENT, thongDiep, duLieu);
}
/**
* Trả về phản hồi lỗi mặc định.
* @return Đối tượng ApiResponse lỗi
*/
public static ApiResponse loi() {
return loi("Thao tác thất bại");
}
/**
* Trả về phản hồi lỗi với thông điệp tùy chỉnh.
* @param thongDiep Thông điệp lỗi
* @return Đối tượng ApiResponse lỗi
*/
public static ApiResponse loi(String thongDiep) {
return loi(MaTrangThaiHTTP.LOI_SERVER, thongDiep, null);
}
/**
* Trả về phản hồi lỗi với thông điệp và dữ liệu tùy chỉnh.
* @param thongDiep Thông điệp lỗi
* @param duLieu Dữ liệu trả về
* @return Đối tượng ApiResponse lỗi
*/
public static ApiResponse loi(String thongDiep, Object duLieu) {
return loi(MaTrangThaiHTTP.LOI_SERVER, thongDiep, duLieu);
}
/**
* Trả về phản hồi lỗi với mã và thông điệp tùy chỉnh.
* @param maLoi Mã lỗi
* @param thongDiep Thông điệp lỗi
* @return Đối tượng ApiResponse lỗi
*/
public static ApiResponse loi(int maLoi, String thongDiep) {
return loi(maLoi, thongDiep, null);
}
/**
* Trả về phản hồi lỗi với mã, thông điệp và dữ liệu tùy chỉnh.
* @param maLoi Mã lỗi
* @param thongDiep Thông điệp lỗi
* @param duLieu Dữ liệu trả về
* @return Đối tượng ApiResponse lỗi
*/
public static ApiResponse loi(int maLoi, String thongDiep, Object duLieu) {
return new ApiResponse(false, maLoi, thongDiep, duLieu);
}
// Getters cho các trường
public boolean isSuccess() {
return success;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
public Object getData() {
return data;
}
public Map<String, Object> getAdditionalInfo() {
return additionalInfo;
}
// Setter cho additionalInfo (nếu cần mở rộng)
public void setAdditionalInfo(Map<String, Object> additionalInfo) {
this.additionalInfo = additionalInfo;
}
/**
* Phương thức tiện ích để thêm thông tin bổ sung vào phản hồi.
* Có thể sử dụng theo kiểu chuỗi (chaining).
* @param key Khóa của thông tin bổ sung
* @param value Giá trị của thông tin bổ sung
* @return Đối tượng ApiResponse hiện tại
*/
public ApiResponse themThongTinBoSung(String key, Object value) {
if (this.additionalInfo == null) {
this.additionalInfo = new HashMap<>();
}
this.additionalInfo.put(key, value);
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ApiResponse that = (ApiResponse) o;
return success == that.success && code == that.code && Objects.equals(message, that.message) && Objects.equals(data, that.data) && Objects.equals(additionalInfo, that.additionalInfo);
}
@Override
public int hashCode() {
return Objects.hash(success, code, message, data, additionalInfo);
}
@Override
public String toString() {
return "ApiResponse{" +
"success=" + success +
", code=" + code +
", message='" + message + '\'' +
", data=" + data +
", additionalInfo=" + additionalInfo +
'}';
}
}