You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

本地运行项目遇Invalid bound statement (not found)错误排查与解决

MyBatis-Plus 「Invalid bound statement (not found)」错误排查与解决

错误触发场景

执行代码boolean superAdmin = sysRoleService.isSuperAdmin(userId);时,抛出以下绑定异常:

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.casey.mapper.SysRoleMapper.getUserRoleCode
    at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235) ~[mybatis-3.5.4.jar:3.5.4]
    at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.<init>(MybatisMapperMethod.java:50) ~[mybatis-plus-core-3.3.2.jar:3.3.2]
    at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.lambda$cachedMapperMethod$0(MybatisMapperProxy.java:101) ~[mybatis-plus-core-3.3.2.jar:3.3.2]
    at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660) ~[na:1.8.0_291]
    at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.cachedMapperMethod(MybatisMapperProxy.java:100) ~[mybatis-plus-core-3.3.2.jar:3.3.2]
    at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:95) ~[mybatis-plus-core-3.3.2.jar:3.3.2]
    at com.sun.proxy.$Proxy159.getUserRoleCode(Unknown Source) ~[na:na]
    at com.casey.service.impl.SysRoleServiceImpl.isSuperAdmin(SysRoleServiceImpl.java:29) ~[classes/:na]

项目相关代码

启动类 AdminServiceApplication

/**
 * admin-service 启动类
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@MapperScan(basePackages = { "com.casey.mapper" })
public class AdminServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(AdminServiceApplication.class, args);
    }
}

服务接口 SysRoleService

public interface SysRoleService extends IService<SysRole>{

    /**
     * 判断一个用户是否为超级管理员
     * @param userId
     * @return
     */
    boolean isSuperAdmin(Long userId);
}

服务实现类 SysRoleServiceImpl

@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService{

    @Autowired
    private SysRoleMapper sysRoleMapper;

    /**
     * 判断一个用户是否为超级管理员
     * @param userId
     * @return
     */
    @Override
    public boolean isSuperAdmin(Long userId) {
        // 当用户角色的 code 为 ROLE_ADMIN 时,该用户为超级管理员
        // 用户id -> 用户角色 -> 该角色是否为 ROLE_ADMIN
        String roleCode = sysRoleMapper.getUserRoleCode(userId);
        if(StringUtils.isEmpty(roleCode) && roleCode.equals("ROLE_ADMIN")){
            return true;
        }
        return false;
    }
}

Mapper 接口 SysRoleMapper

public interface SysRoleMapper extends BaseMapper<SysRole> {
    /**
     * 获取用户 code 的实现
     * @param userId
     * @return
     */
    String getUserRoleCode(Long userId);
}

Mapper XML 文件 SysRoleMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.casey.mapper.SysRoleMapper">
  <resultMap id="BaseResultMap" type="com.casey.domain.SysRole">
    <!--@mbg.generated-->
    <!--@Table sys_role-->
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="code" jdbcType="VARCHAR" property="code" />
    <result column="description" jdbcType="VARCHAR" property="description" />
    <result column="create_by" jdbcType="BIGINT" property="createBy" />
    <result column="modify_by" jdbcType="BIGINT" property="modifyBy" />
    <result column="status" jdbcType="TINYINT" property="status" />
    <result column="created" jdbcType="TIMESTAMP" property="created" />
    <result column="last_update_time" jdbcType="TIMESTAMP" property="lastUpdateTime" />
  </resultMap>
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, `name`, code, description, create_by, modify_by, `status`, created, last_update_time
  </sql>

  <select id="getUserRoleCode" resultType="java.lang.String">
    SELECT
        r.`code`
    FROM
        sys_role AS r LEFT JOIN sys_user_role AS ur ON r.id = ur.role_id
    WHERE
        ur.user_id = #{userId};
  </select>
</mapper>

配置文件

mybatis-plus:
    configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    mapper-locations: classpath:/mappers/*Mapper.xml

前期无效排查动作

执行mvn clean命令并手动清理target文件夹后,错误仍未解决。

问题根因

自定义的SqlSessionFactory配置类覆盖了Nacos中的YAML配置,且未在代码中指定Mapper文件路径,导致MyBatis无法找到对应的XML映射语句。

原错误配置代码:

@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
    //获取mybatis-plus全局配置
    GlobalConfig globalConfig = GlobalConfigUtils.defaults();
    //mybatis-plus全局配置设置元数据对象处理器为自己实现的那个
    globalConfig.setMetaObjectHandler(new AutoFillHandler());
    mybatisSqlSessionFactoryBean.setDataSource(dataSource);
    //mybatisSqlSessionFactoryBean关联设置全局配置
    mybatisSqlSessionFactoryBean.setGlobalConfig(globalConfig);
    return mybatisSqlSessionFactoryBean.getObject();
}

解决方法

在SqlSessionFactory配置中添加Mapper文件路径的设置,确保MyBatis能扫描到XML映射文件:

@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
    //获取mybatis-plus全局配置
    GlobalConfig globalConfig = GlobalConfigUtils.defaults();
    //mybatis-plus全局配置设置元数据对象处理器为自己实现的那个
    globalConfig.setMetaObjectHandler(new AutoFillHandler());
    mybatisSqlSessionFactoryBean.setDataSource(dataSource);
    //mybatisSqlSessionFactoryBean关联设置全局配置
    mybatisSqlSessionFactoryBean.setGlobalConfig(globalConfig);
    // 设置 Mapper 文件的位置
    Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath:mappers/*Mapper.xml");
    mybatisSqlSessionFactoryBean.setMapperLocations(resources);
    return mybatisSqlSessionFactoryBean.getObject();
}

内容的提问来源于stack exchange,提问作者Caseythekiwi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 03:43:11