Mybatis——5.解决属性名和字段名不一致的问题

5.解决属性名和字段名不一致的问题

5.1 问题

数据库中的字段
在这里插入图片描述
新建一个项目,拷贝之前的,测试实体类字段不一致的情况

public class User {
    private int id;
    private String name;
    private String password;
}

测试出现问题
在这里插入图片描述

//  select * from mybatis.user where id = #{id}
//类型处理器
//  select id,name,pwd from mybatis.user where id = #{id}

解决方法:

  • 起别名:
    <select id="getUserById"  resultType="com.zmh.pojo.User">
        select id,name,pwd as password from mybatis.user where id = #{id}
    </select>

5.2 resultMap

结果集映射

id	    name     pwd
id     name     password
	<!--结果映射集-->
    <resultMap id="UserMap" type="User">
        <!--column:数据库中的字段,property:实体类中的属性-->
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="pwd" property="password"/>
    </resultMap>
    
    <select id="getUserById"  resultMap="UserMap">
        select * from mybatis.user where id = #{id}
    </select>
  • resultMap 元素是 MyBatis 中最重要最强大的元素
  • ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
  • ResultMap 的优秀之处——你完全可以不用显式地配置它们。
  • 如果这个世界总是这么简单就好了。
### 解决 MyBatis 使用 `selectKey` 返回主键 ID 时出现的异常问题 在使用 MyBatis 的 `<selectKey>` 功能返回主键 ID 时,如果遇到 `org.mybatis.spring.MyBatisSystemException` 异常,通常是因为以下几个原因导致的问题。以下是详细的分析解决方案: --- #### 可能的原因及解决办法 1. **字段名映射错误** 如果实体类中的字段名称与数据库表中的列名一致,可能导致无法正确设置属性值。这会引发反射异常 (`ReflectionException`),进而抛出 `MyBatisSystemException`。 确保实体类中的字段名与数据库表中的列名完全匹配,或者通过 `resultMap` 显式指定映射关系[^1]。 ```xml <resultMap id="UserResultMap" type="com.example.User"> <id property="userId" column="user_id"/> <result property="username" column="name"/> </resultMap> ``` 2. **`keyProperty` 设置错误** 在 `<selectKey>` 标签中,`keyProperty` 属性用于指定要填充到传入对象中的字段名称。如果该字段存在于传入的对象中,也会触发反射异常。 确认 `keyProperty` 对应的是实体类中存在的字段,并且拼写无误[^1]。 ```xml <insert id="insertUser" parameterType="com.example.User"> <selectKey keyProperty="userId" resultType="int" order="BEFORE"> SELECT NEXTVAL('seq_user_id') </selectKey> INSERT INTO users(user_id, username) VALUES (#{userId}, #{username}) </insert> ``` 3. **数据库序列或函数可用** 如果 `<selectKey>` 中使用的数据库序列或函数(如 `NEXTVAL`)可用或未正确定义,则会导致 SQL 执行失败。检查数据库端的相关资源是否存在并可访问。 确保数据库中有可用的序列或自增机制,并测试其功能是否正常[^3]。 4. **事务管理问题** 如果当前环境启用了 Spring MyBatis 的集成事务管理,但两者并未共享同一个事务上下文,可能会导致一致问题。确认事务管理器已正确配置,使得 Spring MyBatis 共享同一事务连接[^4]。 配置示例: ```java @Bean public DataSourceTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } ``` 5. **驱动程序兼容性** JDBC 驱动版本过旧或与数据库版本兼容也可能引起此类问题。升级至最新稳定版的 JDBC 驱动以排除潜在冲突。 6. **`order` 属性设置当** `<selectKey>` 的 `order` 属性决定了主键生成的时间点——是在插入之前还是之后。如果设置为 `AFTER`,但后续逻辑依赖于提前生成的主键值,则可能出现问题。建议优先使用 `BEFORE` 方式生成主键[^2]。 示例代码: ```xml <insert id="insertOrder" parameterType="com.example.Order"> <selectKey keyProperty="orderId" resultType="long" order="BEFORE"> SELECT UUID() AS orderId </selectKey> INSERT INTO orders(order_id, amount) VALUES (#{orderId}, #{amount}) </insert> ``` 7. **类型处理器 (`TypeHandler`) 适配** 若涉及复杂的数据类型转换,可能需要自定义 `TypeHandler` 来处理特定情况下的 JDBC 类型与 Java 类型间的映射。确保所选 `TypeHandler` 支持对应的操作场景[^2]。 自定义 `TypeHandler` 示例: ```java @MappedTypes(String.class) @MappedJdbcTypes(JdbcType.VARCHAR) public class CustomStringTypeHandler implements TypeHandler<String> { @Override public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter.toUpperCase()); } @Override public String getResult(ResultSet rs, String columnName) throws SQLException { return rs.getString(columnName).toLowerCase(); } @Override public String getResult(ResultSet rs, int columnIndex) throws SQLException { return rs.getString(columnIndex).toLowerCase(); } @Override public String getResult(CallableStatement cs, int columnIndex) throws SQLException { return cs.getString(columnIndex).toLowerCase(); } } ``` --- ### 总结 通过对以上常见问题逐一排查,可以有效定位并修复 `org.mybatis.spring.MyBatisSystemException` 异常的根本原因。重点在于确保字段映射准确、`keyProperty` 正确指向目标字段以及数据库资源配置得当等方面的工作。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值