Spring整合Mybatis一文讲透,手把手带你实操

在介绍Spring整合Mybatis原理之前,我们得先来稍微介绍Mybatis的工作原理。

在Mybatis中,我们可以使用一个接口去定义要执行sql,简化代码如下: 定义一个接口,@Select表示要执行查询sql语句。

以下为执行sql代码:

Mybatis的目的是:使得程序员能够以调用方法的方式执行某个指定的sql,将执行sql的底层逻辑进行了封装。 这里重点思考以下mapper这个对象,当调用SqlSession的getMapper方法时,会对传入的接口生成一个 代理对象,而程序要真正用到的就是这个代理对象,在调用代理对象的方法时,Mybatis会取出该方法所对应的sql语句,然后利用JDBC去执行sql语句,最终得到结果。

UserService中的userMapper属性就会被自动注入为Mybatis中的代理对象。如果你基于一个已经完成整合的项目去调试即可发现,userMapper的类型为: org.apache.ibatis.binding.MapperProxy@41a0aa7d。证明确实是Mybatis中的代理对象。 好,那么现在我们要解决的问题的就是:如何能够把Mybatis的代理对象作为一个bean放入Spring容器中?要解决这个,我们需要对Spring的bean生成过程有一个了解。

Spring启动过程中,大致会经过如下步骤去生成bean

假设有一个A类,假设有如下代码: 一个A类

一个B类,不存在@Component注解

执行如下代码:

输出结果为:com.luban.util.A@6acdbdf5 A类对应的bean对象类型仍然为A类。但是这个结论是不确定的,我们可以利用BeanFactory后置处理器来 修改BeanDefinition,我们添加一个BeanFactory后置处理器:

这样就会导致,原本的A类对应的BeanDefiniton被修改了,被修改成了B类,那么后续正常生成的bean对 象的类型就是B类。此时,调用如下代码会报错:

但是调用如下代码不会报错,尽管B类上没有@Component注解:

并且,下面代码返回的结果是:com.luban.util.B@4b1c1ea0

之所以讲这个问题,是想说明 个问题:在Spring中,bean对象跟class没有直接关系,跟 BeanDefinition才有直接关系。 那么回到我们要解决的问题:如何能够把Mybatis的代理对象作为一个bean放入Spring容器中? 在Spring中,如果你想生成一个bean,那么得先生成一个BeanDefinition,就像你想new一个对象实 例,得先有一个class。

继续回到我们的问题,我们现在想自己生成一个bean,那么得先生成一个BeanDefinition,只要有了 BeanDefinition,通过在BeanDefinition中设置bean对象的类型,然后把BeanDefinition添加给 Spring,Spring就会根据BeanDefinition 动帮我们 成 个类型对应的bean对象。 所以,现在我们要解决两个问题:

注意:上文中我们使用的BeanFactory后置处理器,他只能修改BeanDefinition,并不能新增一个 BeanDefinition。我们应该使用Import技术来添加一个BeanDefinition。后面再详细介绍如果使用Import 技术来添加一个BeanDefinition,可以先看一下伪代码实现思路。

假设:我们有一个UserMapper接口,他的代理对象的类型为UserMapperProxy。 那么我们的思路就是这样的,伪代码如下:

但是,这里有一个严重的问题,就是上文中的UserMapperProxy是我们假设的,他表示一个代理类的类 型,然而Mybatis中的代理对象是利用的JDK的动态代理技术实现的,也就是代理对象的代理类是动态生成的,我们根本方法确定代理对象的代理类到底是什么。 所以回到我们的问题:Mybatis的代理对象的类型是什么? 本来可以有两个答案: 1. 代理对象对应的代理类 2. 代理对象对应的接口 那么答案1就相当于没有了,因为是代理类是动态生成的,那么我们来看答案2:代理对象对应的接口如果我们采用答案2,那么我们的思路就是:

