mybatis升級為mybatis-plus踩到的坑

https://www.cnblogs.com/linyb-geek/p/13647327.html

前言

最近使用RuoYi-Vue來做后臺管理腳手架蚕涤。RuoYi-Vue 是一個 Java EE 企業(yè)級快速開發(fā)平臺滔驾,基于經(jīng)典技術(shù)組合(Spring Boot俺抽、Spring Security凑保、MyBatis、Jwt、Vue)增淹,內(nèi)置模塊如:部門管理、角色用戶舶衬、菜單及按鈕授權(quán)埠通、數(shù)據(jù)權(quán)限、系統(tǒng)參數(shù)逛犹、日志管理端辱、代碼生成等。在線定時任務配置虽画;支持集群舞蔽,支持多數(shù)據(jù)源。其官方文檔如下

http://doc.ruoyi.vip/

感興趣的朋友码撰,可以點鏈接查看渗柿。這個平臺目前的orm框架是mybatis,而項目組的orm框架是mybatis-plus脖岛。為了統(tǒng)一技術(shù)棧朵栖,項目組就決定把若依的orm框架升級為mybatis-plus。因為之前就有過把mybatis升級為mybatis-plus的經(jīng)驗柴梆,就感覺這個升級是很簡單陨溅。但是在改造后,運行程序卻報了形如下異常

Invalid boundstatement(not found): com.lybgeek.admin.file.mapper.FileMapper.insert

排查

從異常的字面意思是說绍在,F(xiàn)IleMapper中的insert方法沒有綁定门扇。查看FileMapper.xml配置,確實沒有發(fā)現(xiàn)綁定insert這個sql語句塊偿渡。那是否加上insert的sql語句塊臼寄,就能解決問題?加上確實是能解決問題溜宽。

但如果用過mybatis-plus的朋友吉拳,應該會知道,mybatis-plus中BaseMapper已經(jīng)幫我們封裝好了一系列的單表增刪改查适揉,我們無需寫配置留攒,就可以實現(xiàn)單表增刪改查。所以在xml配置insert是治標不治本涡扼。

那要如何排查呢?

1盟庞、方向一:是否是包沖突引起吃沪?

利用maven helper插件包沖突

從圖可以看出不是包沖突引起的。

注:?因為之前吃過包沖突的虧什猖,因此在把若依的orm改成mybatis-plus之前票彪,就已經(jīng)去除跟mybatis相關(guān)的 jar沖突了

方向二:是不是引入不同類包的BaseMapper

我們引入的必須是

importcom.baomidou.mybatisplus.core.mapper.BaseMapper;

而不是

importcom.baomidou.mybatisplus.mapper.BaseMapper;

不過出現(xiàn)這個問題红淡,通常也是引入不同版本的mybatis-plus jar才會出現(xiàn)。如果你是只用3+以上版本降铸,他引入就只有

importcom.baomidou.mybatisplus.core.mapper.BaseMapper;

方向三:通用方法(斷點調(diào)試)

其實代碼排查最怕就是異常棧被吃了在旱,如果有異常信息,排查方向相對比較好找推掸。比如這個異常桶蝎,其異常棧信息為

Caused by: org.apache.ibatis.binding.BindingException:Invalid boundstatement(not found): com.lybgeek.admin.file.mapper.FileMapper.insertat org.apache.ibatis.binding.MapperMethod$SqlCommand.(MapperMethod.java:235)at org.apache.ibatis.binding.MapperMethod.(MapperMethod.java:53)at org.apache.ibatis.binding.MapperProxy.lambda$cachedInvoker$0(MapperProxy.java:107)at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)at org.apache.ibatis.binding.MapperProxy.cachedInvoker(MapperProxy.java:94)at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:85)at com.sun.proxy.$Proxy129.insert(Unknown Source)at com.baomidou.mybatisplus.extension.service.IService.save(IService.java:59)at com.baomidou.mybatisplus.extension.service.IService$$FastClassBySpringCGLIB$$f8525d18.invoke(<generated>)at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)

我們從異常棧信息,我們可以知道這個異常從

org.apache.ibatis.binding.MapperMethod

