spring基础-convert

 * 在spring中有一个convert包用于转换,他和相似于JDK中的beans包。*

JDK中beans包实现

在JDK包中,提供了BeanInfo PropertyDescriptor PropertyEditor 实现对Bean属性的 转化。

BeanInfo

Bean信息访问的接口,能够访问BeanDescriptor PropertyDescriptor MethodDescriptor
 方式:BeanInfo student = Introspector.getBeanInfo(Class

    BeanInfo beanInfo = Introspector.getBeanInfo(Student.class);
    System.out.println(beanInfo.getBeanDescriptor());
    for (MethodDescriptor methodDescriptor :   beanInfo.getMethodDescriptors()) {
            System.out.println(methodDescriptor.toString());
        }
        for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors()) {
            System.out.println(propertyDescriptor.toString());
        }

PropertyDescriptor:属性描述器

用于描述Bean属性的描述器,包括属性名称 属性类型 属性编辑方法 
一个BeanInfo对象包含了多个PropertyDescriptor。

for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors()) {
            System.out.println(propertyDescriptor.getReadMethod());
            System.out.println(propertyDescriptor.getWriteMethod());
            System.out.println(propertyDescriptor.getPropertyType());
            System.out.println(propertyDescriptor.getName());
        }

PropertyEditor:属性编辑器

提供了对属性进行编辑的操作,主要方法是setAsText getAsText方法
 可以允许通过页面值设置Bean的属性。
 

java Beans 的缺点

仅支持String到java对象的转化,不能支持java对象到java对象之间的转化
不能使用宿主对象的上下文信息(比如注解)帮助转换
非线程安全的(需要我们每次都必须创建一个)


spring解决之道

上面简单介绍了了JDK中属性转换的实现方式以及他的缺点,下面我们来看一下,spring如何解决这些问题的

针对无法实现java对象到java对象的转化

定义了一个Converter<’S, T>对象,提供了对于任何对象之间的转化

针对无法利用宿主对象的上下文信息

重新定义了一个TypeDescriptor对象,是基于java对象的封装,拥有Class<’?> type,和 注解属性,保存了宿主对象的注解信息。

TypeDescriptor提供了支持Property MethodParameter Filed的构造方法

ConversionService类图

这里写图片描述

ConversionService时序图

Created with Raphaël 2.1.0GenericConversionServiceGenericConversionServiceConversionUtilsConversionUtilsGenericConverterGenericConverterconvert(Object,target,source)getConvert()invokeConverterconvert

总结

spring通过定义了TypeDescriptor重新定义了类型。这个类型包括了类型信息和注解信息,能够支持转换可以利用宿主对象的上下文对象。

spring 定义来GenericConvertor定义了通过source sourceType targetType参数对实例进行转换的接口,提供了对java对象到java对象之间转换的接口

spring内部提供大量的GenericConvertor的实现,满足基本的日常要求。

spring转换器知识使用了方法,而没有类似PropertyEditor的setValue(),利用了实例变量,避免了线程不安全的问题。

spring 学习

