【MyBatis】处理数据库字段名和Java实体类的属性名不一致的5种方法

在 MyBatis 中,数据库表中的字段名和实体类的属性名可能不一致,下面是常见的几种方法来处理这种不一致的命名规则。

方法 1:SQL 别名 AS

在 SELECT 语句中设置列别名(这是一个基本的 SQL 特性)可以强行使之匹配。

<select id="selectUsers" resultType="User">
  select
    user_id             as "id",
    user_name           as "userName",
    hashed_password     as "hashedPassword"
  from some_table
  where id = #{id}
</select>
  • MyBatis 默认情况下会尝试 通过字段名和属性名 来进行映射。如果字段名和属性名不一致,可以使用 SQL 中的 AS 来指定列别名,以确保正确映射。
  • 在这个查询中,列别名的作用是强制数据库的列与 Java 对象的属性之间建立明确的映射关系,确保它们能够正确对应。

优点:

  1. 简单易用:通过在 SQL 中使用 AS 给字段起别名,无需在 Java 实体类或 MyBatis 配置文件中做复杂的映射设置。
  2. 代码整洁:避免了过多的 MyBatis 配置(如使用 @Result 注解或 resultMap)。
  3. 灵活性:对于复杂的 SQL 查询,直接在 SQL 中定义列别名避免了后期的手动映射。

缺点:

  1. 仅限于 SQL 查询语句:这种方法适用于查询语句中的字段映射,如果字段和属性名不一致,其他操作(如插入、更新)仍然需要手动设置映射关系。
  2. 无法应对复杂的映射关系:对于更复杂的映射(如嵌套对象、一对多关联等),仅使用 SQL 列别名可能不够,仍然需要 resultMap@Results 注解。

结论

  • 对于 简单的字段名映射,使用 SQL 中的列别名AS是一个简单而高效的方式。
  • 对于 复杂的映射关系(比如多表联查、嵌套对象),建议使用 resultMap@Results 来明确映射关系。

方法 2:使用 @Results 注解

@Results 注解可在接口方法中直接指定映射关系。

接口方法

import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Result;

import java.util.List;

public interface UserMapper {

    @Select("SELECT id, user_name , email FROM t_user")
    @Results({
        @Result(property = "userName", column = "user_name"),
        @Result(property = "...", column = "..."),
    })
    List<User> selectUsers();
}

解释:

  • @Select:定义了查询语句,查询了 t_user 表中的 iduser_nameemail 字段。
  • @Results:用于指定映射规则,将数据库字段 user_name 映射到实体类的 userName 属性

实体类

public class User {
    private Integer id;
    private String userName;  // 属性名和数据库字段名不一致
    private String email;

    // Getter and Setter methods
}

通过这种方式,即使数据库中的字段名是 user_name ,实体类中是 userName@Result 注解也可以完成映射。

方法 3:使用 resultMap 配置

resultMap 允许更灵活地进行映射。通常在 Mapper XML 中配置。

接口方法

public interface UserMapper {

    List<User> selectUsers();
}

Mapper XML 配置

<mapper namespace="org.example.mapper.UserMapper">

    <resultMap id="userResultMap" type="User">
        <result property="userName" column="user_name"/>
    </resultMap>

    <select id="selectUsers" resultMap="userResultMap">
        SELECT id, user_name, email FROM t_user
    </select>

</mapper>

解释:

  • resultMap:通过 id="userResultMap" 来定义一个resultMap,指定数据库字段 user_name 映射到实体类的 userName 属性
  • select:在select标签中,设置 resultMap="userResultMap" 来引用前面定义的resultMap

实体类

public class User {
    private Integer id;
    private String userName;  // 属性名和数据库字段名不一致
    private String email;

    // Getter and Setter methods
}

在这个配置中,MyBatis 会根据 resultMap 定义的映射规则,将查询结果正确地填充到 User 对象中。

方法 4:使用 MyBatis 的 mapUnderscoreToCamelCase

如果数据库使用下划线命名法,实体类使用驼峰命名法,尽管名字不同,但是可以设置mapUnderscoreToCamelCase=true使MyBatis进行自动映射。

比如,如果数据库字段是 user_name,而实体类属性是 userName,设置之后MyBatis 会自动将二者进行匹配。

mapUnderscoreToCamelCase介绍

mapUnderscoreToCamelCase介绍

在MyBatis中,mapUnderscoreToCamelCase 是一个用于控制数据库字段和Java属性之间映射规则的设置。当这个配置项设置为 true 时,MyBatis会自动将数据库中采用下划线命名法(如 A_COLUMN)的字段名转换为Java中的驼峰命名法(如 aColumn)。

默认情况下,mapUnderscoreToCamelCasefalse

mybatis-config XML 配置

<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

实体类

public class User {
    private Integer id;
    private String userName;  // 属性名遵循驼峰命名规则
    private String email;

    // Getter and Setter methods
}

Mapper XML 配置

<mapper namespace="org.example.mapper.UserMapper">

    <select id="selectUsers" resultType="User">
        SELECT id, user_name, email FROM t_user
    </select>

</mapper>

解释:

  • 设置mapUnderscoreToCamelCase=true之后,不用手动定义映射规则,MyBatis也可以将数据库字段user_name与实体类属性 userName 相匹配。

方法 5:使用自定义类型处理器(TypeHandler)

如果你的命名规则特别复杂,或者你想要更灵活的字段到属性的转换,你可以实现一个自定义的 TypeHandler 来处理转换逻辑。TypeHandler 主要用于转换字段类型,但你也可以在其中实现更复杂的转换逻辑。

定义 TypeHandler

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class UsernameTypeHandler extends BaseTypeHandler<String> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, parameter);
    }

    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String dbValue = rs.getString(columnName);
        // 可以在这里处理特殊的字段名到属性的转换
        return dbValue != null ? dbValue : "";
    }

    @Override
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String dbValue = rs.getString(columnIndex);
        return dbValue != null ? dbValue : "";
    }

    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String dbValue = cs.getString(columnIndex);
        return dbValue != null ? dbValue : "";
    }
}

Mapper XML 配置

<mapper namespace="org.example.mapper.UserMapper">

    <resultMap id="userResultMap" type="User">
        <result property="userName" column="username" typeHandler="org.example.typehandler.UsernameTypeHandler"/>
        <result property="email" column="email"/>
    </resultMap>

    <select id="selectUsers" resultMap="userResultMap">
        SELECT id, username, email FROM t_user
    </select>

</mapper>

总结

  1. AS 设置别名:在 SELECT 语句中设置列别名(这是一个基本的 SQL 特性)可以强行使之匹配,适用于简单情况。
  2. @Results 注解:在接口方法上使用 @Results 注解,可以灵活地指定字段到属性的映射关系,适用于简单情况。
  3. resultMap 配置:在 Mapper XML 文件中使用 resultMap 进行字段到属性的映射,适用于复杂的映射需求,尤其是字段名和属性名完全不一致的情况。
  4. autoMapping:MyBatis 默认会按照驼峰命名规则自动映射数据库字段和实体类属性,适用于数据库字段和属性遵循相同命名规则的情况。
  5. 自定义 TypeHandler:如果需要特殊的字段转换逻辑,可以实现自定义的 TypeHandler 来处理字段与属性之间的映射。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值