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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值