hibernate以及mybatis的緩存、預編譯、延遲加載(也就是懶加載)和批處理的含義和區別

說到這幾個概念,不知道大家有沒有和我一樣的感覺,剛開始學習框架的時候總是傻傻的分不清,甚至在剛學習jdbc的PreparedStatement的時候,就只知道它是預編譯的,更加安全,效率更高。並不知道爲什麼。但是在這篇文章中,我將嘗試着將這幾個概念和其中的原理描述出來,如果我有什麼不對的地方,請大家幫我提出來,

首先從最開始的時候開始吧

            預編譯:預編譯的原理就是先將一個帶佔位符的SQL語句,發送到數據庫的緩存中去,但是不執行,然後等到用戶或者將佔位符替換成變量並且執行的時候在從數據庫的緩存中拿出來進行DQL,或者DML操作,這樣不用每次改變條件的時候都要發送一次SQL語句,實現了一次發送動態修改。並且還防止了SQL注入的風險

            

			String sql = "insert into emp values(?,?)";
			PreparedStatement ps =conn.prepareStatement(sql);//發送到數據庫緩存
			ps.setString(1, emp.getEname());//替換變量
			ps.setString(2, emp.getJob());
                        ps.executeUpdate();//執行操作

        批處理:所謂批處理,就是一次執行很多個SQL語句,並不是一次一次的執行,原理也是將多個SQL語句發送到數據庫緩存中,然後執行的時候,一次執行所欲的sql語句,這樣的話,減少了操作數據庫的次數,減輕了數據庫的壓力,自然速度就變快了

        hibernate和mybaits中的緩存:、

    一級緩存就是在一個連接對象中,hibernate是session,mybaits是sqlsession,就拿session來代替這兩個了,在session中有一個hashmap的數據結構,當你第一次查詢數據的時候,把查到的數據放到這個hashmap中,這個hashmap就是,一級緩存,當第二次查詢同樣的數據的時候,就不會向數據庫發送SQL語句了,而是直接從這個hashmap中查到數據,並且顯示出來,但是這裏面有一個問題就是,當我們進行DML操作,也就是增刪改的時候,數據表中的數據查詢到的數據就會變化,此時hashmap中的數據可能是不對的,也就是我們通常稱爲的髒讀,所以在這兩個框架的中,當進行DML操作的時候,session中的hashmap的數據就會清空。二級緩存是什麼呢?二級緩存通常是dao類或者mapper對象,將查到的數據序列化到硬盤上面,然後就是同樣的道理了

        延遲加載

                我們都知道在做項目的時候,通常會寫實體類,而實體類就避免不了有多表關聯的情況,比如一個表中有一個外鍵,這個外鍵關聯另一個表的主鍵,那麼在Java程序中怎麼表示這種關係呢?就是在一個實體類中存在另一個實體類,在另一個實體類中存在這個類的集合。比如user類和order(訂單)類,一個user中可以含有多個訂單,一個訂單隻能被一個用戶所擁有,這是典型的多表關聯,當我們查詢訂單所屬的用戶的時候,這個時候就會進行關聯查詢。那麼在數據庫中該怎麼寫呢?寫個簡單的例子把:select user.*,orders.* from user,orders where user.uid = orders.uid 。這就得到了兩張表的信息,然後將其分別封裝到兩個Java類中,就得到了訂單所屬的用戶,可是這怎麼實現延遲加載呢?答案是這種方式不能實現延遲加載,只不過通常我們的思維是這樣的,而延遲加載在數據庫中所執行的SQL語句應該是這樣的,select orders.*, (select user.* from user where orders.uid=user.uid) from orders;這個時候該是延遲加載上場的時候了,我們先查詢訂單select orders.* from orders,如果使用者需要用戶的信息,在進行查詢 select user.* from user where orders.uid=user.uid,如果暫時不需要,那麼這句話就免了,即不查詢了,這不就減少了一查詢操作了嗎,就沒必要將orders類中user對象也封裝了。如此就可以高度利用數據庫了




發佈了40 篇原創文章 · 獲贊 38 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章