1. 程式人生 > >**Mybatis框架 筆記二[共四篇,史上最全重點]*

**Mybatis框架 筆記二[共四篇,史上最全重點]*

今日目標

1.回顧mybaits的自定義再分析和環境搭建+完善註解的mybaits
2.mybatis的curd(基於代理dao的方式)
3.mybatis中的引數深入及結果集的深入
4.mybaitis中基於傳統dao的方式(編寫dao的實現類)   --瞭解的內容
5.mybatis中的配置(主配置檔案:SqlMapConfig.xml)
	* propertis標籤
	* typeAliases標籤
	* mappers標籤

回顧自定義框架

1.核心的點:IUserDao userdao=SqlSession.getMapper(IUserDao.class)   使用動態代理獲取一個實體類
2.我們自己實現的自定義框架裡面:sqlsession裡面有個selectList()-->做了真正連線資料庫的操作。
3.回顧自定義框架:
	>SqlSessionFactoryBuilder接收SqlMapConfig.xml檔案流,構建出SqlSessionFactory物件
	>SqlsessionFacotry讀取SqlMap---
	>...
4.環境搭建回顧:
	* 建立專案
	* 在pom.xml中匯入角標   [mybatis,mysql,junit,log4j]
	* 建立com.theima.domain.User實體類,繼承Serializable序列化介面
	* 配置resources根目錄的SqlMapConfig.xml       [配置總環境environments,mysql環境environment,事務transactionManger,連線池dataSource,配置對映檔案地址 resource]
	* 建立com.iheima.dao.IUserdao持久層介面IUSerDao
	* 建立Resources下的com.itheima.dao三層目錄包路徑下的IUserDao.xml配置檔案,並編寫select標籤的查詢語句
	* 建立test下的java.com.itheima.dao.mybatisTest的testFindAll()方法,對對應位置的IUserDao介面的findAll方法進行測試。

mybaits day_2 start