但是,实际上给BeanDefinition对应的类型设置为一个接口是行不通的,因为Spring没有办法根据这个 BeanDefinition去new出对应类型的实例,接口是没法直接new出实例的。 那么现在问题来了,我要解决的问题:Mybatis的代理对象的类型是什么? 两个答案都被我们否定了,所以这个问题是无解的,所以我们不能再沿着这个思路去思考了,只能回到最 开始的问题:如何能够把Mybatis的代理对象作为一个bean放入Spring容器中?

总结上文的推理:我们想通过设置BeanDefinition的class类型,然后由Spring自动的帮助我们去生成对应的bean,但是这条路是行不通的。 终极解决方案 那么我们还有没有其他办法,可以去生成bean呢?并且生成bean的逻辑不能由Spring来帮我们做了,得 由我们自己来做。 FactoryBean 有,那就是Spring中的FactoryBean。我们可以利用FactoryBean去自定义我们要生成的bean对象,比如

我们定义了一个LubanFactoryBean,它实现了FactoryBean,getObject方法就是用来自定义生成bean 对象逻辑的。 执行如下代码:

将打印: lubanFactoryBean: com.luban.util.LubanFactoryBean 1@4d41cee &lubanFactoryBean: com.luban.util.LubanFactoryBean@3712b94 lubanFactoryBean-class: class com.sun.proxy. Proxy20 从结果我们可以看到,从Spring容器中拿名字为"lubanFactoryBean"的bean对象,就是我们所自定义的 jdk动态代理所生成的代理对象。

所以,我们可以通过FactoryBean来向Spring容器中添加一个自定义的bean对象。上文中所定义的 LubanFactoryBean对应的就是UserMapper,表示我们定义了一个LubanFactoryBean,相当于把 UserMapper对应的代理对象作为一个bean放入到了容器中。 但是作为程序员,我们不可能每定义了一个Mapper,还得去定义一个LubanFactoryBean,这是很麻烦的 事情,我们改造一下LubanFactoryBean,让他变得更通用,比如:

改造LubanFactoryBean之后,LubanFactoryBean变得灵活了,可以在构造LubanFactoryBean时,通 过构造传入不同的Mapper接口。 实际上LubanFactoryBean也是一个Bean,我们也可以通过生成一个BeanDefinition来生成一个 LubanFactoryBean,并给构造方法的参数设置不同的值,比如伪代码如下:

特别说一下注意二,表示表示当前BeanDefinition在生成bean对象时,会通过调用LubanFactoryBean的 构造方法来生成,并传入UserMapper的Class对象。那么在生成LubanFactoryBean时就会生成一个 UserMapper接口对应的代理对象作为bean了。 到此为止,其实就完成了我们要解决的问题:把Mybatis中的代理对象作为一个bean放入Spring容器中。

只是我们这是用简单的JDK代理对象模拟的Mybatis中的代理对象,如果有时间,我们完全可以调 Mybatis中提供的方法区生成一个代理对象。这里就不花时间去介绍了。 Import 到这里,我们还有一个事情没有做,就是怎么真正的定义一个BeanDefinition,并把它添加到Spring中, 上文说到我们要利用Import技术,比如可以这么实现: 定义如下类:

并且在AppConfig上添加@Import注解:

这样在启动Spring时就会新增一个BeanDefinition,该BeanDefinition会生成一个LubanFactoryBean对 象,并且在生成LubanFactoryBean对象时会传入UserMapper.class对象,通过LubanFactoryBean内部 的逻辑,相当于会自动生产一个UserMapper接口的代理对象作为一个bean。

总结一下,通过我们的分析,我们要整合Spring和Mybatis,需要我们做的事情如下:


