【非广告】你还在手写crud吗,看完这篇文章,绝对赚了(一)

简介: 我记得最早刚步入互联网行业的时候,当时按照 MVC 的思想和模型,每次开发新功能,会依次编写 dao、service、controller相关服务类,包括对应的 dto、entity、vo 等等实体类,如果有多张单表,也会重复的编写相似的代码,现在回想起来,感觉当时自己好像处于石器时代!

一、介绍

我记得最早刚步入互联网行业的时候,当时按照 MVC 的思想和模型,每次开发新功能,会依次编写 dao、service、controller相关服务类,包括对应的 dto、entity、vo 等等实体类,如果有多张单表,也会重复的编写相似的代码,现在回想起来,感觉当时自己好像处于石器时代

实际上,当仔细的总结一下,对于任何一张单表的操作,基本都是围绕增(Create )、删(Delete )、改(Update )、查(Retrieve )四个方向进行数据操作,简称 CRUD!

他们除了表名和存储空间不一样,基本的 CRUD 思路基本都是一样的。

为了解决这些重复劳动的痛点,业界逐渐开源了一批代码生成器,目的也很简单,就是为了减少手工操作的繁琐,集中精力在业务开发上,提升开发效率

而今天,我们所要介绍的也是代码生成器,很多初学者可能觉得代码生成器很高深。代码生成器其实是一个很简单的东西,一点都不高深。

当你看完本文的时候,你会完全掌握代码生成器的逻辑,甚至可以根据自己的项目情况,进行深度定制

二、实现思路

下面我们就以SpringBoot项目为例,数据持久化操作采用Mybatis,数据库采用Mysql,编写一个自动生成增、删、改、查等基础功能的代码生成器,内容包括controllerservicedaoentitydtovo等信息。

实现思路如下:

  • 第一步:获取表字段名称、类型、表注释等信息
  • 第二步:基于 freemarker 模板引擎,编写相应的模板
  • 第三步:根据对应的模板,生成相应的 java 代码

2.1、获取表结构

首先我们创建一张test_db表,脚本如下:

