中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Mybatis接口式編程的原理

發布時間:2020-10-07 00:11:31 來源:腳本之家 閱讀:219 作者:Terence_Jing 欄目:編程語言

Mybatis 有兩種實現方式

其一:通過xml配置文件實現

其二:面向接口編程的實現

           前者原理在Mybatis運行套路里面大致說了一下,此節說的是后者,面向接口的編程,可以解決掉 namespace / 傳入參數 / 返回值 / 與Sql關聯Id 等四處風險

           意思就是,Mybatis配置文件Dao.xml找了一個接口作為自己的代言人,并告訴其他的Java對象,以后訪問數據庫不要再騷擾我這個Dao.xml文件了,你去找我的代言人助理它會全權負責的。

           如果接口助理要全權負責Dao.xml文件的所有工作,那么,Dao.xml文件肯定要和代言接口交接清楚工作任務,不能然接口亂搞。

仍舊以訪問數據庫信息列表為例:

首先要定義一個接口IMessage和Dao.xml文件里面的各種配置項一一對應:

package hdu.terence.dao; 
import java.util.List; 
import hdu.terence.bean.Message; 
public interface IMessage { 
    publicList<Message> queryMessageList(Message message); 
} 

Dao.xml文件配置:

<?xml version="1.0"encoding="UTF-8"?> 
<!DOCTYPE mapper 
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
<mapper namespace="com.terence.dao.IMessage">  
 <resultMap type="hdu.terence.bean.Message" id="MessageResult">  
  <id column="id" jdbcType="INTEGER"property="id"/> <!--主鍵標簽--> 
  <result column="COMMAND" jdbcType="VARCHAR"property="command"/> 
  <result column="DESCRIPTION" jdbcType="VARCHAR" property="description"/> 
  <result column="CONTENT" jdbcType="VARCHAR"property="content"/> 
 </resultMap>   
 <select id="queryMessageList" parameterType="hdu.terence.bean.Message" resultMap="MessageResult"> 
  SELECTID,COMMAND,DESCRIPTION,CONTENT FROM message WHERE 1=1    
  <if test="command!=null and!"".equals(command.trim())"> 
  andCOMMAND=#{command} 
  </if> 
  <if test="description!=null and!"".equals(description.trim())"> 
  andDESCRIPTION like '%' #{description} '%' 
  </if>  
 </select><span > </span> 

測試:

public List<Message> queryMessageListByMybatis(Stringcommand,String description) 
  { 
    DBAccess dbAccess =new DBAccess(); 
    SqlSession sqlSession=null; 
    List<Message>messageList=new ArrayList<Message>(); 
    try { 
      sqlSession=dbAccess.getSqlSession(); 
      Message message=new Message(); 
      message.setCommand(command); 
      message.setDescription(description);           
      //方式二:通過接口調用配置文件里面的sql語句 
      IMessageimessage=sqlSession.getMapper(IMessage.class); 
      messageList=imessage.queryMessageList(message); 
    } catch (IOException e) { 
      e.printStackTrace(); 
    } 
    finally{ 
      if(sqlSession!=null) 
      { 
        sqlSession.close(); //要關閉數據庫會話 
      } 
    } 
    return messageList; 
  } 

            第一,Dao.xml文件命名空間要和接口的全名保持一致:寫接口的全名(包括報名com.terence.dao.IMessage)方便接口找到配置文件的命名空間。

            第二,接口定義代言的sql語句對應的方法:queryMessageList(),方法名要和代言的sql語句配置項的id:queryMessageList相同,方便接口根據自己聲明的方法映射到對應的配置項id。

            第三,接口聲明的方法帶入的形參Message要和Dao.xml文件對應配置項需要的參數保持一致。

            第四,接口聲明的方法的返回值類型List<Message>要和Dao.xml文件id配置項resultMap類型一致。

            這樣就完成了接口的代理工作,配置文件會告訴其他的Java代碼,以后通過這個接口就可以完成我本來要完成的工作,執行Sql語句對數據庫完成交互工作;很明顯,這種接口式編程比以前的直接調用配置文件方便多了,以前直接調用配置文件,每次使用配置文件,都需要寫配置文件的命名空間、id、參數和返回值,這些地方有時候會手滑寫不一致,如果出錯,編譯器不會出現提示,開發者只能根據執行結果錯誤提示推敲錯誤的地方慢慢調試。如果使用接口式編程,通過將配置文件dao.xml和定義的接口一一匹配對應,通過接口代理配置文件,以后不管誰使用都可以直接調用接口下,不用管配置文件里面的命名空間和sql配置ID,調用接口時如果出錯,會自動提示,更有利于錯誤的查找。

            但是,如果僅僅在Mybatis中使用接口式編程,并沒有什么顯著的效果,但是當Mybatis遇到spring的時候,效果就顯著了。

            當Mybatis遇到Spring,Mybatis的核心配置文件Configuration.xml中連接數據庫的配置,就會取代了Spring中的DB層,Mybatis中的SqlSession會話將會托管給Spring,上述的MessageDao.xml部分帶入參數調用接口的部分都會托管給Spring的Service來完成。此時我們定義的IMessage接口將會替代原來的Dao層,此時的Dao層只剩下接口文件和JavaDao.xml配置文件. 

