mybatis plus使用常见问题

廖晟微 1年前 ⋅ 736 阅读

如何排除非表中字段?

三种方式选择一种即可!

  • 使用 transient 修饰

    private transient String noColumn;
  • 使用 static 修饰

    private static String noColumn;
  • 使用 TableField 注解

    1.  
      @TableField(exist=false)
    2.  
      private String noColumn;

异常Invalid bound statement (not found) 解决方法(MP方法无法调用)

不要怀疑,正视自己,这个异常肯定是你插入的姿势不对……

  • 检查是不是引入 jar 冲突

  • 检查命名空间是否正常? 检查包扫描路径是否正常?如果扫描不到,MP无法进行预注入

  • 检查是否指定了主键?如未指定,则会导致 selectById 相关 ID 无法操作,请用注解 @TableId 注解表 ID 主键

  • 当然 @TableId 注解可以没有!但是你的主键必须叫 id  忽略大小写

  • 注意!maven 多模块 jar 依赖 xml 扫描需为 classpath*: 加载多个 jar 下的 xml

  • 对于IDEA系列编辑器,XML 文件是不能放在 java 文件夹中的,IDEA 默认不会编译源码文件夹中的 XML 文件,可以参照以下方式解决:

    • 将配置文件放在 resource 文件夹中,请参考 Spring-MVC 的集成 DEMO
    • 对于 Maven 项目,可指定 POM 文件的 resource
    1.  
      <build>
    2.  
      <resources>
    3.  
      <resource>
    4.  
      <directory>src/main/java</directory>
    5.  
      <includes>
    6.  
      <include>**/*.xml</include>
    7.  
      </includes>
    8.  
      </resource>
    9.  
      <!--指定资源的位置-->
    10.  
      <resource>
    11.  
      <directory>src/main/resources</directory>
    12.  
      </resource>
    13.  
      </resources>
    14.  
      </build>

自定义sql无法执行

指在xml里面自定义sql,需要配置xml扫描路径

  1.  
    <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
  2.  
    <property name="dataSource" ref="dataSource" />
  3.  
    <property name="typeAliasesPackage" value="xxx.entity" />
  4.  
    <property name="mapperLocations" value="classpath:com/xx/mapper/xml/*Mapper.xml" />
  5.  
    ...
  6.  
    </bean>
  1.  
    mybatis-plus:
  2.  
    mapper-locations: classpath:/mapper/**/*.xml

启动时异常

java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class

  • 配置MapperScan需要排除 com.baomidou.mybatisplus.mapper.BaseMapper
  • MapperScan排除自定义公共Mapper, 比如
  1.  
    public interface SuperMapper<T> extends com.baomidou.mybatisplus.mapper.BaseMapper<T> {
  2.  
    ...your methds
  3.  
    }

异常Injection of autowired 解决方法

  • 原因!低版本不支持泛型注入,请升级 spring 4+

异常java.lang.NoSuchMethodError: org.apache.ibatis.session.Configuration.getDefaultScriptingLanguageInstance() Lorg/apache/ibatis/scripting/LanguageDriver 解决方法

  • 版本引入问题:3.4.1版本里没有,3.4.2里面才有!

关于Long型主键填充不生效的问题

检查是不是用了long而不是Long!【特别说明】long类型默认值为0,而mp只会判断是否为null

ID_WORKER 主键 Long 导致 js 精度丢失

JavaScript 无法处理 Java 的长整型 Long 导致精度丢失,解决办法 Long 转为 String 返回

  • FastJson 处理方式:
  1.  
    /**
  2.  
    * <p>
  3.  
    * 消息转换
  4.  
    * </p>
  5.  
    */
  6.  
    @Override
  7.  
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
  8.  
    FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
  9.  
    FastJsonConfig fjc = new FastJsonConfig();
  10.  
    //1、序列化重点
  11.  
    fjc.setSerializerFeatures(SerializerFeature.BrowserCompatible);
  12.  
    fastJsonConverter.setFastJsonConfig(fjc);
  13.  
    converters.add(fastJsonConverter);
  14.  
    }
  • JackJson 处理方式:
  1.  
    // 1、注解处理,这里可以配置公共 baseEntity 处理
  2.  
    @JsonSerialize(using=ToStringSerializer.class)
  3.  
    public long getId() {
  4.  
    return id;
  5.  
    }
  6.  
     
  7.  
    // 2、全局配置序列化返回 JSON 处理
  8.  
    final ObjectMapper objectMapper = new ObjectMapper();
  9.  
    SimpleModule simpleModule = new SimpleModule();
  10.  
    simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
  11.  
    objectMapper.registerModule(simpleModule);
  • 还有一个方法,增加一个public String getIdStr()方法,前台获取idStr

字段 update 空字符串 OR NULL 修改验证策略

FieldStrategy 三种策略 IGNORED【忽略】,NOT_NULL【非 NULL,默认策略】,NOT_EMPTY【非空】

  • 全局的验证策略,注入配置 GlobalConfiguration 属性 fieldStrategy

  • 根据具体情况,选择验证注解,如验证非空:

    @TableField(strategy=FieldStrategy.NOT_EMPTY)
  • 解决办法 二

    1.  
      updateAllColumnById(entity) // 全部字段更新
    2.  
       
    3.  
      insertAllColumn(entity) // 全部字段插入

