一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - mybatis-4 mybatis與spring結合使用及原理解析

mybatis-4 mybatis與spring結合使用及原理解析

2021-07-30 11:36為了WZJ Java教程

本文通過圖文并茂的形式給大家介紹了mybatis-4 mybatis與spring結合使用及原理解析,非常不錯,具有一定的參考借鑒價值 ,需要的朋友可以參考下

1、創建項目maven,方便依賴下載。使用的jar如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<dependencies>
 <dependency>
 <groupid>org.springframework</groupid>
 <artifactid>spring-context</artifactid>
 <version>5.0.8.release</version>
 </dependency>
 <dependency>
 <groupid>org.mybatis</groupid>
 <artifactid>mybatis-spring</artifactid>
 <version>2.0.0</version>
 </dependency>
 <dependency>
 <groupid>org.mybatis</groupid>
 <artifactid>mybatis</artifactid>
 <version>3.4.6</version>
 </dependency>
 <dependency>
 <groupid>mysql</groupid>
 <artifactid>mysql-connector-java</artifactid>
 <version>5.1.34</version>
 </dependency>
 <dependency>
 <groupid>org.springframework</groupid>
 <artifactid>spring-jdbc</artifactid>
 <version>5.0.8.release</version>
 </dependency>
 <dependency>
 <groupid>org.springframework</groupid>
 <artifactid>spring-core</artifactid>
 <version>5.0.8.release</version>
 </dependency>
</dependencies>

2、創建包com >config、dao、service、test

mybatis-4 mybatis與spring結合使用及原理解析

3、使用spring創建appconfig文件,創建bean>sqlsessionfactorybean、datasourcebean

  1、spring注解@configuration,說明是配置層

  2、注冊掃描映射

  3、注冊包掃描器

  4、創建sqlsessionfactorybean

  5、創建數據源bean

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.config;
import org.mybatis.spring.sqlsessionfactorybean;
import org.mybatis.spring.annotation.mapperscan;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.componentscan;
import org.springframework.context.annotation.configuration;
import org.springframework.jdbc.datasource.drivermanagerdatasource;
import javax.sql.datasource;
@configuration
@mapperscan("com.dao")//注解 與xml<mybatis:scan base-package="org.mybatis.spring.sample.mapper" />
//注冊包中遞歸搜索映射器
@componentscan("com")//注冊bean
public class appconfig {
 @bean
 @autowired
 public sqlsessionfactorybean sqlsessionfactorybean(datasource datasource ){
 sqlsessionfactorybean sqlsessionfactorybean = new sqlsessionfactorybean();
 sqlsessionfactorybean.setdatasource(datasource);
 return sqlsessionfactorybean;
 }
 @bean
 public datasource getdatasource(){
 drivermanagerdatasource datasource = new drivermanagerdatasource();
 datasource.setdriverclassname("com.mysql.jdbc.driver");
 datasource.setusername("root");
 datasource.setpassword("110226wjwj");
 datasource.seturl("jdbc:mysql://localhost:3306/mybatis_wjw?useunicode=true&characterencoding=utf-8&usessl=false");
 return datasource;
 }
}

4、創建dao接口

  1、創建query方法并使用注解@select(mybatis提供,mybatis-spring官網有相關解釋)

?
1
2
3
4
5
6
7
8
package com.dao;
import org.apache.ibatis.annotations.select;
import java.util.list;
import java.util.map;
public interface userdao {
 @select ("select * from t_user where tid =3")
 public list<map> query();
}

5、創建服務層

  1、注解服務層

  2、引入daobean

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.service;
import com.dao.userdao;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.stereotype.service;
//spring注解中service與component意思差不多,區別在于component是中立注解,而service是業務邏輯層的注解
//@component
@service
public class userservice {
 @autowired
 userdao userdao;
 public void query(){
 system.out.println(userdao.query());
 }
}

6、測試

  1、創建application

  2、創建service

?
1
2
3
4
5
6
7
8
9
10
11
package com.test;
import com.config.appconfig;
import com.service.userservice;
import org.springframework.context.annotation.annotationconfigapplicationcontext;
public class maintest {
 public static void main(string args[]){
 annotationconfigapplicationcontext acc = new annotationconfigapplicationcontext(appconfig.class);
 userservice us = acc.getbean(userservice.class);
 us.query();
 }
}

jar包之家:https://mvnrepository.com/artifact

使用spring依賴注入mapper   根據官網提示需要

<mybatis:scan base-package="org.mybatis.spring.sample.mapper" />==@mapperscan(“需要注入的包”)

