mybatis 映射实体类不完整的一些解决问题

本文探讨了在使用MyBatis框架时遇到的驼峰命名问题,即数据库字段与实体类属性映射不全的情况。文章详细介绍了两种有效的解决办法:一是通过resultMap进行映射,二是修改SQL语句中的字段名,使其能直接映射到实体类的驼峰命名属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,基本环境

自己写个demo,习惯性的使用generator逆向生成代码。

这是我的mapper.xml文件。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mapping.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.byk.rong.system.mapper.read.UserReadMapper">
  <resultMap id="BaseResultMap" type="com.byk.rong.system.entity.User">
    <id column="id" jdbcType="VARCHAR" property="id" />
    <result column="user_name" jdbcType="VARCHAR" property="userName" />
    <result column="real_name" jdbcType="VARCHAR" property="realName" />
    <result column="password" jdbcType="VARCHAR" property="password" />
    <result column="salt" jdbcType="VARCHAR" property="salt" />
    <result column="dept_id" jdbcType="VARCHAR" property="deptId" />
    <result column="email" jdbcType="VARCHAR" property="email" />
    <result column="mobile" jdbcType="VARCHAR" property="mobile" />
    <result column="ID_card_number" jdbcType="VARCHAR" property="idCardNumber" />
    <result column="sex" jdbcType="VARCHAR" property="sex" />
    <result column="pictrue" jdbcType="VARCHAR" property="pictrue" />
    <result column="status" jdbcType="VARCHAR" property="status" />
    <result column="city_id" jdbcType="VARCHAR" property="cityId" />
    <result column="hobby" jdbcType="VARCHAR" property="hobby" />
    <result column="remarks" jdbcType="VARCHAR" property="remarks" />
    <result column="create_user" jdbcType="VARCHAR" property="createUser" />
    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    <result column="update_user" jdbcType="VARCHAR" property="updateUser" />
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
    <result column="delete_user" jdbcType="VARCHAR" property="deleteUser" />
    <result column="delete_time" jdbcType="TIMESTAMP" property="deleteTime" />
    <result column="del_flag" jdbcType="VARCHAR" property="delFlag" />
  </resultMap>
  <sql id="Base_Column_List">
      id,
      user_name,
      real_name,
      password,
      salt ,
      dept_id,
      email,
      mobile,
      ID_card_number,
      sex,
      pictrue,
      status,
      city_id ,
      hobby,
      remarks,
      create_user,
      create_time,
      update_user,
      update_time,
      delete_user,
      delete_time,
      del_flag
        
  </sql>
  <select id="selectById" parameterType="java.lang.String" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from user
    where id = #{id,jdbcType=VARCHAR}  AND  del_flag = '0'
  </select>

  <select id="selectByParams" resultType="com.byk.rong.system.entity.User">
    select
    <include refid="Base_Column_List" />
    from user 
    <where>
      <if test="id != null and id != ''">and id = #{id}</if>
      <if test="userName != null and userName != ''">and user_name = #{userName}</if>
      <if test="realName != null and realName != ''">and real_name = #{realName}</if>
      <if test="password != null and password != ''">and password = #{password}</if>
      <if test="salt != null and salt != ''">and salt = #{salt}</if>
      <if test="deptId != null and deptId != ''">and dept_id = #{deptId}</if>
      <if test="email != null and email != ''">and email = #{email}</if>
      <if test="mobile != null and mobile != ''">and mobile = #{mobile}</if>
      <if test="idCardNumber != null and idCardNumber != ''">and ID_card_number = #{idCardNumber}</if>
      <if test="sex != null and sex != ''">and sex = #{sex}</if>
      <if test="pictrue != null and pictrue != ''">and pictrue = #{pictrue}</if>
      <if test="status != null and status != ''">and status = #{status}</if>
      <if test="cityId != null and cityId != ''">and city_id = #{cityId}</if>
      <if test="hobby != null and hobby != ''">and hobby = #{hobby}</if>
      <if test="remarks != null and remarks != ''">and remarks = #{remarks}</if>
      <if test="createUser != null and createUser != ''">and create_user = #{createUser}</if>
      <if test="createTime != null and createTime != ''">and create_time = #{createTime}</if>
      <if test="updateUser != null and updateUser != ''">and update_user = #{updateUser}</if>
      <if test="updateTime != null and updateTime != ''">and update_time = #{updateTime}</if>
      <if test="deleteUser != null and deleteUser != ''">and delete_user = #{deleteUser}</if>
      <if test="deleteTime != null and deleteTime != ''">and delete_time = #{deleteTime}</if>
      and del_flag = '0'
    </where>
    order by create_time desc
    <if test="offset != null and limit != null">
      limit #{offset}, #{limit}
    </if>
  </select>


    <select id="findByUsername" parameterType="java.lang.String" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from user
        where user_name = #{userName,jdbcType=VARCHAR}  AND  del_flag = '0'
    </select>