字段 bit 、tinyint(1) 使用 boolean 类型映射解决方法

默认 mybatis 是不会自动处理该映射,需要修改请求连接添加参数 tinyInt1isBit=false【默认 true】如下:

jdbc:mysql://127.0.0.1:3306/mp?tinyInt1isBit=false

出现2个limit语句

原因:配了2个分页拦截器! 检查配置文件或者代码,只留一个!

insert后如何返回主键

insert后主键会自动set到实体的ID字段,只需要entity.getId()

MP如何只查指定几个字段,而不是全字段?

EntityWrapper.sqlSelect配置你想要查询的字段

  1.  
    EntityWrapper<H2User> ew = new EntityWrapper<>();
  2.  
    ew.setSqlSelect("test_id as id, name, age");//只查询3个字段
  3.  
    List<H2User> list = userService.selectList(ew);
  4.  
    for(H2User u:list){
  5.  
    Assert.assertNotNull(u.getId());
  6.  
    Assert.assertNotNull(u.getName());
  7.  
    Assert.assertNull(u.getPrice());//这个字段没有查询出来
  8.  
    }

mapper 层二级缓存问题

我们建议缓存放到 service 层,你可以自定义自己的 BaseServiceImpl 重写注解父类方法,继承自己的实现。

  • 当然你是一个极端分子,请使用 CachePaginationInterceptor 替换默认分页,这样支持分页缓存。

mapper层二级缓存刷新问题

如果你按照mybatis的方式配置第三方二级缓存,并且使用2.0.9以上的版本,则会发现自带的方法无法更新缓存内容,那么请按如下方式解决  1.在代码中mybatis的mapper层添加缓存注释,声明implementation或eviction的值为cache接口的实现类  @CacheNamespace(implementation=MybatisRedisCache.class,eviction=MybatisRedisCache.class) public interface DataResourceMapper extends BaseMapper{}

 2.在对应的mapper.xml中将原有注释修改为链接式声明,以保证xml文件里的缓存能够正常

Cause: org.apache.ibatis.type.TypeException:

Error setting null for parameter #1 with JdbcType OTHER

配置jdbcTypeForNull=NULL Spring Bean配置方式:

  1.  
    MybatisConfiguration configuration = new MybatisConfiguration();
  2.  
    configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
  3.  
    configuration.setJdbcTypeForNull(JdbcType.NULL);
  4.  
    configuration.setMapUnderscoreToCamelCase(true);//开启下划线转驼峰
  5.  
    sqlSessionFactory.setConfiguration(configuration);

自定义sql里使用Page对象传参无法获取

Page对象是继承RowBounds,是Mybatis内置对象,无法在mapper里获取 请使用自定义Map/对象,或者通过@Param("page") int page,size来传参

开启查询结果【下划线转驼峰】

该功能是mybatis原生自带,配置如下

Spring Bean 配置:

  1.  
    MybatisConfiguration configuration = new MybatisConfiguration();
  2.  
    configuration.setMapUnderscoreToCamelCase(true);//开启下划线转驼峰
  3.  
    ...其他配置,见上面的【配置jdbcTypeForNull=NULL】

Spring Boot yml配置:

  1.  
    mybatis-plus:
  2.  
    configuration:
  3.  
    map-underscore-to-camel-case: true

如何使用:Map下划线自动转驼峰

指的是:resultType="java.util.Map"

!> 注意:结果集用Map返回时,不同数据库的处理大小写不一样

  • 比如mysql原样返回 select test_type from xxx -> test_type:1
  • Oracle只返回全大写 select test_type from xxx -> TEST_TYPE:1
  • 上述2种情况,只要是下划线命名的,使用Map下划线自动转驼峰 结果集都是 testType
  • 但是针对Oracle数据库:请注意MP自带方法selectMaps: 语句是 select test_type as testType from xxx -> 得到的结果:
  1. 没配Map下划线自动转驼峰TESTTYPE:value
  2. 配了:testtype:value(Mysql数据库会保留驼峰不受影响)
  • Java Config Bean方式
  1.  
    @Configuration
  2.  
    @MapperScan("com.baomidou.mybatisplus.test.h2.entity.mapper")
  3.  
    public class MybatisConfigMetaObjOptLockConfig {
  4.  
     
  5.  
    @Bean("mybatisSqlSession")
  6.  
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource, ResourceLoader resourceLoader, GlobalConfiguration globalConfiguration) throws Exception {
  7.  
    MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
  8.  
    MybatisConfiguration configuration = new MybatisConfiguration();
  9.  
    configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
  10.  
    configuration.setJdbcTypeForNull(JdbcType.NULL);
  11.  
    //*注册Map 下划线转驼峰*
  12.  
    configuration.setObjectWrapperFactory(new MybatisMapWrapperFactory());
  13.  
     
  14.  
    sqlSessionFactory.setConfiguration(configuration);
  15.  
    //...其他配置
  16.  
    return sqlSessionFactory.getObject();
  17.  
    }
  18.  
    ...
  19.  
    }

在 wrapper 中如何使用 limit 限制 SQL

  1.  
    // 取 1 条数据
  2.  
    wrapper.last("limit 1")

注意:本文归作者所有,未经作者允许,不得转载

全部评论: 0

    我有话说: