Mybatis所用的模式和快取

2021-10-10 17:27:55 字數 3845 閱讀 2277

inputstream in = resources.getresourceasstream("sqlmapconfig.xml");

//2.建立sqlsessionfactory工廠

sqlsessionfactorybuilder builder = new sqlsessionfactorybuilder();//建立工廠mybatis使用了構建者模式

sqlsessionfactory factory = builder.build(in);//builder就是構建者

//3.使用工廠生產sqlsession物件

sqlsession session1 = factory.opensession();//生產sqlsession使用了工廠模式,解耦

// sqlsession session2 = factory.opensession();

//4.使用sqlsession建立dao介面的**物件

//5.使用**物件執行方法

listusers = userdao1.findall();

for (user user : users)

概念解釋:假如你現在要蓋個廠子(汽車廠)。這個時候,如果自己去做,要考慮工人,蓋樓所需要的材料,工具,施工車等等...,會比較麻煩。此時我們一般會把這些事情承包給包工隊,讓包工隊去做這些事情,我們只需要告訴他們需求,最後給錢就可以了。

那麼,上面的**,sqlsessionfactorybuilder 就是構建者,相當於包工隊,它就負責去建立工廠,  sqlsessionfactory factory = builder.build(in); 就使用到了構建者模式,你只需要把錢塞給這個builder,就可以造出你所要的工廠,省事又省力。

sqlsession session1 = factory.opensession();//生產sqlsession使用了工廠模式,解耦
概念解釋:當你的廠子蓋完後,你就可以拿廠子去生產汽車,如果自己去做,就要考慮到汽車所需要的零件,材料,工人等等,那麼現在我不需要這些,我直接通過工廠模式來造車,過程我不管,你給我造出來就可以了,那麼sqlsession就是我想要的車。

opensession()方法就是造車的方法,我不管你咋造的,你造出來可以用就行。

概念解釋:當你把車子造出來之後,我要開,我現在懶的連車都不想開,不想開咋辦?找代駕,找個代駕幫我開。

public inte***ce iuserdao
此時代駕要幹的事情就是開車,開車是乙個動作,即方法,我們把我們所有需要的執行動作放在這個介面裡面。並且不需要自己建立物件,通過**物件去執行方法,就可以完成了我們所需要的功能。

為什麼要生產**物件去執行方法呢?為什麼要使用**模式?

假設你有一套房子要賣,一種方法是你直接去網上發布**資訊,然後直接帶要買房子的人來看房子、過戶等一直到房子賣出去,但是可能你很忙,你沒有時間去處理這些事情,所以你可以去找中介,讓中介幫你處理這些瑣碎事情,中介實際上就是你的**。本來是你要做的事情,現在中介幫助你一一處理,對於買方來說跟你直接交易跟同中介直接交易沒有任何差異,買方甚至可能覺察不到你的存在,這實際上就是**的乙個最大好處。

接下來我們再深入考慮一下為什麼你不直接買房子而需要中介?其實乙個問題恰恰解答了什麼時候該用**模式的問題。

原因一:你可能在外地上班,買房子的人沒法找到你直接交易。

對應到我們程式設計的時候就是:客戶端無法直接操作實際物件。那麼為什麼無法直接操作?一種情況是你需要呼叫的物件在另外一台機器上,你需要跨越網路才能訪問,如果讓你直接去呼叫,你需要處理網路連線、處理打包、解包等等非常複雜的步驟,所以為了簡化客戶端的處理,我們使用**模式,在客戶端建立乙個遠端物件的**,客戶端就像呼叫本地物件一樣呼叫該**,再由**去跟實際物件聯絡,對於客戶端來說可能根本沒有感覺到呼叫的東西在網路另外一端,這實際上就是web service的工作原理。另一種情況雖然你所要呼叫的物件就在本地,但是由於呼叫非常耗時,你怕影響你正常的操作,所以特意找個**來處理這種耗時情況,乙個最容易理解的就是word裡面裝了很大一張,在word被開啟的時候我們肯定要載入裡面的內容一起開啟,但是如果等載入完這個大再開啟word使用者等得可能早已經跳腳了,所以我們可以為這個設定乙個**,讓**慢慢開啟這個而不影響word本來的開啟的功能。申明一下我只是猜可能word是這麼做的,具體到底怎麼做的,俺也不知道。