作者:程序员周瑜
链接:https://juejin.cn/post/7089023062800236552



  • Spring鏁村悎Mybatis涓鏂囪閫,鎵嬫妸鎵嬪甫浣犲疄鎿
    绛旓細鍦ㄤ粙缁Spring鏁村悎Mybatis鍘熺悊涔嬪墠锛屾垜浠緱鍏堟潵绋嶅井浠嬬粛Mybatis鐨勫伐浣滃師鐞嗐傚湪Mybatis涓紝鎴戜滑鍙互浣跨敤涓涓帴鍙e幓瀹氫箟瑕佹墽琛宻ql锛岀畝鍖栦唬鐮佸涓嬶細 瀹氫箟涓涓帴鍙o紝@Select琛ㄧず瑕佹墽琛屾煡璇ql璇彞銆備互涓嬩负鎵цsql浠g爜锛歁ybatis鐨勭洰鐨勬槸锛氫娇寰楃▼搴忓憳鑳藉浠ヨ皟鐢ㄦ柟娉曠殑鏂瑰紡鎵ц鏌愪釜鎸囧畾鐨剆ql锛屽皢鎵цsql鐨勫簳灞傞昏緫杩涜...
  • Spring+Boot鏁村悎MyBatis鐨勯嗗悜宸ョ▼闇瑕佸湪pom鏂囦欢涓厤缃浉搴旂殑渚濊禆鏄...
    绛旓細棣栧厛锛屼綘闇瑕佹坊鍔MyBatis鐩稿叧鐨勪緷璧栵細xml澶嶅埗浠g爜<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version></dependency> 鎺ヤ笅鏉ワ紝浣犺繕闇瑕佹坊鍔燤ySQL鏁版嵁搴撻┍鍔ㄤ緷璧栵紙濡傛灉浣犱娇鐢ㄧ殑鏄疢ySQL锛夛細xml澶嶅埗浠g爜<dependency> ...
  • 璇锋暀Mybatis鍜Spring缁撳悎鐨勯厤缃棶棰
    绛旓細椤圭洰涓敤鐨勬槸spring3.0.5锛孧yBatis3.0.5锛鏁村悎mybatis,spring鐢ㄧ殑鏄痬ybatis-spring-.1.0.1銆傚湪杩欎釜杩囩▼涓紝閬囧埌浜嗕竴涓厤缃笂鐨勯棶棰橈紝灏辨槸閰嶇疆Mapper鏃剁殑閿欒锛屽湪杩愯鏃舵姏鍑哄涓嬪紓甯革細Exception in thread "main" java.lang.IllegalArgumentException : Mapped Statements collection does not contain ...
  • spring鍜mybatis鏁村悎鎬庝箞灏嗕簨鍔″湪service灞傚叧闂?浣跨敤xml閰嶇疆
    绛旓細濡傦細<tx:method name="save*" propagation="REQUIRED"/> 杩欑鍦╯ervice灞傝皟鐢╯aveXXX鏂规硶鏃跺 杩欎釜鏂规硶灏辫浜嬪姟绠$悊锛岃繖涓猻ave鏂规硶閲 鍐嶈皟鐢╠ao灞傛煡璇簡浣犺鐨勬暟鎹椂鍊 寮鍚簡session 寮鍚簡浜嬪姟 銆傚綋浣犳墽琛屽畬浜嗚繖涓猻ave鏂规硶 浜嬪姟鑷姩鍏抽棴锛宻ession涔熻嚜鍔ㄥ叧闂紝閮芥槸鐢spring绠$悊鐨 ...
  • 鎬庝箞鎼缓springmvc鍜mybatis
    绛旓細SpringMVC+MyBatis+Freemarker 绠鍗曟鏋舵惌寤(涓)涓銆佸紑鍙戠幆澧: Eclipse銆乀omcat銆丼VN绛夎鍙傝濡備笅鐨勫笘瀛,寰堣缁嗕簡銆 http://www.iteye.com/topic/982182 svn鍜宮aven鎻掍欢鐨勫畨瑁: 1銆佸厛瀹夎gef鎻掍欢 鍦板潃:http://download.eclipse.org/tools/gef/updates/interim/ 2銆佸畨瑁卻vn鎻掍欢 鍦板潃:http://subclipse.tigris.org...
  • 姹傛暀Springboot+mybatis鐨勯厤缃
    绛旓細<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.0.0</version></dependency>properties 閰嶇疆 mybatis.config= # mybatis config filemybatis.mapperLocations= # mappers filemybatis.typeAliasesPackage= # dom...
  • spring鏁村悎mybatis鏌ヨ鏁版嵁搴撴椂鍗℃浠涔堝師鍥?
    绛旓細sql閿佹浜嗗惂銆傜湅鐪嬫湁娌℃湁閿乻ql璇彞浜嗭紝鍐嶇湅鐪嬪叧鑱斿瓧娈垫槸涓嶆槸閲囩敤鐩稿悓鐨勬牸寮忥紝濡傛灉涓嶆槸锛屽氨浼氬嚭鐜皊ql鎵ц瓒婃潵瓒婃參锛屾渶鍚庣洿鎺ュ鑷存煡璇㈠牭濉炵殑鎯呭喌
  • spring+mybatis鐨勪紭缂虹偣
    绛旓細mybatis閫傜敤浜庡皬鍨嬩笖绋嬪簭鍛樿兘鍔涜緝浣庣殑椤圭洰鍜屼汉缇や娇鐢紝瀵逛簬涓ぇ鍨嬮」鐩潵璇存垜骞朵笉鎺ㄨ崘浣跨敤锛屽鏋滆寰梙ibernate鏁堢巼浣庣殑璇濓紙瀹為檯涓婁篃鏄娇鐢ㄤ笉褰撴墍鑷达紝hibernate鏄疄闄呬笂鏄笉閫傜敤浜庢嫢鏈夐珮璐熻浇鐨勫伐绋嬮」鐩級锛岃繕涓嶅鐩存帴鐢spring鎻愪緵鐨刯dbc绠鍗曟鏋讹紙Template锛夛紝鍚屾牱鏀寔瀵硅薄鏄犲皠銆俿pring鐨勪紭缂虹偣:浼樼偣a. Spring鑳...
  • SpringBoot鏁村悎Mybatis鑷畾涔夋嫤鎴櫒涓嶈捣浣滅敤瑙e喅鏂规!!!
    绛旓細; 銆傚鑷村嵆浣垮皢鑷畾涔夋嫤鎴櫒鏀惧叆鍒Spring瀹瑰櫒锛屼絾鍗翠笉鐢熸晥銆傝繖绉嶆儏鍐典笅锛mybatis鑷畾涔夋嫤鎴櫒浼氳鎵ц涓ゆ銆傚嵆鍦╩ybatis-config.xml閰嶇疆鐨勬嫤鎴櫒浼氶氳繃鍙嶅皠鐨勬柟寮忓垱寤烘嫤鎴櫒锛屾斁鍏pring瀹瑰櫒鐨勬嫤鎴櫒涔熶細琚垵濮嬪寲銆傛簮鐮佷綅缃細 org.mybatis.spring.SqlSessionFactoryBean#buildSqlSessionFactory 鏈缁堜細鎵ц鍒帮細
  • 鍩轰簬Spring+SpringMVC+Mybatis鍒嗗竷寮忔晱鎹峰紑鍙戠郴缁熸灦鏋(闄勬簮鐮)_鐧惧害...
    绛旓細Spring+SpringMVC+Mybatis妗嗘灦闆嗘垚鍏叡妯″潡锛屽寘鎷叕鍏遍厤缃丮ybatisGenerator鎵╁睍鎻掍欢銆侀氱敤BaseService銆佸伐鍏风被绛夈傚熀浜巄ootstrap瀹炵幇鐨勫搷搴斿紡Material Design椋庢牸鐨勯氱敤鍚庡彴绠$悊绯荤粺锛寊heng椤圭洰鎵鏈夊悗鍙扮郴缁熼兘鏄娇鐢ㄨ妯″潡鐣岄潰浣滀负鍓嶇灞曠ず銆傚悇涓瓙绯荤粺鍓嶅彴thymeleaf妯℃澘锛屽墠绔祫婧愭ā鍧楋紝浣跨敤nginx浠g悊锛屽疄鐜板姩闈欏垎绂汇...
  • 扩展阅读:欧洲applestore ... online shopping ... springboot整合mybatis-plus ... springmvc整合mybatis ... shiro整合springbootadmin ... springer官网入口 ... spring boot集成mybatis ... spring boot引入mybatis ... springer nature ...

    本站交流只代表网友个人观点,与本站立场无关
    欢迎反馈与建议,请联系电邮
    2024© 车视网