RuoYi-Vue坑之添加Mybatis-Plus

在RuoYi-Vue项目中添加Mybatis-Plus时遇到了SqlSessionFactory配置问题导致自动填充接口失效。解决方案包括注释掉MybatisConfig中的特定代码,或修改SqlSessionFactoryBean为MybatisSqlSessionFactoryBean,以及在SqlSessionFactory配置中添加全局配置和元数据处理器,以确保Mybatis-Plus的正常工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RuoYi-Vue坑之添加Mybatis-Plus

整合Mybatis-Plus

事情是这样的最近因为之前管理平台内容太过于混乱想单独隔离一部分代码,于是从gitee上拉了ruoyi-vue的开源代码来作为新的后台,而ruoyi-vue中使用的是mybatis而之前很大一部分代码使用了mybatis-plus,因此需要手动添加mybatis-plus依赖,但是添加完依赖之后运行代码却显示如下错误。

Invalid bound statement (not found): com.ruoyi.xx.mapper.xxx.selectList

左思右想问题得不到解决,于是从网上搜寻答案,最终确定问题在ruoyi的MybatisConfig配置类中的SqlSessionFactory这段代码中。

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
        String mapperLocations = env.getProperty("mybatis.mapperLocations");
        String configLocation = env.getProperty("mybatis.configLocation");
        typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
        VFS.addImplClass(SpringBootVFS.class);

        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
        sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
        sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
        return sessionFactory.getObject();
    }

SqlSessionFactory的bean影响到了mybatis-plus,当项目已经有配置SqlSessionFactory,mybatis-plus将不会自动帮我们注入SqlSessionFactory,而使用我们自己定义的SqlSessionFactory。

实际上mybatis-plus需要的是MybatisSqlSessionFactoryBean,而不是SqlSessionFactoryBean。

以上我们通过注释掉该代码,使得mybatis-plus自动帮我们注入SqlSessionFactoryBean。或者我们也可以调整该代码,使得手动将其中的SqlSessionFactoryBean修改为MybatisSqlSessionFactoryBean。

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
        String mapperLocations = env.getProperty("mybatis.mapperLocations");
        String configLocation = env.getProperty("mybatis.configLocation");
        typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
        VFS.addImplClass(SpringBootVFS.class);

        MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
        sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
        sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
        return sessionFactory.getObject();
    }

经过测试,原代码中涉及到mybatis-plus的功能可以正常运行。

参考:http://e.betheme.net/article/show-976685.html

自动填充接口不起作用

Mybatis-Plus为我们提供了 MetaObjectHandler 接口方便在插入或者修改时自动填充数据,这为我们在日常开发中对于插入或填充操作时修改数据提供了便利,如在插入时自动添加 create_time字段,初始化is_del字段,在进行修改操作时 自动修改 update_time字段。
使用自动填充功能首先要在相应的字段上添加@TableField注解并通过设置fill属性来确定字段填充的类型。

    @TableField(fill= FieldFill.INSERT)  // 插入时自动填充createTime字段
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private Date createTime;

    @TableField(fill= FieldFill.UPDATE) // 修改时自动填充updateTime字段
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private Date updateTime;

    @TableLogic
    @JsonIgnore
    @TableField(fill= FieldFill.INSERT)
    private Integer isDel;

其次,创建MetaObjectHandler接口的实现类设置填充值