</mapper>

然而,测试的时候发现实体类里面的属性映射不完整,一些字段明明有值,但是输出的实体类里面相对应的属性值为null,如下:

对比了一下,问题都出现在带有“_”的字段,也就是使用到驼峰命名的属性上。

查找资料,发现了问题所在。

二、解决办法

第一种解决办法

  <select id="selectByParams" resultType="com.byk.rong.system.entity.User">

这个方法是我自己写的,使用了resultType,直接映射到实体类,没有通过mabatis提供的 BaseResultMap,因此映射失败,将这里的resultType改成 resultMap="BaseResultMap"即可,使查询到的数据通过mabatis的内部实现完整的映射到实体类。

第二种解决办法

修改sql语句,即

 <sql id="Base_Column_List">
      id AS id,
      user_name AS userName,
      real_name AS realName,
      password as password,
      salt as salt,
      dept_id AS deptId,
      email as email,
      mobile as mobile,
      ID_card_number as   idCardNumber,
      sex as sex,
      pictrue as pictrue,
      status as status,
      city_id as cityId,
      hobby as hobby,
      remarks as remarks,
      create_user as createUser,
      create_time as createTime,
      update_user as updateUser,
      update_time as updateTime,
      delete_user as deleteUser,
      delete_time as deleteTime,
      del_flag AS delFlag
  </sql>

这样,查询到的字段数据直接映射成属性,也能解决这个问题。

效果如下:

注意:

这两种办法只能二选一,不能同时使用。

### MyBatis实体类映射详解 #### 手动映射方式 在MyBatis中,`<resultMap>`标签用于定义手动映射关系。当需要处理复杂的对象结构时,这种方法非常有用。例如,在用户和地址信息的情况下: ```xml <resultMap id="UserResultMap" type="com.example.User"> <id property="userId" column="user_id"/> <result property="username" column="user_name"/> <!-- 嵌套关联 --> <association property="address" javaType="com.example.Address"> <id property="addressId" column="addr_id"/> <result property="street" column="street"/> </association> </resultMap> <select id="getUserById" resultMap="UserResultMap"> SELECT * FROM users WHERE user_id = #{userId} </select> ``` 此方法允许精确控制每一列到Java属性的转换过程[^1]。 #### 自动映射机制 对于简单的场景,可以依赖于MyBatis内置的自动映射功能来简化开发工作量。如果启用了`mapUnderscoreToCamelCase=true`参数,则即使数据库字段采用下划线命名法(如`user_name`),也可以无缝匹配至Java Bean中的驼峰风格变量名(如`userName`)。这减少了显式指定每一对映射的需求。 此外,针对入参映射问题,MyBatis会尝试将传入的方法参数按照名称或位置顺序绑定到SQL语句占位符上。对于类型差异较大的情况,比如ID字段从整数变为字符串形式传递给Mapper接口函数调用时,框架内部会做必要的类型转换操作以适应实际需求[^2]。 #### 利用别名进行简单映射 除了上述两种主要手段外,还可以直接在查询语句内设置别名为各列赋予新的名字以便更好地对应目标POJO成员变量。这种方式适用于那些仅需少量调整即可完成映射的任务。 ```sql SELECT t.user_id AS userId, t.user_name AS userName ... FROM table_name t; ``` 这样做的好处在于无需额外配置任何XML节点就可以快速解决问题[^3]。 综上所述,MyBatis提供了多种灵活的方式来满足同层次的应用程序设计者们对于ORM层定制化的要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值