原因二:你不知道怎麼辦過戶手續,或者說除了你現在會幹的事情外,還需要做其他的事情才能達成目的。

對應到我們程式設計的時候就是:除了當前類能夠提供的功能外,我們還需要補充一些其他功能。最容易想到的情況就是許可權過濾,我有乙個類做某項業務,但是由於安全原因只有某些使用者才可以呼叫這個類,此時我們就可以做乙個該類的**類,要求所有請求必須通過該**類,由該**類做許可權判斷,如果安全則呼叫實際類的業務開始處理。可能有人說為什麼我要多加個**類?我只需要在原來類的方法裡面加上許可權過濾不就完了嗎?在程式設計中有乙個類的單一性原則問題,這個原則很簡單,就是每個類的功能盡可能單一。為什麼要單一,因為只有功能單一這個類被改動的可能性才會最小,就拿剛才的例子來說,如果你將許可權判斷放在當前類裡面,當前這個類就既要負責自己本身業務邏輯、又要負責許可權判斷,那麼就有兩個導致該類變化的原因,現在如果許可權規則一旦變化,這個類就必需得改,顯然這不是乙個好的設計。

mybatis提供查詢快取,如果快取中有資料,就不用從資料庫中獲取,用於減輕資料壓力,提高系統效能

一級快取是sqlsession級別的快取,在運算元據庫的時候,需要構造sqlsession物件,在物件中有乙個資料結構(hashmap)用於儲存快取資料。不同的sqlsession的快取區域(hashmap)是互相不受影響的。

mybatis預設是支援一級快取的。

1.1.證明一級快取的存在:

驗證方法:

public void testonelevelcache()
測試結果:

同時通過測試,當在第二次查詢的時候,向資料庫提交資料後,就會對快取進行重新整理,這樣在第二次查詢的時候就沒有走快取,而是走的資料庫。

2.2.禁用二級快取

由於二級快取預設是關閉的,如果不開啟就不會使用二級快取。如果,我們開啟了二級快取,而在有些查詢結果集中,不需要受到二級快取影響,該怎麼去做呢?

在select查詢中,預設是使用了二級快取,如果不想使用二級快取,就在select標籤中有乙個usecache的屬性設定為false,就代表不使用二級快取,每次進行查詢資料都不會從快取總獲取,而是直接從資料庫中進行查詢。usecache的預設值是true,即代表statement使用二級快取。

2.3.重新整理二級快取

在statement中設定flushcache=true,可以重新整理二級快取。預設情況下,select語句中的flushcache是false。如果是insert、update、delete語句,那麼flushcache的預設值是true。如果將select語句中的flushcache值改為true,就意味著查詢語句的二級快取失效,每次查詢都會從資料庫進行查詢。如果將select語句的flushcache值為false,就代表該查詢語句使用了二級快取,如果在資料庫中修改了資料,而二級快取中的資料還是原來的資料,那麼這樣就會出現髒讀。

flushcache設定如下:

mybatis 事務和快取

即session快取,作用域為 session,當 session flush 或 close 之後,該session中的所有 cache 就將清空,預設開啟。在業務層執行方法時,我們通常會在方法上加事務註解 transactional,這樣的話進入方法時,就會從資料庫連線池拿取鏈結資訊,建立連線,...

Mybatis的延遲載入和快取

1.mybatis中的延遲載入,也稱為懶載入,是指在進行關聯查詢時,按照設定延遲載入規則推遲對關聯物件的select查詢。延遲載入可以有效的減少資料庫壓力。注意 mybatis的延遲載入只是對關聯物件的查詢有延遲設定,對於主載入物件都是直接執行查詢語句的。2.mybatis根據對關聯物件查詢的sel...

Mybatis懶載入和快取機制

mybatis的配置快取機制和懶載入 二級快取的侷限性 在乙個物件更新後,無法更新其他同乙個namespace中的物件,並且會清空。二級快取以namespace劃分。一級快取 在同乙個sqlsession中兩次執行相同的sql語句,第一次執行完畢會將資料庫中查詢的資料寫到快取 記憶體 第二次會從快取...