這個類拋出谅畅,于是我們可以把斷點先設置到這邊登渣。通過源碼我們可以得知org.apache.ibatis.mapping.MappedStatement空了,導致報了如上異常毡泻,而MappedStatement又是由

org.apache.ibatis.session.Configuration

提供胜茧。而Configuration是通過

org.apache.ibatis.session.SqlSessionFactory

進行設置。然后繼續(xù)排查仇味,就會發(fā)現(xiàn)

com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration

這個自動裝配類呻顽。里面有這么一段代碼

@Bean@ConditionalOnMissingBeanpublicSqlSessionFactorysqlSessionFactory(DataSource dataSource)throwsException{// TODO 使用 MybatisSqlSessionFactoryBean 而不是 SqlSessionFactoryBeanMybatisSqlSessionFactoryBean factory =newMybatisSqlSessionFactoryBean();? ? ? ? factory.setDataSource(dataSource);? ? ? ? factory.setVfs(SpringBootVFS.class);if(StringUtils.hasText(this.properties.getConfigLocation())) {? ? ? ? ? ? factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));? ? ? ? }? ? ? ? applyConfiguration(factory);if(this.properties.getConfigurationProperties() !=null) {? ? ? ? ? ? factory.setConfigurationProperties(this.properties.getConfigurationProperties());? ? ? ? }if(!ObjectUtils.isEmpty(this.interceptors)) {? ? ? ? ? ? factory.setPlugins(this.interceptors);? ? ? ? }if(this.databaseIdProvider !=null) {? ? ? ? ? ? factory.setDatabaseIdProvider(this.databaseIdProvider);? ? ? ? }if(StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {? ? ? ? ? ? factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());? ? ? ? }if(this.properties.getTypeAliasesSuperType() !=null) {? ? ? ? ? ? factory.setTypeAliasesSuperType(this.properties.getTypeAliasesSuperType());? ? ? ? }if(StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {? ? ? ? ? ? factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());? ? ? ? }if(!ObjectUtils.isEmpty(this.typeHandlers)) {? ? ? ? ? ? factory.setTypeHandlers(this.typeHandlers);? ? ? ? }? ? ? ? Resource[] mapperLocations =this.properties.resolveMapperLocations();if(!ObjectUtils.isEmpty(mapperLocations)) {? ? ? ? ? ? factory.setMapperLocations(mapperLocations);? ? ? ? }// TODO 對源碼做了一定的修改(因為源碼適配了老舊的mybatis版本,但我們不需要適配)Class defaultLanguageDriver =this.properties.getDefaultScriptingLanguageDriver();if(!ObjectUtils.isEmpty(this.languageDrivers)) {? ? ? ? ? ? factory.setScriptingLanguageDrivers(this.languageDrivers);? ? ? ? }? ? ? ? Optional.ofNullable(defaultLanguageDriver).ifPresent(factory::setDefaultScriptingLanguageDriver);// TODO 自定義枚舉包if(StringUtils.hasLength(this.properties.getTypeEnumsPackage())) {? ? ? ? ? ? factory.setTypeEnumsPackage(this.properties.getTypeEnumsPackage());? ? ? ? }// TODO 此處必為非 NULLGlobalConfig globalConfig =this.properties.getGlobalConfig();// TODO 注入填充器this.getBeanThen(MetaObjectHandler.class, globalConfig::setMetaObjectHandler);// TODO 注入主鍵生成器this.getBeanThen(IKeyGenerator.class, i -> globalConfig.getDbConfig().setKeyGenerator(i));// TODO 注入sql注入器this.getBeanThen(ISqlInjector.class, globalConfig::setSqlInjector);// TODO 注入ID生成器this.getBeanThen(IdentifierGenerator.class, globalConfig::setIdentifierGenerator);// TODO 設置 GlobalConfig 到 MybatisSqlSessionFactoryBeanfactory.setGlobalConfig(globalConfig);returnfactory.getObject();? ? }

作者在注釋上都寫了,要用

MybatisSqlSessionFactoryBean 而不是 SqlSessionFactoryBean

于是查看若依代碼丹墨,發(fā)現(xiàn)在若依中的mybatis配置類中有配置如下代碼片段

@BeanpublicSqlSessionFactorysqlSessionFactory(DataSource dataSource)throwsException{? ? ? ? String typeAliasesPackage = env.getProperty("mybatis.type-aliases-package");? ? ? ? String mapperLocations = env.getProperty("mybatis.mapper-locations");? ? ? ? String configLocation = env.getProperty("mybatis.config-location");? ? ? ? typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);? ? ? ? VFS.addImplClass(SpringBootVFS.class);finalSqlSessionFactoryBean sessionFactory =newSqlSessionFactoryBean();? ? ? ? sessionFactory.setDataSource(dataSource);? ? ? ? sessionFactory.setTypeAliasesPackage(typeAliasesPackage);? ? ? ? sessionFactory.setMapperLocations(newPathMatchingResourcePatternResolver().getResources(mapperLocations));? ? ? ? sessionFactory.setConfigLocation(newDefaultResourceLoader().getResource(configLocation));returnsessionFactory.getObject();? ? }

