歷史就是一面鏡子
回顧自己開發的歷程,見證了時代變遷史記,下面我針對java連接數據庫的方式說起
0 原生jdbc
先普及下jdbc,怕新入行的人早已沉浸在包裝庫和框架中,甚至都沒用過原生jdbc。
Java數據庫連接,全稱是Java Database Connectivity,簡稱JDBC,是Java語言中用來規范客戶端程序如何來訪問數據庫的應用程序接口,提供了諸如查詢和更新數據庫中數據的方法。JDBC也是Sun Microsystems的商標。我們通常說的JDBC是面向關系型數據庫的。百科這樣解釋的Java數據庫連接。
開發人員要做的幾個步驟:
開發步驟:
1、注冊驅動.,告知JVM使用的是哪一個數據庫的驅動
2、獲得連接.,使用JDBC中的類,完成對MySQL數據庫的連接
3、獲得語句執行平台,通過連接對象獲取對SQL語句的執行者對象
4、執行sql語句,使用執行者對象,向數據庫執行SQL語句 獲取到數據庫的執行后的結果
5、處理結果
6、釋放資源.
注意寫代碼之前,要導入數據庫驅動包,連接不同廠商的數據庫要用不同的驅動包
對應的驅動包
新建項目,普通的java項目就行,導入第三方jar太簡單了,自行百度
示例代碼如下:
查詢結果
恩早期開發就是這么過來,只是自己封裝成了JDBC工具,於具體的業務開發人員要寫大量的SQL語句,調用時這樣的
看上去此種開發模式也很好,只要規模不大,此方式還很好,瓶頸在於數據庫連接,現在也不是問題了,社會在進步,池化技術出現了。
池化簡單點說就是預先連接好一定數量的連接,等需要時隨意從中選擇一個進行操作。略了,當時主要用的tomcat自帶的池化技術,此時獲取數據庫連接的代碼就變成了這樣核心偽代碼(tomcat要做些配置):
普及下JNDIhttps://baike.baidu.com/item/JNDI/3792442?fr=aladdin,現在也難見到了,很多框架越來越傻瓜式了
1. hibernate來了
Hibernate是一種ORM框架,全稱為 Object_Relative DateBase-Mapping,在Java對象與關系數據庫之間建立某種映射,以實現直接存取Java對象。
想不明白為啥沒有mybatis發展的好,看來拉攏技術人員搞社區還是很重要的。
很遺憾,沒有保留以前的老項目,沒有自己的電腦,也沒有申請github。
看了下網上已有很多教程了:https://www.w3cschool.cn/hibernate/skzl1idz.html,就不多說什么,重點關注架構、緩存、事務和攔截器。重點代碼
2. mybatis也來了,來的更猛
用的時間稍微長久些,沒辦法,誰讓它勢頭發展的好,也有大廠強烈支持。
mybatis簡介https://baike.baidu.com/item/MyBatis/2824918?fr=aladdin,算是hibernate的競爭者
我看網上也有了類似教程,MyBatis 教程 https://www.w3cschool.cn/mybatis/、
重點也是關注架構、緩存和事務
簡單demo如下:
配置文件三個如下
mybatis-config.xml
myBatisMapper.xml文件內容
數據庫配置mysql.properties
執行測試代碼效果:
注意配置型的文件不能放錯位置,要么就改加載屬性文件的代碼,記得導入數據庫驅動包和mybatis.jar
緩存分兩種,一級緩存和二級緩存。
一級緩存
一級緩存 Mybatis的一級緩存是指SQLSession,一級緩存的作用域是SQlSession, Mabits默認開啟一級緩存。 在同一個SqlSession中,執行相同的SQL查詢時;第一次會去查詢數據庫,並寫在緩存中,第二次會直接從緩存中取。 當執行SQL時候兩次查詢中間發生了增刪改的操作,則SQLSession的緩存會被清空。 每次查詢會先去緩存中找,如果找不到,再去數據庫查詢,然后把結果寫到緩存中。 Mybatis的內部緩存使用一個HashMap,
key為hashcode+statementId+sql語句。Value為查詢出來的結果集映射成的java對象。 SqlSession執行insert、update、delete等操作commit后會清空該SQLSession緩存。
幾種情況:
第一種情況:同個session進行兩次相同查詢
結論:MyBatis只進行1次數據庫查詢。
第二種情況:同個session進行兩次不同的查詢
結論:MyBatis進行兩次數據庫查詢。
第三種:不同session,進行相同查詢。
結論:MyBatis進行兩次數據庫查詢。
第四種情況:同個session,查詢之后更新數據,再次查詢相同的語句
直接下結論了:更新操作之后緩存會被清除
小結:一級緩存是SqlSession級別的緩存,Mybatis默認是開啟一級緩存的,當調用SqlSession的修改、添加、刪除、commit()、close()等方法時,就會清空一級緩存。
二級緩存
之所以稱之為“二級緩存”,是相對於“一級緩存”而言的。既然有了一級緩存,那么為什么要提供二級緩存呢?我們知道,在一級緩存中,不同session進行相同SQL查詢的時候,是查詢兩次數據庫的。顯然這是一種浪費,既然SQL查詢相同,就沒有必要再次查庫了,直接利用緩存數據即可,這種思想就是MyBatis二級緩存的初衷。
另外,Spring和MyBatis整合時,每次查詢之后都要進行關閉sqlsession,關閉之后數據被清空。所以MyBatis和Spring整合之后,一級緩存是沒有意義的。如果開啟二級緩存,關閉sqlsession后,會把該sqlsession一級緩存中的數據添加到mapper namespace的二級緩存中。這樣,緩存在sqlsession關閉之后依然存在。
默認情況下,MyBatis只啟用了本地的會話緩存,它僅僅對一個會話中的數據進行緩存,見: MyBatis一級緩存介紹 。要啟用全局的二級緩存,只需要在SQL映射文件中添加一行:
<cache/>
二級緩存是Mapper級別的緩存,多個SqlSession去操作同一個Mapper的sql語句,多個SqlSession可以共用二級緩存,二級緩存是跨SqlSession的。
上面這個簡單語句的效果如下:
映射語句文件中的所有 select 語句的結果將會被緩存。
映射語句文件中的所有 insert、update 和 delete 語句會刷新緩存。
緩存會使用最近最少使用算法(LRU, Least Recently Used)算法來清除不需要的緩存。
緩存不會定時進行刷新(也就是說,沒有刷新間隔)。
緩存會保存列表或對象的1024個引用。
緩存會被視為讀/寫緩存,這意味着獲取到的對象並不是共享的,可以安全地被調用者修改,而不干擾其他調用者或線程所做的潛在修改。
這些屬性可以通過 cache 元素的屬性來修改。比如:
這個更高級的配置創建了一個 FIFO 緩存,每隔 60 秒刷新,最多可以存儲結果對象或列表的 512 個引用,而且返回的對象被認為是只讀的,因此對它們進行修改可能會在不同線程中的調用者產生沖突。
可用的清除策略有:
LRU – 最近最少使用:移除最長時間不被使用的對象。
FIFO – 先進先出:按對象進入緩存的順序來移除它們。
SOFT – 軟引用:基於垃圾回收器狀態和軟引用規則移除對象。
WEAK – 弱引用:更積極地基於垃圾收集器狀態和弱引用規則移除對象。
默認的清除策略是 LRU。
flushInterval(刷新間隔)屬性可以被設置為任意的正整數,設置的值應該是一個以毫秒為單位的合理時間量。 默認情況是不設置,也就是沒有刷新間隔,緩存僅僅會在調用語句時刷新。
size(引用數目)屬性可以被設置為任意正整數,要注意欲緩存對象的大小和運行環境中可用的內存資源。默認值是 1024。
readOnly(只讀)屬性可以被設置為 true 或 false。只讀的緩存會給所有調用者返回緩存對象的相同實例。 因此這些對象不能被修改。這就提供了可觀的性能提升。而可讀寫的緩存會(通過序列化)返回緩存對象的拷貝。 速度上會慢一些,但是更安全,因此默認值是 false。
提示:二級緩存是事務性的。這意味着,當 SqlSession 完成並提交時,或是完成並回滾,但沒有執行 flushCache=true 的 insert/delete/update 語句時,緩存會獲得更新。
小結: 二級緩存是mapper映射級別的緩存,默認是不開啟的,多個SqlSession去操作同一個Mapper映射的sql語句是共用二級緩存的,二級緩存是跨SqlSession的。
框架前幾部分都是屬性文件解析,構造工廠,生產產品做真正的事
記一次使用mybatis使用出現的排序問題: ${}和 #{}的區別
由於開始時排序字段,特別是分頁查詢時,傳的參數有第幾頁,每頁幾條記錄,排序字段,是動態設置的,有時從前端傳來,按某些個字段排序
就是這個sortOrder
大致就這樣了,每個人都可以接着擴展開發。框架性迭代總是這樣,xml到json,sql寫在xml文件里到如今通過注解實現(spring也是如此,早期都是xml大量配置,如今也轉換到注解配置),框架越來越包裝了,願每個碼農都把基礎學好,再學框架,不要一上來就mybatis,據說新碼農都沒寫過原生servlet,更別提開發了。。。
總結:
自己早年封裝的jdbc組件,簡單易用,適合小規模化開發,主要當時技術受限,大量數據庫連接沒處理好,沒有池化和緩存策略,且對碼農的sql功底很強,其實面向SQL編程
hibernate,個人覺得一個很不錯得到orm框架,脫離了部分sql,只是沒推廣好
mybatis ,從架構上來說和hibernate雷同,生態圈建立的好,也有大廠光環。
匯總一句話:再好的orm,也脫離不了最最最基本的JDBC,勸扎進框架圈里的人,務必打好基礎,框架各有千秋,沒有最好,只要合適!!!
參考:
0. Develop Java applications with Oracle Database https://www.oracle.com/database/technologies/appdev/jdbc.html
2. JNDI數據庫連接池配置 https://www.iteye.com/blog/xiaoliang330-978823
4. Java Mybatis框架入門教程 http://c.biancheng.net/mybatis/
5. JDBC Example – MySQL, Oracle https://www.journaldev.com/2471/jdbc-example-mysql-oracle