mybatis-4 mybatis與spring結合使用及原理解析

mybatis缺點:使用xml方式與dao開發結合出現嚴重的臃腫現象,需要維護很多sql語句。

測試的時候出現這個問題。(版本導致,我直接將最新[mybatis-spring]的導入進來就沒問題了)

mybatis-4 mybatis與spring結合使用及原理解析

 上面的問題解決后有出現這個問題,此問題出現的原因是java compiler改成8就ok了

mybatis-4 mybatis與spring結合使用及原理解析

 測試結果:

mybatis-4 mybatis與spring結合使用及原理解析
mybatis-4 mybatis與spring結合使用及原理解析

重點:

  mybatis運行原理

    我們可以看到,再測試類中用的是userservice對象調用dao接口中的query,但是mybatis是如何實現將接口轉換成對象的呢? 答案:動態代理 ,我們常用的代理(proxy)一共有兩種:cglib和jdk兩用代理模式
    無論哪一種最終都是使用反射機制進行代理。詳情自己查看度娘(哈哈@0@) 

mybatis-4 mybatis與spring結合使用及原理解析

  mybatis源碼解析

    defaultsqlsession下如何實現返回一條數據的:底層調用的是selectlist方法,對返回的結果集進行數量判斷如果==1則直接放回,>1直接拋出toomanyresultsexception(感覺很傻,有些妄自菲薄!)

?
1
2
3
4
5
6
7
8
9
10
public <t> t selectone(string statement, object parameter) {
 list<t> list = this.selectlist(statement, parameter);
 if (list.size() == 1) {
  return list.get(0);
 } else if (list.size() > 1) {
  throw new toomanyresultsexception("expected one result (or null) to be returned by selectone(), but found: " + list.size());
 } else {
  return null;
 }
 }

  下面我們繼續看selectlist是如何實現的

?
1
2
3
4
5
6
7
8
9
10
11
12
public <e> list<e> selectlist(string statement, object parameter, rowbounds rowbounds) {
 list var5;
 try {
  mappedstatement ms = this.configuration.getmappedstatement(statement);
  var5 = this.executor.query(ms, this.wrapcollection(parameter), rowbounds, executor.no_result_handler);
 } catch (exception var9) {
  throw exceptionfactory.wrapexception("error querying database. cause: " + var9, var9);
 } finally {
  errorcontext.instance().reset();
 }
 return var5;
 }

  我們來看看這個defaultsqlsession.configuration.getmappedstatement方法具體是什么

mybatis-4 mybatis與spring結合使用及原理解析


mybatis-4 mybatis與spring結合使用及原理解析

結論:再啟動項目的時候,mybatis會進行初始化,這個初始化就是將我們的"包+類+方法名"作為key 和 sql語句作為value 的鍵值對形式賦給下面map類型的mappedstatements
protected final map<string, mappedstatement> mappedstatements;
這也是為什么我們使用xml方式一定要將方法名字與id對應上才能使用,如果對應不上再進行id傳值的時候找不到對應的key。

繼續往下分析:

mybatis-4 mybatis與spring結合使用及原理解析

已發帖子詢問大神具體是什么原因導致不進入124行,等大佬們回答后我將公布結果。直接看看executor是什么鬼

是一個接口,https://blog.csdn.net/ykzhen2015/article/details/50315027

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
protected set<beandefinitionholder> doscan(string... basepackages) {
 assert.notempty(basepackages, "at least one base package must be specified");
 set<beandefinitionholder> beandefinitions = new linkedhashset();
 string[] var3 = basepackages;
 int var4 = basepackages.length;
 for(int var5 = 0; var5 < var4; ++var5) {
  string basepackage = var3[var5];
  set<beandefinition> candidates = this.findcandidatecomponents(basepackage);
  iterator var8 = candidates.iterator();
  while(var8.hasnext()) {
  beandefinition candidate = (beandefinition)var8.next();
  scopemetadata scopemetadata = this.scopemetadataresolver.resolvescopemetadata(candidate);
  candidate.setscope(scopemetadata.getscopename());
  string beanname = this.beannamegenerator.generatebeanname(candidate, this.registry);
  if (candidate instanceof abstractbeandefinition) {
   this.postprocessbeandefinition((abstractbeandefinition)candidate, beanname);
  }
  if (candidate instanceof annotatedbeandefinition) {
   annotationconfigutils.processcommondefinitionannotations((annotatedbeandefinition)candidate);
  }
  if (this.checkcandidate(beanname, candidate)) {
   beandefinitionholder definitionholder = new beandefinitionholder(candidate, beanname);
   definitionholder = annotationconfigutils.applyscopedproxymode(scopemetadata, definitionholder, this.registry);
   beandefinitions.add(definitionholder);
   this.registerbeandefinition(definitionholder, this.registry);
  }
  }
 }
 return beandefinitions;
 }

