MyBatis-学习笔记03【03.自定义Mybatis框架】
- Java后端 學習路線 筆記匯總表【黑馬程序員】
目錄
1 自定義Mybatis的分析-執行查詢所有分析
2 自定義Mybatis的分析-創建代理對象的分析
3 自定義mybatis的編碼-根據測試類中缺少的創建接口和類
class Resources
class SqlSessionFactoryBuilder
interface SqlSessionFactory
interface SqlSession
4 自定義mybatis的編碼-解析XML的工具類介紹
導入dom4j的坐標
Configuration.java
Mapper
XMLConfigBuilder.java
5 自定義Mybatis的編碼-創建兩個默認實現類并分析類之間的關系
DefaultSqlSession.java
6 自定義Mybatis的編碼-實現基于XML的查詢所有操作
7 自定義Mybatis的編碼-實現基于注解配置的查詢所有
day01附錄
泛型術語
截圖
mybatis框架 共四天 第一天:mybatis入門mybatis的概述mybatis的環境搭建mybatis入門案例自定義mybatis框架(主要的目的是為了讓大家了解mybatis中執行細節) 第二天:mybatis基本使用mybatis的單表crud操作mybatis的參數和返回值mybatis的dao編寫mybatis配置的細節幾個標簽的使用 第三天:mybatis的深入和多表mybatis的連接池mybatis的事務控制及設計的方法mybatis的多表查詢一對多(多對一)多對多 第四天:mybatis的緩存和注解開發mybatis中的加載時機(查詢的時機)mybatis中的一級緩存和二級緩存mybatis的注解開發單表CRUD多表查詢 ----------------------------------------------------------- 1、什么是框架?它是我們軟件開發中的一套解決方案,不同的框架解決的是不同的問題。使用框架的好處:框架封裝了很多的細節,使開發者可以使用極簡的方式實現功能。大大提高開發效率。 2、三層架構表現層:是用于展示數據的業務層:是處理業務需求持久層:是和數據庫交互的 3、持久層技術解決方案JDBC技術:ConnectionPreparedStatementResultSetSpring的JdbcTemplate:Spring中對jdbc的簡單封裝Apache的DBUtils:它和Spring的JdbcTemplate很像,也是對Jdbc的簡單封裝以上這些都不是框架JDBC是規范Spring的JdbcTemplate和Apache的DBUtils都只是工具類 4、mybatis的概述mybatis是一個持久層框架,用java編寫的。它封裝了jdbc操作的很多細節,使開發者只需要關注sql語句本身,而無需關注注冊驅動,創建連接等繁雜過程它使用了ORM思想實現了結果集的封裝。ORM:Object Relational Mappging 對象關系映射簡單的說:就是把數據庫表和實體類及實體類的屬性對應起來讓我們可以操作實體類就實現操作數據庫表。user Userid userIduser_name userName今天我們需要做到:實體類中的屬性和數據庫表的字段名稱保持一致。user數據表 User實體類id iduser_name user_name 5、mybatis的入門mybatis的環境搭建第一步:創建maven工程并導入坐標第二步:創建實體類和dao的接口第三步:創建Mybatis的主配置文件 SqlMapConifg.xml第四步:創建映射配置文件 IUserDao.xml環境搭建的注意事項:第一個:創建IUserDao.xml 和 IUserDao.java時,名稱是為了和我們之前的知識保持一致。在Mybatis中它把持久層的操作接口名稱和映射文件也叫做:Mapper所以:IUserDao 和 IUserMapper是一樣的。(Mapper==Dao)第二個:在idea中創建目錄的時候,它和包是不一樣的包在創建時:com.itheima.dao是三級結構目錄在創建時:com.itheima.dao是一級目錄第三個:mybatis的映射配置文件位置必須和dao接口的包結構相同第四個:映射配置文件的mapper標簽namespace屬性的取值必須是dao接口的全限定類名第五個:映射配置文件的操作配置(select),id屬性的取值必須是dao接口的方法名好處:當我們遵從了第三、四、五點之后,我們在開發中就無須再寫dao的實現類。mybatis的入門案例第一步:讀取配置文件第二步:創建SqlSessionFactory工廠第三步:創建SqlSession第四步:創建Dao接口的代理對象第五步:執行dao中的方法第六步:釋放資源注意事項:不要忘記在映射配置中告知mybatis要封裝到哪個實體類中配置的方式:指定實體類的全限定類名 resultType="com.itheima.domain.User"mybatis基于注解的入門案例:把IUserDao.xml移除,在dao接口的方法上使用@Select注解,并且指定SQL語句同時需要在SqlMapConfig.xml中的mapper配置時,使用class屬性指定dao接口的全限定類名。明確(說明)-mybatis可寫dao實現類:我們在實際開發中,都是越簡便越好,所以都是采用不寫dao實現類的方式,不管使用XML配置還是使用注解配置。但是Mybatis它是支持寫dao實現類的。 6、自定義Mybatis的分析:mybatis在使用代理dao的方式實現增刪改查時做什么事呢?只有兩件事:第一:創建代理對象;第二:在代理對象中調用selectList。自定義mybatis能通過入門案例看到類class Resourcesclass SqlSessionFactoryBuilderinterface SqlSessionFactoryinterface SqlSession
1 自定義Mybatis的分析-執行查詢所有分析
6、自定義Mybatis的分析:
?? ?mybatis在使用代理dao的方式實現增刪改查時做什么事呢?
?? ??? ?只有兩件事:
?? ??? ??? ?第一:創建代理對象
?? ??? ??? ?第二:在代理對象中調用selectList
用什么語句執行,封裝到哪里去?
讀流,解析配置文件。
(E) 強轉類型
查詢所有的分析2 自定義Mybatis的分析-創建代理對象的分析
自定義mybatis分析3 自定義mybatis的編碼-根據測試類中缺少的創建接口和類
6、自定義Mybatis的分析:
?? ?自定義mybatis能通過入門案例看到類
?? ??? ?class Resources
?? ??? ?class SqlSessionFactoryBuilder
?? ??? ?interface SqlSessionFactory
?? ??? ?interface SqlSession
?
?自定義實現類的好處:實現靈活控制(每多一個方法,就可以多一些功能)!
class Resources
package com.itheima.mybatis.io;import java.io.InputStream;/*** 使用類加載器讀取配置文件的類*/ public class Resources {/*** 根據傳入的參數,獲取一個字節輸入流** @param filePath* @return*/public static InputStream getResourceAsStream(String filePath) {//Resources.class得到當前類的字節碼;getClassLoader()獲取字節碼的類加載器;//getResourceAsStream根據類加載器讀取配置return Resources.class.getClassLoader().getResourceAsStream(filePath);} }class SqlSessionFactoryBuilder
package com.itheima.mybatis.sqlsession;import com.itheima.mybatis.cfg.Configuration; import com.itheima.mybatis.sqlsession.defaults.DefaultSqlSessionFactory; import com.itheima.mybatis.utils.XMLConfigBuilder;import java.io.InputStream;/*** 用于創建一個SqlSessionFactory對象*/ public class SqlSessionFactoryBuilder {/*** 根據參數的字節輸入流來構建一個SqlSessionFactory工廠** @param config* @return*/public SqlSessionFactory build(InputStream config) {return null;} }interface SqlSessionFactory
package com.itheima.mybatis.sqlsession;public interface SqlSessionFactory {/*** 用于打開一個新的SqlSession對象** @return*/SqlSession openSession(); }interface SqlSession
package com.itheima.mybatis.sqlsession;/*** 自定義Mybatis中和數據庫交互的核心類* 它里面可以創建dao接口的代理對象*/ public interface SqlSession {/*** 根據參數創建一個代理對象** @param daoInterfaceClass dao的接口字節碼* @param <T>* @return*/<T> T getMapper(Class<T> daoInterfaceClass);/*** 釋放資源*/void close(); }4 自定義mybatis的編碼-解析XML的工具類介紹
導入dom4j的坐標
?
?
Configuration.java
Mapper
?
XMLConfigBuilder.java
package com.itheima.mybatis.utils;//import com.itheima.mybatis.annotations.Select;import com.itheima.mybatis.annotations.Select; import com.itheima.mybatis.cfg.Configuration; import com.itheima.mybatis.cfg.Mapper; import com.itheima.mybatis.io.Resources; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader;import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.HashMap; import java.util.List; import java.util.Map;/*** 用于解析配置文件*/ public class XMLConfigBuilder {/*** 解析主配置文件,把里面的內容填充到DefaultSqlSession所需要的地方* 使用的技術:* dom4j+xpath*/public static Configuration loadConfiguration(InputStream config) {try {//定義封裝連接信息的配置對象(mybatis的配置對象)Configuration cfg = new Configuration();//1.獲取SAXReader對象SAXReader reader = new SAXReader();//2.根據字節輸入流獲取Document對象Document document = reader.read(config);//3.獲取根節點Element root = document.getRootElement();//4.使用xpath中選擇指定節點的方式,獲取所有property節點List<Element> propertyElements = root.selectNodes("//property");//5.遍歷節點for (Element propertyElement : propertyElements) {//判斷節點是連接數據庫的哪部分信息//取出name屬性的值String name = propertyElement.attributeValue("name");if ("driver".equals(name)) {//表示驅動//獲取property標簽value屬性的值String driver = propertyElement.attributeValue("value");cfg.setDriver(driver);}if ("url".equals(name)) {//表示連接字符串//獲取property標簽value屬性的值String url = propertyElement.attributeValue("value");cfg.setUrl(url);}if ("username".equals(name)) {//表示用戶名//獲取property標簽value屬性的值String username = propertyElement.attributeValue("value");cfg.setUsername(username);}if ("password".equals(name)) {//表示密碼//獲取property標簽value屬性的值String password = propertyElement.attributeValue("value");cfg.setPassword(password);}}//取出mappers中的所有mapper標簽,判斷他們使用了resource還是class屬性List<Element> mapperElements = root.selectNodes("//mappers/mapper");//遍歷集合for (Element mapperElement : mapperElements) {//判斷mapperElement使用的是哪個屬性Attribute attribute = mapperElement.attribute("resource");if (attribute != null) {System.out.println("使用的是XML");//表示有resource屬性,用的是XML//取出屬性的值String mapperPath = attribute.getValue();//獲取屬性的值"com/itheima/dao/IUserDao.xml"//把映射配置文件的內容獲取出來,封裝成一個mapMap<String, Mapper> mappers = loadMapperConfiguration(mapperPath);//給configuration中的mappers賦值cfg.setMappers(mappers);} else {System.out.println("使用的是注解");//表示沒有resource屬性,用的是注解//獲取class屬性的值String daoClassPath = mapperElement.attributeValue("class");//根據daoClassPath獲取封裝的必要信息Map<String, Mapper> mappers = loadMapperAnnotation(daoClassPath);//給configuration中的mappers賦值cfg.setMappers(mappers);}}//返回Configurationreturn cfg;} catch (Exception e) {throw new RuntimeException(e);} finally {try {config.close();} catch (Exception e) {e.printStackTrace();}}}/*** 根據傳入的參數,解析XML,并且封裝到Map中** @param mapperPath 映射配置文件的位置* @return map中包含了獲取的唯一標識(key是由dao的全限定類名和方法名組成)* 以及執行所需的必要信息(value是一個Mapper對象,里面存放的是執行的SQL語句和要封裝的實體類全限定類名)*/private static Map<String, Mapper> loadMapperConfiguration(String mapperPath) throws IOException {InputStream in = null;try {//定義返回值對象Map<String, Mapper> mappers = new HashMap<String, Mapper>();//1.根據路徑獲取字節輸入流in = Resources.getResourceAsStream(mapperPath);//2.根據字節輸入流獲取Document對象SAXReader reader = new SAXReader();Document document = reader.read(in);//3.獲取根節點Element root = document.getRootElement();//4.獲取根節點的namespace屬性取值String namespace = root.attributeValue("namespace");//是組成map中key的部分//5.獲取所有的select節點List<Element> selectElements = root.selectNodes("//select");//6.遍歷select節點集合for (Element selectElement : selectElements) {//取出id屬性的值 組成map中key的部分String id = selectElement.attributeValue("id");//取出resultType屬性的值 組成map中value的部分String resultType = selectElement.attributeValue("resultType");//取出文本內容 組成map中value的部分String queryString = selectElement.getText();//創建KeyString key = namespace + "." + id;//創建ValueMapper mapper = new Mapper();mapper.setQueryString(queryString);mapper.setResultType(resultType);//把key和value存入mappers中mappers.put(key, mapper);}return mappers;} catch (Exception e) {throw new RuntimeException(e);} finally {in.close();}}/*** 根據傳入的參數,得到dao中所有被select注解標注的方法。* 根據方法名稱和類名,以及方法上注解value屬性的值,組成Mapper的必要信息** @param daoClassPath* @return*/private static Map<String, Mapper> loadMapperAnnotation(String daoClassPath) throws Exception {//定義返回值對象Map<String, Mapper> mappers = new HashMap<String, Mapper>();//1.得到dao接口的字節碼對象Class daoClass = Class.forName(daoClassPath);//2.得到dao接口中的方法數組Method[] methods = daoClass.getMethods();//3.遍歷Method數組for (Method method : methods) {//取出每一個方法,判斷是否有select注解boolean isAnnotated = method.isAnnotationPresent(Select.class);if (isAnnotated) {//創建Mapper對象Mapper mapper = new Mapper();//取出注解的value屬性值Select selectAnno = method.getAnnotation(Select.class);String queryString = selectAnno.value();mapper.setQueryString(queryString);//獲取當前方法的返回值,還要求必須帶有泛型信息Type type = method.getGenericReturnType();//List<User>//判斷type是不是參數化的類型if (type instanceof ParameterizedType) {//強轉ParameterizedType ptype = (ParameterizedType) type;//得到參數化類型中的實際類型參數Type[] types = ptype.getActualTypeArguments();//取出第一個Class domainClass = (Class) types[0];//獲取domainClass的類名String resultType = domainClass.getName();//給Mapper賦值mapper.setResultType(resultType);}//組裝key的信息//獲取方法的名稱String methodName = method.getName();String className = method.getDeclaringClass().getName();String key = className + "." + methodName;//給map賦值mappers.put(key, mapper);}}return mappers;}}5 自定義Mybatis的編碼-創建兩個默認實現類并分析類之間的關系
DefaultSqlSession.java
6 自定義Mybatis的編碼-實現基于XML的查詢所有操作
7 自定義Mybatis的編碼-實現基于注解配置的查詢所有
?
?
day01附錄
泛型術語
以ArrayList<E>為例:<>念作typeof
ArrayList<E>中的E稱為類型參數變量,其實就是類型的占位符(傳入什么類型就是什么類型)。
ArrayList<Integer>中的Integer稱為實際類型參數
整個稱為ArrayList<E>泛型類型
整個ArrayList<Integer>稱為參數化的類型ParameterizedType
Set<String>、Enumeration<String>、Map<String,Object>、Map<K,V>
截圖
01三層架構02持久層總圖03mapper配置文件的創建要求04mybatis的分析總結
以上是生活随笔為你收集整理的MyBatis-学习笔记03【03.自定义Mybatis框架】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MyBatis-学习笔记02【02.My
- 下一篇: 学长的求职经验 记录【就业创业信息网、求