Mybatis接口式編程的原理

第一個問題,明天為什么接口Imssage.queryMessageList()沒有實現類,但是卻可以調用對應的方法?

            首先要有一個創建代理實例的類,類里面有個方法invoke();

MapperProxy implements InvocationHandler
{
 MapperProxy.invoke();
}

            當我們調用接口的時候,走的是Invoke()方法,會通過Proxy.NewProxyInstance()加載一個代理實例,實際上也就是通過sqlSession.getMapper()來獲取代理實例,即

sqlSession.getMapper()==Proxy.newProxyInstance(); 
IMessage imessage=sqlSession.getMapper(IMessage.class);
messageList=imessage.queryMessageList(message);

            這樣,即使IMessage自身沒有實現類,但是通過SqlSession的getMapper方法帶入接口類IMessage.class,就可以獲取一個IMessage類型的代理實例,很明顯,這里是泛型在起作用,帶入什么樣的類型,就得到一個什么類型的接口,原因是Mybatis已經利用泛型做了強轉了; 

第二個問題,既然是通過invoke()方法,它是怎么知道我們要調用sqlSession.selectList()方法?

            因為剛初始化sqlSession的時候,加載了Configuration.xml文件,并在改文件中加載了各個JavaDao.xml文件,而這個Configuration.xml文件對應了Mybatis中相關的類:Configuration,接口的全名稱在Invoke()方法里面都可以拿到, 接口全名稱.方法名==namespace.id,所以可以拿到配置文件中的查詢方法。 

SqlSession的獲取

public SqlSession getSqlSession() throws IOException 
{ 
    //1、通過配置文件獲取數據庫連接相關信息 
    Readerreader=Resources.getResourceAsReader("hdu/terence/config/Configuration.xml"); 
    //2、通過配置信息構建SqlSessionFactory 
    SqlSessionFactorySSF=newSqlSessionFactoryBuilder().build(reader); 
    //3、通過SqlSessionFactory打開數據庫會話 
    SqlSessionsqlSession=SSF.openSession(); 
    return sqlSession; } 

    SqlSession通過上述配置實現,首先通過Resources.getResourceAsReader(“配置文件路徑”)方法加載配置文件包裝一個reader對象,然后通過SqlSessionFactory這個接口帶入reader對象,獲取一個動態代理實例,即SqlSessionFactory會話工廠,通過會話工廠得到一個會話SqlSession().   

  其中,在獲取會話工廠獲取實例的時候,底層實現源碼是將帶入的參數read作為key,找到Map中對應的value值,即MapperProxyFactory。

以上所述是小編給大家介紹的Mybatis接口式編程的原理,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對億速云網站的支持!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

扎兰屯市| 德保县| 郁南县| 万年县| 昌乐县| 贞丰县| 石渠县| 开封县| 澜沧| 贵德县| 应城市| 赞皇县| 保康县| 梁河县| 和林格尔县| 龙门县| 怀来县| 永春县| 吉首市| 马尔康县| 新疆| 静乐县| 兰西县| 安溪县| 万荣县| 广灵县| 鲜城| 和硕县| 忻城县| 洞口县| 滕州市| 临猗县| 钟山县| 依兰县| 江川县| 云安县| 军事| 涪陵区| 南和县| 潼关县| 南陵县|