1.saveUser  儲存使用者
	* before 用於在測試方法執行之前執行
	* after 用於在測試方法執行之後執行
	* 所以在測試類中,可以將一些初始化的方法和釋放資源的方法進行提取,如init和destory方法。
	* 在測試完之後需要提交事務,末尾新增或者提取到destory方法:sqlsession.commit();如果在新增刪除修改等操作中,如果沒有提交事務,則會沒有儲存到資料庫中,因為事務是預設手動提交的。事務提交需要在資源關閉close之前。
	* 自動提交事務方法:Session session=factory.openSession(true);
	* select查詢語句中values中insert into user(username)values{#{username}}中username是引數名一致。如果引數名是大寫,那麼也就大寫。
2.updateUser 更新使用者
	* 語句:update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where...
	* (測試類中)執行儲存方法:userDao.updateUser      [先在測試類中建立實體類,再執行更新方法。]
3.根據ID刪除使用者
	* 語句:<delect id= "deleteUser" parameterType="java.lang.Integer/INT/int/Integer">
		* delect form user where id=#{id}		//id是一個佔位符可以隨便寫
		* </delect>
	* 執行刪除操作:userDao.delectUser(48);    //刪除id為48的使用者
	* 上面的其他方法是parameterType通過反射到物件的佔位符,所以不能隨便起名字,必須跟反射的物件屬性名字一一對應,而這裡的反射是到基本資料型別或者資料型別的包裝類中,所以不需要指定名字,這裡的id可以為其他名字都可以。
4.測試查詢一個方法:
	* 測試語句:User user =userDao.findById(30);

5.根據名稱模糊查詢資訊
	* 測試語句:List<User> users=userDao.findByName("%王%");
	* 在xml配置檔案查詢中可以使用'%#{value}%'  ,但是在實際開發中建議使用name佔位符,不用value,value是固定寫死,它是拼接字串,容易引發sql注入,不安全。

6.儲存中的細節:
	* keyProperty:User中的id;
	* keyColumn:資料庫中的id;
	* resultType:返回值;
	* order:在什麼時候執行。
	* 語句演示:
		* <insert id="saveUser" ParameterType="com.itheima.domain.User">
		* <selectKey KeyProperty="id" KeyColumn="id" resultType="int">
		* select last_insert_id();
		* </selectKey>
		* insert into user()...
		* </insert>
7.OGNL表示式
	* Object Graphic Navigation Language
	* 物件		圖		導航			語言
	* 它是通過物件的取值方法來獲取資料。在寫法上把get的方法忽略了。
	* 格式:物件.屬性名
8.內省機制:
	* domain實體類中必須設定set方法。java的內省機制,它可以將列名和類進行封裝,再通過反射與實體物件對應。
9.對映檔案中#號與$符號的區別:
		1. #{} 佔位符 prepareSatement 預編譯
			* ${value} 拼接字串		satment  拼接
			* "%"#{}"#"  可以將%放在這裡進行拼接。
		2. #{}和${}都是用來設定sql對映檔案中statement引數的佔位符,通過parameterType設定statemenet的引數型別,這裡可以有string字串、基本型別、pojo、map型別;
		3. 區別: 
			* 安全性:#..可以防止sql注入,$..只是進行內容拼接不能避免
			* 實現方式:#..是預編譯寫入  ,$.. 是拼接方式
			* 如果只是單純的設定引數就使用#{},而不用${}
			* 使用場景:
				* 表名是動態的: select* from ${value}
				* like查詢: select* from name like '%${value}%'
				* 列名是動態的:
				* 排序列是動態的: 
			* 總結:
				* 在操作確定資料型別的情況下使用#{}
				* 在操作不確定的資料型別的情況下使用${}
10.核心配置檔案中的配置問題:
	1.結果型別有三種:
		1.資料型別
		2.物件
		3.列表(眾多的資料型別或者物件)
	2.在Windows中mysql不區分大小寫,所以如果java中類屬性大小寫不一樣也能匹配;Linux中mysql嚴格區分大小寫。
	3.在IUserDao.xml中,執行sql語句如果與屬性引數對應不上的解決辦法:
		1.起別名: as;    執行效率高
		    * 將資料庫中的列名起別名,使之與實體類屬性一致。(執行效率最高,是從sql語句層面解決問題)
		2.採用配置的方式;  開發效率高
			*  在mapper標籤下新增標籤:   
			*  <resultMap id="userMap" type="com.itheima.domain.User">
			*  <id property="userId" column="id"></id>
			*  <result property="userName" column="username"></result>
			*  <result property="userAddress" column="address"></result>
			*  <result property="userSex" column="sex"></result>
			*  <result property="userBirthday" column="birthday"></result>
			*  </resultMap>
			*  同時:select標籤新增:resultMap="userMap"屬性;
			*  雖然這個方法執行效率不高,但是隻需要在上面配置好了,後面的每個select標籤只需要新增resultMap屬性即可,效率很高!
			*  property代表實體類,column代表資料庫
		3.實體類和資料庫屬性命名一致
	4.可以在configuration標籤內部配置連線資料庫的資訊,也可以通過屬性引入外部配置檔案資訊。
		1. resource屬性:用於指定配置檔案的位置,是按照類路徑的寫法來寫,並且必須存在於類路徑下。如:<properties resource="jdbcConfig.proties">  //這裡是放在resource路徑的根路徑下。[推薦]
		2. url屬性:是要求按照Url的下發來寫地址
			* URL:Uniform Resource Locator: 統一資源定位符。它是可以唯一標識一個資源的位置。
			* 它的寫法:
				* http://localHost:8080/mybatisserver/demo1Servlet
					協議		主機		埠		URI
		3. FIle協議:我們開啟的資源都是file協議的,file:///C:/Users/...
			* <properties url="file:///D:IdeaProjects/day02_eesy_01mybatisCRUD/src/main/resource/..."
11.傳統方式:寫實現類完成mybatis框架的持久層操作:
	1.實現類:
		* 在實現類中定義通過建構函式傳入的工廠類。
		* 在方法中使用工廠factory.openSession();獲取SqlSession物件session
		* 使用session.select...返回一個數據型別,物件或者列表
		* 釋放資源,返回結果
	2.在測試類中:
		* 讀取位元組碼檔案返回位元組碼inputStream
		* 使用構建者模式建立工廠factroy
		* 使用userDao呼叫實現類中的方法返回結果集
		* 列印結果
	3.注意:
		* session.insert("全限定類名",有值的實體類);這樣才能實現儲存使用者的操作。* session.fendByName("全限定類名",username);這裡通過名字查詢,則需要傳入名字進去。
		* 不帶條件的即可不需要傳入值。
12.使用代理Dao以及使用dao實現類的方式的區別
	1.sqlSession.getMapper(IUserDao.class)
	2.sqlSession.selectList()
	3.一些技巧:
		* ctrl+H 可以檢視一個類的繼承結構
		* 找到某一個類的快捷鍵:Double Shift  (Double就是按兩下)
		* 快速找到方法:Ctrl+F12
13.標籤:
	1. 起別名
		1. 使用typeAliases配置別名,它只能配置domain中類的別名:
			* <typeAliases>
			*	//方法一: <typeAlias type="com.itheima.domain.User" alias="User">
			* //方法二: <package name="com.itheima.domain"></package>
			* </typeAlias>
			* </typeAliases>
		2. 使用package,用於指定要配置別名的包,當包指定之後,這個可以用於環境配置和mappers對映檔案位置的(package標籤是用於指定dao介面所在的包,當指定了之後即不需要寫mapper以及resource或者classes了)
			* 為什麼指定了就不用寫了呢? 因為使用package標籤指定了掃描的包,那麼該包下的所有的該型別檔案就不必要寫class和resource了,因為class是表示註解,resource表示xml檔案,如果有多個dao介面需要寫多個class或者resource型別的對映配置,如果有了package就只需要寫一次就夠了,因為package是面向包路徑,包含包下所有檔案,而其他是面向檔案的;

今日任務:

1. 使用代理dao的方式完成crud以及模糊查詢
2. 使用自己實現dao實現類的方式完成crud
3. 嘗試著理一遍原始碼的過程:代理dao以及實現類dao的方式