数据库表字段变动 ! 如何快速完成项目上线 ?

889 阅读4分钟

问题描述: 基于 MyBatis-Plus 开发的 Spring Boot 项目中,如何在改动项目代码最少的前提下,更新数据库表中的字段,完成项目的更新上线。

为了在变动较少代码的前提下完成数据库字段名的更新(如将 id 改为 业务_id),同时使用 MyBatis-Plus 的 ORM 功能,可以按照以下步骤操作。核心思路是通过注解和配置映射新旧字段,避免大规模修改业务代码


解决方案步骤:

1. 步骤1:修改数据库表结构

使用 SQL 脚本直接修改表字段名:

ALTER TABLE your_table RENAME COLUMN id TO 业务_id;

注意:需确保所有相关表都执行修改(如关联表的外键字段)。


2. 步骤2:修改实体类字段映射

在实体类中使用 @TableId@TableField 注解绑定新字段名:

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;

public class YourEntity {
    // 映射主键字段
    @TableId(value = "业务_id") // 指定数据库字段名
    private Long id; // 保持属性名不变,减少代码改动

    // 示例:其他字段修改
    @TableField("新字段名")
    private String oldFieldName;
}

关键点

  • 实体类属性名(如 id)保持不变,仅通过注解映射到新字段名 业务_id
  • MyBatis-Plus 的 CRUD 操作将自动使用新字段名。

3. 步骤3:处理自定义 SQL 或 XML 文件(推荐优先使用)

仅通过设置别名的方式修改SQL语句,不修改<resultMap></resultMap>中的内容,经过试验没问题。

试验方式将user表中的id修改为user_id,email修改为emailorQQ。

如果项目中有手写 SQL(如 Mapper XML 文件),需全局替换字段名:

<!-- 修改前 -->
<select id="selectById" resultType="YourEntity">
    SELECT id, name FROM your_table WHERE id = #{id}
</select>
<!-- 修改后 -->
<select id="selectById" resultType="YourEntity">
    SELECT 业务_id AS id, name FROM your_table WHERE 业务_id = #{id}
</select>

技巧

  • 使用 AS 保持结果集映射到实体类的属性名(如 业务_id AS id)。
  • 用 IDE 的全局替换功能批量修改 XML 中的字段名。
<?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.example.todo.dao.IUserDao">

    <resultMap id="dataMap" type="com.example.todo.entity.User">
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="password" property="password"/>
        <result column="nick_name" property="nickName"/>
        <result column="email" property="email"/>
        <result column="phone_number" property="phoneNumber"/>
        <result column="avatar" property="avatar"/>
        <result column="signature" property="signature"/>
        <result column="deleted" property="deleted"/>
        <result column="create_time" property="createTime"/>
        <result column="update_time" property="updateTime"/>
    </resultMap>

    <select id="getUserByIdAndUserName" resultMap="dataMap">
        select user_id as id, username, password, nick_name, emailorQQ as email
        from user
        where user_id=#{id} and username=#{userName}
        limit 10
    </select>
    
</mapper>

注意事项: <select></select>中的SQL语句是直接发送给MySQL的,随后将MySQL查询出的结果再进行<resultMap></resultMap>到实体类的映射。


4. 修改xml注意事项(选择步骤3可跳过步骤4)

同时修改resultMap与SQL语句,经过试验没问题。

进修改SQL语句中的字段,运行查询会没问题,但是查询出的已修改字段为null。

需要同时修改xml文件中的<resultMap></resultMap>内容与SQL语句中的内容。

<?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.example.todo.dao.IUserDao">
  
    <resultMap id="dataMap" type="com.example.todo.entity.User">
        <id column="user_id" property="id"/>
        <result column="username" property="username"/>
        <result column="password" property="password"/>
        <result column="nick_name" property="nickName"/>
        <result column="emailorQQ" property="email"/>
        <result column="phone_number" property="phoneNumber"/>
        <result column="avatar" property="avatar"/>
        <result column="signature" property="signature"/>
        <result column="deleted" property="deleted"/>
        <result column="create_time" property="createTime"/>
        <result column="update_time" property="updateTime"/>
    </resultMap>

    <select id="getUserByIdAndUserName" resultMap="dataMap">
        select user_id, username, password, nick_name, emailorQQ
        from user
        where user_id=#{id} and username=#{userName}
        limit 10
    </select>
</mapper>

5. 步骤4:检查全局配置下划线转换(可选)

若多数字段遵循 驼峰转下划线 规则,在 application.yml 中配置:

mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true # 开启自动转换
  global-config:
    db-config:
      column-format: "%s" # 防止MP自动添加反引号(可选)

此配置可使 业务_id 自动映射到实体类属性 业务Id(需同步改属性名)。

慎用:如果仅部分字段改名,建议优先用注解。


6. 步骤5:统一处理条件构造器(核心)

MyBatis-Plus 的 QueryWrapperLambdaQueryWrapper 依赖实体类注解,无需修改:

// 修改前
queryWrapper.eq("id", 1); 

// 修改后:直接使用Lambda表达式,避免硬编码字段名!
queryWrapper.eq(YourEntity::getId, 1); 

重要

  • 禁止硬编码字段名(如 eq("id", 1)),改用 Lambda 表达式(YourEntity::getId)。
  • Lambda 构造器会自动读取注解映射的字段名(业务_id)。

7. 修复外键关联和业务代码

  • 关联查询:在 @TableField 注解中指定外键字段:
@TableField(value = "关联业务_id")
private Long refId;
  • 业务代码:如果存在直接使用字段名的场景(如反射、Map 操作),需局部调整。

8. 测试与回归验证

  • 单元测试:重点测试增删改查和复杂查询。
  • 集成测试:验证关联操作和事务。
  • 日志检查:开启 MyBatis SQL 日志,确认生成的 SQL 使用新字段名:
logging:
  level:
    com.your.mapper: debug

总结优化点:

措施目的
保持实体类属性名不变减少业务代码、Service、Controller 层的改动
注解驱动映射通过 @TableId/@TableField 绑定新字段名,解耦数据库与代码
Lambda 条件构造器避免硬编码字段名,依赖注解自动映射
全局替换 XML 字段名快速修复自定义 SQL
渐进式修改按模块逐步验证,降低风险

通过以上步骤,90% 的改动集中在 实体类注解XML/SQL 文件,业务逻辑层几乎无需修改,最小化变更影响。


本文内容存在AI生成,但文中提到的方法已通过试验验证。如文中存在错误描述,还请各位大佬批评指正!