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