本来是想用Springboot3整合MyBatisPlus 做一波数据处理层的简化 也就是不用再写sql语句 直接使用IService封装好的方法 做简单的curd
本来用的好好的 在一次业务迭代中 需要对复杂嵌套的json对象进行curd
灵机一动 反手写个类型处理器吧 JSONTypeHandler 然后再把类型处理器在Data的实体类当中映射出来
然后就有了
public class JSONTypeHandler extends BaseTypeHandler<JSONObject> { @Override public void setNonNullParameter(PreparedStatement ps, int i, JSONObject parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter.toString()); } @Override public JSONObject getNullableResult(ResultSet rs, String columnName) throws SQLException { return JSONUtil.parseObj(rs.getString(columnName)); } @Override public JSONObject getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return JSONUtil.parseObj(rs.getString(columnIndex)); } @Override public JSONObject getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return JSONUtil.parseObj(cs.getString(columnIndex)); } }
好了 为了让MyBatisPlus识别到 我写的类型处理器 要加上对应配置文件
<configuration> <!-- 其他配置项 --> <typeHandlers> <!-- 注册自定义的类型处理器 --> <typeHandler handler="TopOne.utils.Handler.JSONTypeHandler"/> </typeHandlers> </configuration>
问题就出现了 除了这个 映射了json类型的查询可以curd以外 其他所有原生态的封装好的方法全部都不能用了!!!
可能你还不明白具体是什么概念
我们看到 这个Mapper 明明是继承BaseMapper对吧?
我们再来看看BaseMapper里面有啥!进去看!
public interface BaseMapper<T> extends Mapper<T> { int insert(T entity); int deleteById(Serializable id); int deleteById(T entity); int deleteByMap(@Param("cm") Map<String, Object> columnMap); int delete(@Param("ew") Wrapper<T> queryWrapper); int deleteBatchIds(@Param("coll") Collection<?> idList); int updateById(@Param("et") T entity); int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper); T selectById(Serializable id); List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList); List<T> selectByMap(@Param("cm") Map<String, Object> columnMap); default T selectOne(@Param("ew") Wrapper<T> queryWrapper) { List<T> list = this.selectList(queryWrapper); if (list.size() == 1) { return list.get(0); } else if (list.size() > 1) { throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size()); } else { return null; } } default boolean exists(Wrapper<T> queryWrapper) { Long count = this.selectCount(queryWrapper); return null != count && count > 0L; } Long selectCount(@Param("ew") Wrapper<T> queryWrapper); List<T> selectList(@Param("ew") Wrapper<T> queryWrapper); List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper); List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper); <P extends IPage<T>> P selectPage(P page, @Param("ew") Wrapper<T> queryWrapper); <P extends IPage<Map<String, Object>>> P selectMapsPage(P page, @Param("ew") Wrapper<T> queryWrapper); }
这是完整的BaseMapper 看清楚那个报错说的什么Invalid bound statement (not found): TopOne.ListenerSystem.mapper.ListenerMapper.selectList 找不到selectList 方法!!!
学过Java都知道 一个子类继承他的父类 使用他父类的方法不是理所当然的吗?
这个BaseMapper的selectList 方法就好端端摆在那里 他就是用不了!说找不到! 你想一下气不气人? 不止是selectList 方法 而是那里面所有封装好的方法 就摆在那 他就是用不了!
试错
尝试过确认的东西:
1.ScannerMapper 扫描到了对应的Mapper
2.配置文件 路径正确
3.xml文件路径正确并无语法错误
4.别名扫描包确认路径无误
5.使用最新的MyBatisPlus版本
6.能用的法子都用了...
最终解决方案!已经完美解决:
在你确认了我上面的所有待确认点无误后
可以尝试 在MybatisConfig中
注意看这个地方
@Bean public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(dataSource); sessionFactory.setConfigLocation(new PathMatchingResourcePatternResolver().getResource("mybatis-config.xml")); return sessionFactory.getObject(); }
只需要在你配置数据源的地方:
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
更改为:
MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
已确认 所有失效的方法全部恢复!