@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {


    /**
     * 新增数据执行
     *
     * @param metaObject 元数据
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        try {
            Timestamp time = new Timestamp(System.currentTimeMillis());
            if (metaObject.hasSetter("createTime")) {
                log.debug("自动插入 createTime");
                this.setFieldValByName("createTime", time, metaObject);
            }
            if (metaObject.hasSetter("updateTime")) {
                log.debug("自动插入 updateTime");
                this.setFieldValByName("updateTime", time, metaObject);
            }
            if (metaObject.hasSetter("createDate")) {
                log.debug("自动插入 createDate");
                this.setFieldValByName("createDate", time, metaObject);
            }
            if (metaObject.hasSetter("updateDate")) {
                log.debug("自动插入 updateDate");
                this.setFieldValByName("updateDate", time, metaObject);
            }
            if (metaObject.hasSetter("delFlag")) {
                log.debug("自动插入 delFlag");
                this.setFieldValByName("delFlag", false, metaObject);
            }
            if (metaObject.hasSetter("isDel")) {
                log.debug("自动插入 isDel");
                this.setFieldValByName("isDel", 0, metaObject);
            }
            if (metaObject.hasSetter("addTime")) {
                String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
                this.setFieldValByName("addTime", Integer.valueOf(timestamp), metaObject);
            }
        } catch (Exception e) {
            log.error("自动注入失败:{}", e.getMessage(), e);
        }
    }

    /**
     * 更新数据执行
     *
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        try {
            Timestamp time = new Timestamp(System.currentTimeMillis());
            if (metaObject.hasSetter("updateTime")) {
                log.debug("自动插入 updateTime");
                this.setFieldValByName("updateTime", time, metaObject);
            }
            if (metaObject.hasSetter("updateDate")) {
                log.debug("自动插入 updateDate");
                this.setFieldValByName("updateDate", time, metaObject);
            }
            if (metaObject.hasSetter("delFlag")) {
                log.debug("自动插入 delFlag");
                this.setFieldValByName("delFlag", null, metaObject);
            }
            if (metaObject.hasSetter("createTime")) {
                log.debug("自动插入 createTime");
                this.setFieldValByName("createTime", null, metaObject);
            }
        } catch (Exception e) {
            log.error("自动注入失败:{}", e.getMessage(), e);
        }
    }
}

参考:https://www.baomidou.com/pages/4c6bcf/

设置完之后运行程序,发现在进行填充时并未起作用,最后发现仍是ruoyi-vue的 MybatisConfig的原因,因为在整合 Mybatis-plus时在 MybatisConfig 中设置了 Mybatis-Plus 的 SqlSessionFactory 导致覆盖了默认的相关配置,因此需要在 SqlSessionFactory 这段代码中添加全局配置并在全局配置中添加元数据处理器。

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
        String mapperLocations = env.getProperty("mybatis.mapperLocations");
        String configLocation = env.getProperty("mybatis.configLocation");
        typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
        VFS.addImplClass(SpringBootVFS.class);

        MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
        sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
        sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));

        //获取mybatis-plus全局配置
        GlobalConfig globalConfig = GlobalConfigUtils.defaults();
        //mybatis-plus全局配置设置自己实现的元数据对象处理器
        globalConfig.setMetaObjectHandler(new MybatisPlusAutoFillConfig());
        sessionFactory.setGlobalConfig(globalConfig);
        return sessionFactory.getObject();
    }

添加完毕测试,程序正常运行

参考:http://www.icodebang.cn/article/397509

<think>好的,用户想查找关于RuoYi-Vue-Plus的信息,包括项目介绍、源码地址、使用说明和官方文档。首先,我需要回忆一下之前提供的引用内容,看看有哪些相关信息可用。 在用户提供的引用中,引用[1]提到RuoYi-Vue-Plus的初步了解和快速上手指南,并指向项目官方文档。引用[2]给出了项目的地址,是https://gitcode.com/gh_mirrors/ru/RuoYi-Vue-fast,但可能需要确认这个链接是否正确,因为有时候镜像仓库可能不是官方的。引用[3]到引用[5]似乎涉及到其他项目,比如Spring Boot Admin和Vue3的练习项目,可能相关性不大,但需要注意是否有其他有用的信息。 接下来,用户需要项目介绍。根据引用[1],RuoYi-Vue-Plus是基于RuoYi的增强版,可能包含更多功能或优化。需要确认是否有更多详细的项目特性,比如技术栈、功能模块等,但根据现有引用,可能需要建议用户查看官方文档以获取详细信息。 关于源码地址,引用[2]提供了一个GitCode的链接,但通常开源项目的主仓库可能在GitHub或Gitee。需要检查这个链接是否有效,或者是否还有其他官方仓库。例如,RuoYi本身有多个变体,可能Vue-Plus版本有特定的仓库。另外,引用[5]提到Vue3项目,可能RuoYi-Vue-Plus是否基于Vue3?需要确认,但根据引用[5]的内容,它可能只是提到Vue3的趋势,并不直接相关。 使用说明方面,引用[1]提到有快速上手指南,用户应参考官方文档。可能需要指导用户如何找到文档,是否在项目仓库的README或Wiki中,或者有独立的文档站点。 官方文档和GitHub地址可能需要进一步确认。如果引用[2]的项目地址正确,那么源码就在那里,但需要确认是否为官方源。此外,是否有其他引用提到文档位置,比如引用[3]中的Spring Boot Admin修改可能与监控模块相关,但可能不直接影响用户的问题。 总结用户的需求,可能需要整理出以下几点: 1. 项目介绍:基于RuoYi的增强版,可能包含更多模块或优化,适合快速开发。 2. 源码地址:根据引用[2]提供的GitCode链接,但建议用户核实是否为官方仓库。 3. 使用说明:参考官方文档,可能包含快速上手指南和详细配置步骤。 4. 官方文档和GitHub地址:需要明确链接,可能引用[1]中的官方文档链接未直接给出,需提示用户查看项目仓库的文档部分。 需要注意是否有其他引用被遗漏,比如引用[4]提到Spring Boot 3和knife4j的依赖,可能说明RuoYi-Vue-Plus使用了这些技术,但用户可能更关注获取项目的基本信息和如何开始使用。 可能还需要提醒用户,如果提供的链接不是最新或官方的,建议访问RuoYi的官方网站或GitHub组织页面查找Vue-Plus版本的正确仓库。此外,可能需要提及项目的社区或支持渠道,比如论坛或Issues页面,以便用户获取帮助。 最后,生成相关问题时应围绕用户可能进一步的需求,比如如何部署、配置特定模块,或者与其他技术的集成,如Spring Cloud、Vue3等。</think>### RuoYi-Vue-Plus 项目信息整理 #### 1. 项目介绍 RuoYi-Vue-Plus 是基于若依(RuoYi)框架的增强版本,主要面向企业级后台管理系统开发,整合了 Spring Boot、Vue3、MyBatis-Plus 等主流技术栈[^1][^5]。相比基础版本,其优化了以下功能: - 支持 Spring Boot 3.x 和 JDK 17+[^4] - 集成更完善的前后端分离架构 - 增强代码生成器功能 - 扩展监控模块(集成 Spring Boot Admin)[^3] #### 2. 源码地址 - **主仓库镜像**(GitCode): https://gitcode.com/gh_mirrors/ruoyi-vue-plus[^2] - **官方文档**: 建议优先查看项目仓库中的 `README.md` 和 `/docs` 目录,快速入门指南可直接访问文档说明[^1] #### 3. 使用说明 1. **环境要求**: ```markdown - JDK 17+ - MySQL 8.0+ - Redis 5.0+ ``` 2. **快速启动**: ```bash # 后端启动 mvn clean install java -jar ruoyi-admin.jar # 前端启动 npm install npm run dev ``` 3. **核心功能配置**: - 监控模块需单独部署 `ruoyi-monitor` 子模块[^3] - API 文档通过 `knife4j` 集成,访问 `/doc.html` 查看[^4] #### 4. 技术生态 ```mermaid graph LR A[RuoYi-Vue-Plus] --> B[Spring Boot 3] A --> C[Vue3 + Vite] A --> D[MyBatis-Plus] A --> E[Spring Boot Admin] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值