CREATE TABLE test_db (
  id bigint(20) unsigned NOT NULL COMMENT '主键ID',
  name varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '名称',
  is_delete tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否删除 1:已删除;0:未删除',
  create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (id),
  KEY idx_create_time (create_time) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='测试表';

表创建完成之后,基于test_db表,我们查询对应的表结果字段名称、类型、备注信息,这些关键信息将用于后续进行代码生成器所使用

# 获取对应表结构
SELECT column_name, data_type, column_comment FROM information_sch


13.jpg

同时,获取对应表注释,用于生成备注信息

# 获取对应表注释
SELECT TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_schema =

14.jpg


2.2、编写模板

  • 编写mapper.ftl模板,涵盖新增、修改、删除、查询等信息
<?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="${daoPackageName}.${daoName}">
 <!--BaseResultMap-->
 <resultMap id="BaseResultMap" type="${entityPackageName}.${entityName}">
        <#list columns as pro>
            <#if pro.proName == primaryId>
    <id column="${primaryId}" property="${primaryId}" jdbcType="${pro.fieldType}"/>
            <#else>
    <result column="${pro.fieldName}" property="${pro.proName}" jdbcType="${pro.fieldType}"/>
            </#if>
        </#list>
 </resultMap>
 <!--Base_Column_List-->
 <sql id="Base_Column_List">
        <#list columns as pro>
            <#if pro_index == 0>${pro.fieldName}<#else>,${pro.fieldName}</#if>
        </#list>
 </sql>
 <!--批量插入-->
 <insert id="insertList" parameterType="java.util.List">
  insert into ${tableName} (
        <#list columns as pro>
            <#if pro_index == 0>${pro.fieldName},<#elseif pro_index == 1>${pro.fieldName}<#else>,${pro.fieldName}</#if>
        </#list>
  )
  values
  <foreach collection ="list" item="obj" separator =",">
   <trim prefix=" (" suffix=")" suffixOverrides=",">
                <#list columns as pro>
                    ${r"#{obj." + pro.proName + r"}"},
                </#list>
   </trim>
  </foreach >
 </insert>
 <!--按需新增-->
 <insert id="insertPrimaryKeySelective" parameterType="${entityPackageName}.${entityName}">
  insert into ${tableName}
  <trim prefix="(" suffix=")" suffixOverrides=",">
            <#list columns as pro>
    <if test="${pro.proName} != null">
                    ${pro.fieldName},
    </if>
            </#list>
  </trim>
  <trim prefix="values (" suffix=")" suffixOverrides=",">
            <#list columns as pro>
    <if test="${pro.proName} != null">
                    ${r"#{" + pro.proName + r",jdbcType=" + pro.fieldType +r"}"},
    </if>
            </#list>
  </trim>
 </insert>
 <!-- 按需修改-->
 <update id="updatePrimaryKeySelective" parameterType="${entityPackageName}.${entityName}">
  update ${tableName}
  <set>
            <#list columns as pro>
                <#if pro.fieldName != primaryId && pro.fieldName != primaryId>
     <if test="${pro.proName} != null">
                        ${pro.fieldName} = ${r"#{" + pro.proName + r",jdbcType=" + pro.fieldType +r"}"},
     </if>
                </#if>
            </#list>
  </set>
  where ${primaryId} = ${r"#{" + "${primaryId}" + r",jdbcType=BIGINT}"}
 </update>
 <!-- 按需批量修改-->
 <update id="updateBatchByIds" parameterType="java.util.List">
  update ${tableName}
  <trim prefix="set" suffixOverrides=",">
            <#list columns as pro>
                <#if pro.fieldName != primaryId && pro.fieldName != primaryId>
     <trim prefix="${pro.fieldName}=case" suffix="end,">
      <foreach collection="list" item="obj" index="index">
       <if test="obj.${pro.proName} != null">
        when id = ${r"#{" + "obj.id" + r"}"}
        then  ${r"#{obj." + pro.proName + r",jdbcType=" + pro.fieldType +r"}"}
       </if>
      </foreach>
     </trim>
                </#if>
            </#list>
  </trim>
  where
  <foreach collection="list" separator="or" item="obj" index="index" >
   id = ${r"#{" + "obj.id" + r"}"}
  </foreach>
 </update>
 <!-- 删除-->
 <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
  delete from ${tableName}
  where ${primaryId} = ${r"#{" + "${primaryId}" + r",jdbcType=BIGINT}"}
 </delete>
 <!-- 查询详情 -->
 <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long">
  select
  <include refid="Base_Column_List"/>
  from ${tableName}
  where ${primaryId} = ${r"#{" + "${primaryId}" + r",jdbcType=BIGINT}"}
 </select>
 <!-- 按需查询 -->
 <select id="selectByPrimaryKeySelective" resultMap="BaseResultMap" parameterType="${entityPackageName}.${entityName}">
  select
  <include refid="Base_Column_List"/>
  from ${tableName}
 </select>
 <!-- 批量查询-->
 <select id="selectByIds" resultMap="BaseResultMap" parameterType="java.util.List">
  select
  <include refid="Base_Column_List"/>
  from ${tableName}
  <where>
   <if test="ids != null">
    and ${primaryId} in
    <foreach item="item" index="index" collection="ids" open="(" separator="," close=")">
                    ${r"#{" + "item" + r"}"}
    </foreach>
   </if>
  </where>
 </select>
 <!-- 根据条件查询 -->
 <select id="selectByMap" resultMap="BaseResultMap" parameterType="java.util.Map">
  select
  <include refid="Base_Column_List"/>
  from ${tableName}
 </select>
 <!-- 查询${entityName}总和 -->
 <select id="countPage" resultType="int" parameterType="${dtoPackageName}.${dtoName}">
  select count(${primaryId})
  from ${tableName}
 </select>
 <!-- 查询${entityName}列表 -->
 <select id="selectPage" resultMap="BaseResultMap" parameterType="${dtoPackageName}.${dtoName}">
  select
  <include refid="Base_Column_List"/>
  from ${tableName}
  limit ${r"#{" + "start,jdbcType=INTEGER" + r"}"},${r"#{" + "end,jdbcType=INTEGER" + r"}"}
 </select>
</mapper>
相关文章
|
7月前
|
JavaScript 前端开发 Java
LayUI之CRUD(增删改查功能实现)项目案例
LayUI之CRUD(增删改查功能实现)项目案例
48 0
|
7月前
|
存储 JSON 前端开发
LayUI之CRUD(增删改查)
LayUI之CRUD(增删改查)
89 0
|
7月前
|
存储 前端开发 JavaScript
Layui的CRUD(增删改查)
Layui的CRUD(增删改查)
81 0
|
8月前
|
前端开发 JavaScript API
Layui的CRUD(增删改查)
Layui的CRUD(增删改查)
69 0
|
8月前
|
前端开发 数据管理 数据库
Layui之CRUD(增删改查)
Layui之CRUD(增删改查)
26 0
|
12天前
|
存储 SQL 关系型数据库
【软件设计师】一篇文章带你了解数据库
【软件设计师】一篇文章带你了解数据库
|
2天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的《数据库系统原理》课程平台附带文章和源代码设计说明文档ppt
基于ssm+vue.js+uniapp小程序的《数据库系统原理》课程平台附带文章和源代码设计说明文档ppt
8 1
|
19天前
|
druid 网络协议 Java
再有人问你数据库连接池的原理,这篇文章甩给他!
在 Spring Boot 项目中,数据库连接池已经成为标配,然而,我曾经遇到过不少连接池异常导致业务错误的事故。很多经验丰富的工程师也可能不小心在这方面出现问题。 在这篇文章中,我们将探讨数据库连接池,深入解析其实现机制,以便更好地理解和规避潜在的风险。
|
19天前
|
存储 NoSQL 关系型数据库
一篇文章带你搞懂非关系型数据库MongoDB
一篇文章带你搞懂非关系型数据库MongoDB
87 0
|
19天前
|
存储 SQL 关系型数据库
【MySQL 数据库】6、一篇文章学习【索引知识】,提高大数据量的查询效率【文末送书】
【MySQL 数据库】6、一篇文章学习【索引知识】,提高大数据量的查询效率【文末送书】
63 0