關于mybatis中的executor與一級緩存的關系:

這里引出一個經典問題,關于mybatis一級緩存問題,這個緩存存儲在session中,當sql關閉的時候就會自動銷毀,涉及到mybatis中的session生命周期問題

為什么mybatis與spring結合后一級緩存會失效?以為sqlsession是由sqlsessionfactorybean生成,二這個sqlsessionfactorybean是由spring管理,也就是此時的session是由spring進行管理的并不是mybatis管理,所以此時session緩存會失效。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public interface executor {
 resulthandler no_result_handler = null;
 int update(mappedstatement var1, object var2) throws sqlexception;
 <e> list<e> query(mappedstatement var1, object var2, rowbounds var3, resulthandler var4, cachekey var5, boundsql var6) throws sqlexception;
 <e> list<e> query(mappedstatement var1, object var2, rowbounds var3, resulthandler var4) throws sqlexception;
 <e> cursor<e> querycursor(mappedstatement var1, object var2, rowbounds var3) throws sqlexception;
 list<batchresult> flushstatements() throws sqlexception;
 void commit(boolean var1) throws sqlexception;
 void rollback(boolean var1) throws sqlexception;
 cachekey createcachekey(mappedstatement var1, object var2, rowbounds var3, boundsql var4);
 boolean iscached(mappedstatement var1, cachekey var2);
 void clearlocalcache();
 void deferload(mappedstatement var1, metaobject var2, string var3, cachekey var4, class<?> var5);
 transaction gettransaction();
 void close(boolean var1);
 boolean isclosed();
 void setexecutorwrapper(executor var1);
}

mybatis-spring依賴中mapperscannerregistrar的作用:registerbeandefinitions方法中的doscan()此方法是將mapper掃描到初始化中。原理就是獲取到項目路徑找到對應的classes路徑,獲取了com.dao包名,將獲取的路徑+包名轉成文件夾,循環獲取文件夾下面的文件(userdao.class),然后使用將userdao拿到。此時包名+類名都拿到后使用class.forname(包名+類名)反射出對象,進行bean注冊

總結運行原理:

  初始化信息(數據庫連接信息,掃描mapper包中的class用于創建bean對象,spring中的類applicationfactory用于創建變對象、mapper中的xml的id與sql放到mapperstatement對象中)
      其中對于掃描mapper包中的class路徑+參數basepackages轉成文件夾,然后循環找到所有的類名,使用.......(請看mapperscannerregistrar引出的doscan方法)

  執行過程:根據sqlsessionfactorybean創建出sqlsession,調用selectlist方法,之后根據參數(namespacename+id)作為key找到mapperstatement對象中存儲的value獲取到sql語句,再有executor(mybatis默認使用                               cacheexecutor)執行sql語句查詢出結果集

原文鏈接:https://www.cnblogs.com/gnwzj/p/10680940.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产成人福利免费视频 | 午夜精品久久久久久中宇 | 欧美一区二区三区久久久 | evelynlin亚裔播放 | 日朝欧美亚洲精品 | 五月天婷婷网亚洲综合在线 | 日本国产最新一区二区三区 | 国产东北三老头伦一肥婆 | 欧美亚洲另类综合 | 成人免费毛片一区二区三区 | 国产成人一区二区三区在线视频 | 毛片手机在线视频免费观看 | 亚州精品视频 | 天天操天天舔 | 久久精品成人免费看 | 日本欧美一二三区色视频 | 艾秋麻豆果冻传媒老狼仙踪林 | 成年人视频在线 | 色欧美亚洲 | 国产一区精品视频 | 国产精品露脸国语对白河北 | 日本免费三片在线播放 | 国产91短视频 | 亚洲欧美日韩在线观看看另类 | 日韩porn| 久久日本片精品AAAAA国产 | 午夜精品久久久久久久99 | 青青视频国产依人在线 | 非洲黑人又大粗gay 非洲黑人bbwbbwbbw | yy6080欧美三级理论 | 久久热在线视频精品店 | 高清视频在线播放 | 日本加勒比在线精品视频 | 国产成人精品777 | 日韩视频在线免费观看 | 欧美国产日韩综合 | 国产成人免费高清激情视频 | 麻豆天美精东果冻传媒在线 | 欧美日韩精品亚洲精品v18 | 69p69国产精品 | 91亚色视频在线观看 |