關鍵字:ORM(對象/關系數(shù)據(jù)庫映射),反射,內(nèi)省,注解/配置文件,緩存,插件/自定義,延遲加載
雖然不是spring家的,但是ssm框架用到了,也算是個編外人員把。
持久層框架對JDBC進行封裝
原始的JDBC就像自己去超市購物
1.找去超市的車
Class.forName("com.mysql.jdbc.Driver");
2.進入超市
connection =DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "root");
3.看著媽媽的購物清單拿要買的東西
String sql = "select * from user where username = ?";
preparedStatement = connection.prepareStatement(sql);
4.結(jié)賬 ?
resultSet = preparedStatement.executeQuery();
5.分類放進冰箱
int id = resultSet.getInt("id"); String username = resultSet.getString("username");
user.setId(id);? user.setUsername(username);
6.躺回沙發(fā)上
preparedStatement.close();? connection.close();
原始jdbc開發(fā)存在的問題如下:
頻繁從沙發(fā)上起來躺下腰吃不消(連接/釋放頻繁),
寫死的購物清單(Sql語句在代碼中硬編碼,占位符固定,造成代碼不易維護),
回家后還要把菜分類儲存(如果能將數(shù)據(jù) 庫記錄封裝成pojo對象解析?較?便)
而Mybatis就像一個采購員
可以幫你解決這些問題
1.這個采購員有一輛車,可以開到任何想去的超市(核心配置文件,修改配置文件就可以連接不同的數(shù)據(jù)庫)
2.這個采購員有個對講機,方便的修改購物清單(sql語句寫在xml中)
3.這個采購員會將貨物分類放在冰箱(反射,內(nèi)省;出入?yún)?shù)都可以是POJO);
額外.可以添加插件或自定義插件,比如分頁。
采購專車(核心配置文件)
只需要給出目標,就可以去到不同超市。
將連接參數(shù)全部轉(zhuǎn)移到核心配置文件中,不需要再費力的修改java代碼。
先以數(shù)據(jù)流的方式讀取配置文件,再解析
基于 Java XPath 解析器


自動進貨的儲物箱(ORM映射,Mapper代理)
家里有個土豆儲物箱,采購員就會往里面加土豆,不需要過多的交流。
操作實體類等同于操作表
怎么樣通過操作儲物箱就可以拿到貨。
簡單的說:
建立mapper.xml和Dao之間的連接:核心配置文件->mapper包->mapper.xml->namespace->Dao;
實體類映射數(shù)據(jù)庫:Dao->方法->實體類(反射)->paramterType(入?yún)?->mapper.xml->resultType(出參)->實體類(反射)。
項目啟動時,通過ORM映射將mapper.xml中的sql語句和mapper中的接口方法關聯(lián)起來,有點像spring的IOC容器,這里叫javaBean容器,Mybatis會創(chuàng)建一個javaBean(說白了就是實體類帶上set,get和其他常用方法)來保存解析后的mapper.xml中的sql方法(語句和其他屬性)
是Map類型的,結(jié)構(gòu)是<namespace.id,javaBean>
在解析mappers標簽的時候

找到核心配置文件的mappers標簽,然后獲取里面package標簽中的name屬性,指向的是mapper.xml的位置(和Dao層文件結(jié)構(gòu)上一樣的)。

然后進入mapper.xml,通過namespace屬性和Dao層建立聯(lián)系

出參和入?yún)⑼ㄟ^配置文件的屬性反射User類,這樣就可以使用pojo來操作數(shù)據(jù)庫并且返回封裝好的pojo對象
反射方法Class.forName(“全限定類名”)

到這里就找到了namespace和id還有javaBean,可以添加進javaBean容器了。
簡單的說反射是拿類的方法,內(nèi)省是拿類的屬性。
Mapper代理
Mapper代理中增刪改方法處理都是類似的,他們都是更新操作

最終都是到這個方法

查詢就不一樣了,會根據(jù)方法返回值類型做不同處理,其實也就是包裝成那種類型的返回值。

發(fā)現(xiàn)一個小秘密,selectOne就是查全部返回第一條

儲物箱便利貼(注解開發(fā))
再買一次(緩存)
想補貨的時候又懶得在翻一遍商品頁面,這時候就可以再次下單。
SqlSession(mapper代理里用到的)是一級緩存
查詢條件會編碼后和查詢結(jié)果一起保存在一個HashMap中,如果條件相同會直接從緩存里取。有更新數(shù)據(jù)庫的操作(修改,刪除,添加)就會清空緩存。
默認是開啟的

?級緩存是基于mapper?件的namespace的
也就是多個SqlSession在操作同一個mapper時會共用一個緩存,任意一個SqlSession有更新操作也會清空這個緩存。
默認是關閉的。
?級緩存底層還是HashMap結(jié)構(gòu)。
二級緩存一般集群的時候用redis,有很好的兼容性
導入jar包

需要使用的mapper.xml里配置

隨時加單(延遲加載)
一車裝不下的東西可以要用到時候再去買
要用到的時候再加載,而不是一啟動就添加進緩存里。
局部延遲加載
resultMap標簽下的collection 標簽里的fetchType="lazy"
<collection property="orderList" ofType="com.xxx.pojo.Order" select="com.xxx.mapper.IOrderMapper.findOrderByUid" column="id" fetchType="lazy">
全局延遲加載
在Mybatis的核?配置?件中可以使?setting標簽修改全局的加載策略