在convert中,看到了spring对接口的定义比较细致一些。
使用ConvertRegistory定义了可以注册Convertor的接口
GenericService定义了canConvert() convert()接口,大量重载这两个方法,只是为了实现操作的易用性而已,底层都是TypeDescriptor这个类型,这种设计便于维护,同时也是接口单一职责的体现。
ConfigurableConversionService继承了上述接口,起名为可配置的,表述上更加清晰。
GenericConversionService提供了ConfigurableConversionService基本实现,也是一个骨架类
DefaultConversionService 表示为系统的默认实现
整个spring中大量使用这种命名方式,很值得借鉴和学习的命名方式。

 
<think>好的,我现在需要帮助用户解决MyBatis Plus中BaseMapper的selectById方法遇到的参数类型不匹配和未映射目标属性的问题。首先,我得回忆一下MyBatis Plus的使用方式,以及常见的错误情况。 用户提到的问题有两个:参数类型不匹配和未映射的目标属性。可能的原因是什么呢?参数类型不匹配通常是因为实体类的主键类型与BaseMapper中指定的泛型类型不一致。例如,如果实体类的主键是Long类型,但BaseMapper的泛型参数设置成了Integer,就会导致selectById方法期望的参数类型与实际不符。这时候,用户调用selectById时传入Integer就会报错,或者反之亦然。 然后是未映射的目标属性问题。这通常是因为实体类的字段和数据库表的列没有正确映射,导致MyBatis Plus在查询结果映射到实体类对象时找不到对应的字段。可能的原因包括字段命名不一致(比如数据库使用下划线命名,而实体类使用驼峰命名),或者没有使用@TableField注解明确指定映射关系,或者配置问题导致MyBatis Plus没有正确扫描到实体类。 接下来,我需要一步步分析解决方法。首先,检查BaseMapper的泛型类型是否正确。用户示例中的最初写法是BaseMapper<T>,而正确写法应该是具体的实体类,比如BaseMapper<Pojo>。所以用户需要确认他们的Mapper接口是否正确定义了实体类,而不是泛型T。 然后,检查主键类型是否匹配。实体类中的主键字段应该使用@TableId注解,并且类型要与BaseMapper的泛型参数中的主键类型一致。例如,如果主键在数据库中是BIGINT,对应的Java类型应该是Long,所以BaseMapper的泛型应为BaseMapper<Entity, Long>,而用户可能错误地使用了Integer。 关于未映射的属性,需要检查实体类字段是否与数据库列名匹配。如果数据库列名是user_name,而实体类字段是userName,可能需要开启驼峰映射,或者在字段上添加@TableField("user_name")注解。此外,确认是否在配置中正确设置了映射策略,比如在MyBatis Plus的配置类中使用@Configuration和@MapperScan注解,或者在application.properties中配置mapUnderscoreToCamelCase为true。 另外,还需要检查实体类是否被MyBatis Plus正确识别,可能需要使用@TableName注解指定表名,特别是当表名与实体类名不一致的时候。同时,检查是否有字段被遗漏,或者存在多余的字段没有在实体类中定义,导致MyBatis Plus在映射时忽略这些字段。 可能用户还遇到了缓存或配置问题,比如没有正确清理缓存,导致旧的映射信息残留。这时候,清理项目并重新编译可能会有帮助。或者,检查日志输出,查看MyBatis Plus生成的SQL语句和参数,确认是否有明显的错误信息,比如Unknown column或者类型转换异常。 最后,用户可能需要参考官方文档或社区中的解决方案,比如在实体类中正确使用注解,配置正确的类型处理器,或者调整Mapper接口的泛型参数。同时,提供示例代码和配置可以帮助用户更直观地理解正确的做法。</think>### MyBatis Plus中BaseMapper的selectById方法问题解决方案 #### 1. **参数类型不匹配问题** **原因分析** `selectById`方法的参数类型由实体类主键字段类型决定。若Mapper接口泛型声明错误或实体类主键注解配置不当,会导致类型不匹配。例如: - 实体类主键为`Long`类型,但Mapper定义为`BaseMapper<Entity, Integer>` - 主键未使用`@TableId`注解明确标识类型[^1] **解决方案** - **步骤1:检查Mapper接口泛型声明** 确保Mapper接口继承`BaseMapper`时指定了**具体实体类**而非泛型`T`: ```java // 正确写法 public interface UserMapper extends BaseMapper<User> {} ``` - **步骤2:核对主键注解配置** 在实体类中明确标注主键字段并指定类型: ```java @TableId(type = IdType.AUTO) // 根据数据库主键策略调整 private Long id; // 类型需与数据库一致 ``` #### 2. **未映射目标属性问题** **原因分析** 该问题通常由以下原因导致: - 实体类字段名与数据库列名未正确映射(如驼峰命名与下划线命名未转换) - 未使用`@TableField`注解显式映射非常规字段 - MyBatis Plus全局配置未启用驼峰映射规则 **解决方案** - **步骤1:启用驼峰命名转换** 在`application.properties`中添加配置: ```properties mybatis-plus.configuration.map-underscore-to-camel-case=true ``` - **步骤2:显式字段映射** 对非常规命名字段使用注解: ```java @TableField("user_name") private String userName; ``` - **步骤3:检查实体类完整性** 确保所有查询结果中的数据库列均有对应的实体类字段,若存在冗余字段可添加`@TableField(exist = false)`: ```java @TableField(exist = false) private String ignoreField; ``` #### 3. **辅助验证方法** - **查看生成的SQL日志** 在`application.properties`中开启SQL日志验证映射正确性: ```properties mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl ``` - **清理缓存重新编译** Maven项目执行`mvn clean install`,Gradle项目执行`gradle clean build`。 --- ### 示例代码 **实体类定义** ```java @TableName("user") // 显式指定表名 public class User { @TableId(type = IdType.AUTO) private Long id; @TableField("user_name") private String userName; // getters/setters省略 } ``` **Mapper接口定义** ```java public interface UserMapper extends BaseMapper<User> {} ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值