從MybatisPlusAutoConfiguration的源碼中廊遍,我們可以得知,當項目已經(jīng)有配置SqlSessionFactory带到。mybatis-plus將不會自動幫我們注入SqlSessionFactory昧碉,而使用我們自己定義的SqlSessionFactory。而若依項目配置的SqlSessionFactory不是MybatisSqlSessionFactoryBean

修復

1揽惹、方法一

把mybatis的SqlSessionFactoryBean替換成mybatis-plus的MybatisSqlSessionFactoryBean

2被饿、方法二

去掉項目中sqlSessionFactory。這樣mybatis-plus就會自動幫我們注入sqlSessionFactory

總結(jié)

可能有朋友會覺得遇到異常問題搪搏,直接通過搜索引擎找答案不就可以了狭握。這確實是一個挺好的方法,但有時候可能搜索半天都沒找到答案疯溺,我們就可以通過異常信息棧论颅、以及調(diào)試線程棧,就可以得出一些比較有用的信息囱嫩。出現(xiàn)異常并不可怕恃疯,可怕的是出了問題,異常日志信息被吞墨闲,都不知道從何排查今妄。最后安利一下若依這個腳手架,管理后臺開發(fā)神器,誰用誰知道

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末盾鳞,一起剝皮案震驚了整個濱河市犬性,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌腾仅,老刑警劉巖乒裆,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異推励,居然都是意外死亡鹤耍,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進店門吹艇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來惰蜜,“玉大人,你說我怎么就攤上這事受神∨撞” “怎么了?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵鼻听,是天一觀的道長财著。 經(jīng)常有香客問我,道長撑碴,這世上最難降的妖魔是什么撑教? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮醉拓,結(jié)果婚禮上伟姐,老公的妹妹穿的比我還像新娘。我一直安慰自己亿卤,他們只是感情好愤兵,可當我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著排吴,像睡著了一般秆乳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上钻哩,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天屹堰,我揣著相機與錄音,去河邊找鬼街氢。 笑死扯键,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的珊肃。 我是一名探鬼主播荣刑,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼扣泊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了嘶摊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤评矩,失蹤者是張志新(化名)和其女友劉穎叶堆,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體斥杜,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡虱颗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蔗喂。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忘渔。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖缰儿,靈堂內(nèi)的尸體忽然破棺而出畦粮,到底是詐尸還是另有隱情,我是刑警寧澤乖阵,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布宣赔,位于F島的核電站,受9級特大地震影響瞪浸,放射性物質(zhì)發(fā)生泄漏儒将。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一对蒲、第九天 我趴在偏房一處隱蔽的房頂上張望钩蚊。 院中可真熱鬧,春花似錦蹈矮、人聲如沸砰逻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽诱渤。三九已至,卻和暖如春谈况,著一層夾襖步出監(jiān)牢的瞬間勺美,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工碑韵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留赡茸,地道東北人。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓祝闻,卻偏偏與公主長得像占卧,于是被迫代替她去往敵國和親遗菠。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,974評論 2 355