您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關Java持久層面試題目有哪些的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
什么是ORM?
對象關系映射(Object-Relational Mapping,簡稱ORM)是一種為了解決程序的面向對象模型與數據庫的關系模型互不匹配問題的技術;
簡單的說,ORM是通過使用描述對象和數據庫之間映射的元數據(在Java中可以用XML或者是注解),將程序中的對象自動持久化到關系數據庫中或者將關系數據庫表中的行轉換成Java對象,其本質上就是將數據從一種形式轉換到另外一種形式。
Hibernate中SessionFactory是線程安全的嗎?Session是線程安全的嗎(兩個線程能夠共享同一個Session嗎)?
SessionFactory對應Hibernate的一個數據存儲的概念,它是線程安全的,可以被多個線程并發訪問。SessionFactory一般只會在啟動的時候構建。對于應用程序,最好將SessionFactory通過單例模式進行封裝以便于訪問。
Session是一個輕量級非線程安全的對象(線程間不能共享session),它表示與數據庫進行交互的一個工作單元。Session是由SessionFactory創建的,在任務完成之后它會被關閉。Session是持久層服務對外提供的主要接口。
Session會延遲獲取數據庫連接(也就是在需要的時候才會獲取)。為了避免創建太多的session,可以使用ThreadLocal將session和當前線程綁定在一起,這樣可以讓同一個線程獲得的總是同一個session。
Hibernate 3中SessionFactory的getCurrentSession()方法就可以做到。
Session的save()、update()、merge()、lock()、saveOrUpdate()和persist()方法分別是做什么的?有什么區別?
Hibernate的對象有三種狀態:瞬時態(transient)、持久態(persistent)和游離態(detached)。
瞬時態的實例可以通過調用save()、persist()或者saveOrUpdate()方法變成持久態;
游離態的實例可以通過調用 update()、saveOrUpdate()、lock()或者replicate()變成持久態。save()和persist()將會引發SQL的INSERT語句,而update()或merge()會引發UPDATE語句。
save()和update()的區別在于一個是將瞬時態對象變成持久態,一個是將游離態對象變為持久態。merge()方法可以完成save()和update()方法的功能,它的意圖是將新的狀態合并到已有的持久化對象上或創建新的持久化對象。
對于persist()方法,按照官方文檔的說明:
1、persist()方法把一個瞬時態的實例持久化,但是并不保證標識符被立刻填入到持久化實例中,標識符的填入可能被推遲到flush的時間;
2、persist()方法保證當它在一個事務外部被調用的時候并不觸發一個INSERT語句,當需要封裝一個長會話流程的時候,persist()方法是很有必要的;
3、save()方法不保證第2條,它要返回標識符,所以它會立即執行INSERT語句,不管是在事務內部還是外部。
至于lock()方法和update()方法的區別,update()方法是把一個已經更改過的脫管狀態的對象變成持久狀態;lock()方法是把一個沒有更改過的脫管狀態的對象變成持久狀態。
闡述Session加載實體對象的過程。
1、Session在調用數據庫查詢功能之前,首先會在一級緩存中通過實體類型和主鍵進行查找,如果一級緩存查找命中且數據狀態合法,則直接返回;
2、如果一級緩存沒有命中,接下來Session會在當前NonExists記錄(相當于一個查詢黑名單,如果出現重復的無效查詢可以迅速做出判斷,從而提升性能)中進行查找,如果NonExists中存在同樣的查詢條件,則返回null;
3、如果一級緩存查詢失敗查詢二級緩存,如果二級緩存命中直接返回;
4、如果之前的查詢都未命中,則發出SQL語句,如果查詢未發現對應記錄則將此次查詢添加到Session的NonExists中加以記錄,并返回null;
5、根據映射配置和SQL語句得到ResultSet,并創建對應的實體對象;
6、將對象納入Session(一級緩存)的管理;
7、如果有對應的攔截器,則執行攔截器的onLoad方法;
8、如果開啟并設置了要使用二級緩存,則將數據對象納入二級緩存;
9、返回數據對象。
#將傳入的數據都當成一個字符串,會對傳入的數據自動加上引號;
$將傳入的數據直接顯示生成在SQL中。
注意:使用$占位符可能會導致SQL注射攻擊,能用#的地方就不要使用$,寫order by子句的時候應該用$而不是#。
解釋一下MyBatis中命名空間(namespace)的作用。
在大型項目中,可能存在大量的SQL語句,這時候為每個SQL語句起一個唯一的標識(ID)就變得并不容易了。
為了解決這個問題,在MyBatis中,可以為每個映射文件起一個唯一的命名空間,這樣定義在這個映射文件中的每個SQL語句就成了定義在這個命名空間中的一個ID。
只要我們能夠保證每個命名空間中這個ID是唯一的,即使在不同映射文件中的語句ID相同,也不會再產生沖突了。
MyBatis中的動態SQL是什么意思?
對于一些復雜的查詢,我們可能會指定多個查詢條件,但是這些條件可能存在也可能不存在,如果不使用持久層框架我們可能需要自己拼裝SQL語句,不過MyBatis提供了動態SQL的功能來解決這個問題。MyBatis中用于實現動態SQL的元素主要有:
- if - choose / when / otherwise - trim - where - set - foreach
用法舉例:
<select id="foo" parameterType="Blog" resultType="Blog"> select * from t_blog where 1 = 1 <if test="title != null"> and title = #{title} </if> <if test="content != null"> and content = #{content} </if> <if test="owner != null"> and owner = #{owner} </if> </select>
JDBC編程有哪些不足之處,MyBatis是如何解決這些問題的?
1、JDBC:數據庫鏈接創建、釋放頻繁造成系統資源浪費從而影響系統性能,如果使用數據庫鏈接池可解決此問題。
MyBatis:在SqlMapConfig.xml中配置數據鏈接池,使用連接池管理數據庫鏈接。
2、JDBC:Sql語句寫在代碼中造成代碼不易維護,實際應用sql變化的可能較大,sql變動需要改變java代碼。
MyBatis:將Sql語句配置在XXXXmapper.xml文件中與java代碼分離。
3、JDBC:向sql語句傳參數麻煩,因為sql語句的where條件不一定,可能多也可能少,占位符需要和參數一一對應。
MyBatis: Mybatis自動將java對象映射至sql語句。
4,JDBC:對結果集解析麻煩,sql變化導致解析代碼變化,且解析前需要遍歷,如果能將數據庫記錄封裝成pojo對象解析比較方便。
MyBatis:Mybatis自動將sql執行結果映射至java對象。
MyBatis與Hibernate有哪些不同?
1、Mybatis和hibernate不同,它不完全是一個ORM框架,因為MyBatis需要程序員自己編寫Sql語句,不過mybatis可以通過XML或注解方式靈活配置要運行的sql語句,并將java對象和sql語句映射生成最終執行的sql,最后將sql執行的結果再映射生成java對象。
2、Mybatis學習門檻低,簡單易學,程序員直接編寫原生態sql,可嚴格控制sql執行性能,靈活度高,非常適合對關系數據模型要求不高的軟件開發,例如互聯網軟件、企業運營類軟件等,因為這類軟件需求變化頻繁,一但需求變化要求成果輸出迅速。
但是靈活的前提是mybatis無法做到數據庫無關性,如果需要實現支持多種數據庫的軟件則需要自定義多套sql映射文件,工作量大。
3、Hibernate對象/關系映射能力強,數據庫無關性好,對于關系模型要求高的軟件(例如需求固定的定制化軟件)如果用hibernate開發可以節省很多代碼,提高效率。
但是Hibernate的缺點是學習門檻高,要精通門檻更高,而且怎么設計O/R映射,在性能和對象模型之間如何權衡,以及怎樣用好Hibernate需要具有很強的經驗和能力才行。
總之,按照用戶的需求在有限的資源環境下只要能做出維護性、擴展性良好的軟件架構都是好架構,所以框架只有適合才是最好。
(這里也可以結合自己的理解說,別說的收不住)
簡單的說一下MyBatis的一級緩存和二級緩存?
Mybatis首先去緩存中查詢結果集,如果沒有則查詢數據庫,如果有則從緩存取出返回結果集就不走數據庫。Mybatis內部存儲緩存使用一個HashMap,key為hashCode+sqlId+Sql語句。value為從查詢出來映射生成的java對象
Mybatis的二級緩存即查詢緩存,它的作用域是一個mapper的namespace,即在同一個namespace中查詢sql可以從緩存中獲取數據。二級緩存是可以跨SqlSession的。
感謝各位的閱讀!關于“Java持久層面試題目有哪些”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。