https://blog.csdn.net/Song_JiangTao/article/details/82252852
一、Spring部分
1、Spring的運行流程
·第一步:加載配置文件ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
,ApplicationContext接口,它由BeanFactory接口派生而來,因而提供了BeanFactory所有的功能。配置文件中的bean的信息是被加載在HashMap中的,一個bean通常包括,id,class,property等,bean的id對應HashMap中的Key,value就是bean。
具體如何加載,源碼如下:

if (beanProperty.element("map") != null){ Map<String, Object> propertiesMap = new HashMap<String, Object>(); Element propertiesListMap = (Element)beanProperty.elements().get(0); Iterator<?> propertiesIterator = propertiesListMap .elements().iterator(); while (propertiesIterator.hasNext()) { Element vet = (Element) propertiesIterator.next(); if(vet.getName().equals("entry")) { String key = vet.attributeValue("key"); Iterator<?> valuesIterator = vet.elements() .iterator(); while (valuesIterator.hasNext()) { Element value = (Element) valuesIterator.next(); if (value.getName().equals("value")){ propertiesMap.put(key, value.getText()); } if (value.getName().equals("ref")) { propertiesMap.put(key, new String[]{ value.attributeValue("bean") }); } } } } bean.getProperties().put(name, propertiesMap); //看完反正我是默默放棄了。。。 }
·第二步:調用getBean方法,getBean是用來獲取applicationContext.xml文件里的bean的,()寫的是bean的id。一般情況下都會強轉換成對應的業務層(接口)。例如SpringService springService = (SpringService)ac.getBean("Service");
·第三步:這樣我們就可以調用業務層(接口實現)的方法。
具體如下:
java反射博大精深,具體請看:
https://blog.csdn.net/sinat_38259539/article/details/71799078
那么bean中的東西到底是怎么注入進去的?簡單來講,就是在實例化一個bean時,實際上就實例化了類,它通過反射調用類中set方法將事先保存在HashMap中的類屬性注入到類中。這樣就回到了我們java最原始的地方,對象.方法,對象.屬性。
2、Spring的原理
·什么是Spring?
·Spring是一個容器框架,它可以接管web層,業務層,dao層,持久層的各個組件,並且可以配置各種bean,並可以維護bean與bean的關系,當我們需要使用某個bean的時候,我們可以直接getBean(id),使用即可。
·Spring目的:
就是讓對象與對對象(模塊與模塊)之間的關系沒有通過代碼來關聯,都是通過配置類說明管理的(Spring根據這些配置,內部通過反射去動態的組裝對象),Spring是一個容器,凡是在容器里的對象才會有Spring所提供的這些服務和功能。
·層次架構圖:
說明:
·web層:Struts充當web層,接管jsp,action,表單,主要體現出MVC的數據輸入,數據的處理,數據的顯示分離。
·model層:model層在概念上可以理解為包含了業務層,dao層,持久層,需要注意的是,一個項目中,不一定每一個層次都有;
·持久層:體現oop,主要解決關系模型和對象模型之間的阻抗。
3、Spring的核心技術
·IOC:
·IOC(Inverse of control)控制反轉:所謂反轉就是把創建對象(bean)和維護對象(bean)之間的關系的權利從程序轉移到spring的容器(spring-config.xml)。
說明:
<bean></bean>這對標簽元素的作用:當我們加載spring框架時,spring就會自動創建一個bean對象,並放入內存。相當於我們常規的new一個對象,而<property></property>中的value則是實現了“對象.set方法”,這里也體現了注入概念。
·DI
·DI(dependency injection)依賴注入:實際上di和ioc是同一個概念,spring的設計者,認為di更准確的表示spring的核心;
·spring提倡接口編程,在配合di技術就可以達到層與層解耦的目的,為什么呢?因為層與層之間的關聯,由框架幫我們做了,這樣代碼之間的耦合度降低,代碼的復用性提高。
·接口編程的好處請訪問Java中接口編程的好處以及實現方式的選擇?
·AOP
·aspect oriented programming(面向切面編程);
·核心:在不增加代碼的基礎上,還增加新功能;
·理解:面向切面:其實是,把一些公共的“東西”拿出來,比如說,事務,安全,日志,這些方面,如果你用的到,你就引入。也就是說:當你需要在執行一個操作(方法)之前想做一些事情(比如開啟事務,記錄日志等等),那你就用before,如果想在操作之后做點事情(比如,關閉一些連接等等),那你就用after。其他類似。
二、Spring MVC部分
1、spring MVC框架:
架構執行流程(面試必問):
·1、用戶發送請求至前端控制器DispatcherServlet;
·2、DispatcherServlet收到請求調用HandlerMapping處理器映射器;
·3、處理器映射器根據請求URL找到具體的處理器,生成處理器對象及處理器攔截器(如果有則生成),一並返回給DispatcherServlet;
·4、DispatcherServlet通過HandlerAdapter處理器適配器調用處理器;
·5、執行處理器(Controller,也叫后端控制器);
·6、Controller執行完成返回ModelAndView;
·7、HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet;
·8、DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器;
·9、ViewReslover解析后返回具體View;
·10、DispatcherServlet對View進行渲染視圖(即將模型數據填充至視圖中);
·11、DispatcherServlet響應用戶。
2、Spring MVC的原理
·1、什么是SpringMVC?
·springmvc是spring框架的一個模板,springmvc和spring無需通過中間整合層進行整合;
·springmvc是一個基於mvc的web框架。
·mvc
·mvc在b/s系統下的應用:
·前端控制器DispatcherServlet(不需要程序員開發)
·作用:接受請求,響應結果,相當於轉發器,中央處理器。有了DispatcherServlet減少了其它組件之間的耦合度。
·處理器映射器HandlerMapping(不需要程序員開發)
·作用:根據請求的url查找Handler
·處理器適配器HandlerAdapter
·作用:按照特定規則(HandlerAdapter要求的規則)去執行Handler
·處理器Handler(需要程序員開發)
·注意:編寫Handler時按照HandlerAdapter的要求去做,這樣適配器才可以正確執行Handler。
·視圖解析器View resolver(不需要程序員開發)
·作用:進行視圖解析,根據邏輯視圖名解析成真正的視圖(view)
·視圖view(需要程序員開發)
·View是一個接口,實現類支持不同的View類型(jsp、freemarker、pdf...)
·Struts2與springmvc的區別?
1、Struts2是類級別的攔截,一個類對應一個request上下文,springmvc是方法級別的攔截器,一個方法對應一個request上下文,而方法同時又跟一個URL對應,所以說從框架本身上Springmvc就容易實現restful url,而Struts2的框架實現起來要費勁,因為Struts2中Action的一個方法對應一個URL,而其屬性卻被所有方法共享,這也就無法用注解或其他方式標識其所屬方法了。
2、由上邊原因,springmvc的方法之間基本上獨立的,獨享request response數據,請求數據通過參數獲取,處理結果通過ModelMap交回給框架,方法之間不共享變量,而Struts2搞的就比較亂,雖然方法之間也是獨立的,但其所有Action變量共享,這不會影響程序運行,卻給我們編碼讀程序時帶來麻煩,每次來了請求就創建一個Action,一個Action對象對應一個request上下文。
3、由於Struts2需要針對每個request進行封裝,把request,session等servlet生命周期的變量封裝成一個Map,供給每個Action使用,並保證線程安全,所以在原則上,是比較耗費內存的。
4、攔截器實現機制上,Struts2有以自己的interceptor機制,springmvc用的是獨立的AOP方式,這樣導致Struts2的配置文件量還是比springMVC大。
5、springmvc的入口是servlet,而Struts2是filter(這里要指出,filter和servlet是不同的。以前認為filter是servlet的一種特殊),這就導致了二者的機制不同,這里就牽涉到servlet和filter的區別了。
6、springmvc集成了Ajax,使用非常方便,只需一個注解@ResponseBody就可以實現,然后直接返回相應文本即可,而Struts2攔截器集成了Ajax,在Action中處理時一般必須安裝插件或者自己寫代碼進去,使用起來也相對不方便。
7、springmvc驗證支持JSR303,處理起來相對更加靈活方便,而Struts2驗證比較繁瑣,感覺太煩亂。
8、springmvc和spring是無縫的。從這個項目的管理和安全上也比Struts2高(當然Struts2也可以通過不同的目錄結構和相關配置做到springmvc一樣的效果,但是需要xml配置的地方不少)。
9、設計思想上,Struts2更加符合OOP的編程思想,springmvc就比較謹慎,在servlet上擴展。
10、springmvc開發效率和性能高於Struts2.
11、springMVC可以認為已經100%零配置。
3、spring MVC的核心技術
·注解開發(@Controller,@ResponseMapping,@ResponseBody...)
·還有spring的諸多注解,這兩者是不需要整合的
·傳參,接參(request)
·基本配置
·文件上傳與下載
·spring MVC中文件上傳需要添加Apache Commons FileUpload相關的jar包;
·基於該jar,spring中提供了MultipartResolver實現類:CommonsMutipartResolver
·攔截器
·其實最核心的還是springMVC的執行流程,哥哥點的作用得搞清楚。
三、Mybatis部分
1、Mybatis的運行流程:
·Mybatis運行流程圖:
1、:配置mybatis.xml文件,大體如下:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 引入外部文件 resource:引入項目中配置文件 url:引入網絡中或者路徑文件 --> <properties resource="jdbc.properties"/> <settings> <!--<setting name="mapUnderscoreToCamelCase" value="true" />--> <setting name="lazyLoadingEnabled" value="true" /> <setting name="aggressiveLazyLoading" value="false" /> <setting name="cacheEnabled" value="true"/> </settings> <typeAliases> <package name="com.nuc.entity"></package> </typeAliases> <!-- - - - - - - 數據庫環境配置- - - - - - - - - --> <environments default="environments"> <environment id="environments"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driverClass}"/> <property name="url" value="${jdbc.jdbcUrl}"/> <property name="username" value="${jdbc.user}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <!-- - - - - - - -映射文件路徑- - - - - - --> <mappers> <!--自動掃描包下的映射文件,要求:同名,同目錄--> <package name="com.nuc.mapper" /> </mappers> </configuration>
2、:加載我們的xml文件;
3、:創建SqlSessionFactoryBuilder;
4、:創建SqlSessionFactory;
5、:調用openSession(),開啟sqlSession;
6、:getMapper()來獲取我們的mapper(接口),mapper對應的映射文件,在加載mybatis.xml時就會加載;
7、:使用我們自己的mapper和它對應的xml來完成我們和數據庫的交互。即增刪改查。
8、:提交session,關閉session。
代碼如下:
String resource = "mybatis-config.xml";
SqlSession sqlSession = null;
InputStream inputStream = Resources.getResourceAsStream(resource);//讀取mybatis配置文件
//SqlSessionFactoryBuilder這個類的作用就是為了創建SqlSessionFactory的
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);
/**
* factory.openSession(); //需手動提交事務
* factory.openSession(true); //系統自動提交事務
*/
sqlSession = factory.openSession();
CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class);
//增刪改查的操作
sqlSession.commit();//如果沒有提交,數據庫的數據不會改變
sqlSession.close();
需要注意的是,sqlSession也自帶一些數據交互的操作。
2、MyBatis的原理
·什么是Mybatis?
·mybatis專注sql本身,需要程序員自己編寫sql語句,sql修改,優化比較方便。mybatis是一個不完全的ORM框架,雖然程序員自己寫sql,mybatis也可以實現映射(輸入映射、輸出映射);
·mybatis是一個持久層的框架,是apache下的頂級項目;
·mybatis托管到googlecode下,后來托管到github下:mybatis github地址
·mybatis讓程序將主要精力放在sql上,通過mybatis提供的映射方式,自由靈活生成(半自動化,大部分需要程序員編寫sql)滿足需要sql語句。
·mybatis可以將向preparedStatement中的屬兔參數自動進行輸入映射,將查詢結果集靈活映射成Java對象。(輸出映射)
·mybatis底層實現
·mybatis底層還是采用原生jdbc來對數據庫進行操作的,只是通過SqlSessionFactory,SqlSession,Executor,StatementHandler,ParameterHandler,ResultHandler和TypeHandler等幾個處理器封裝了這些過程。
·對原生態jdbc程序(單獨使用jdbc開發)問題總結:
·1、數據庫連接,使用時創建,不用就關閉,對數據庫進行頻繁連接開啟和關閉,造成數據庫資源的浪費;
解決:使用數據庫連接池管理數據庫連接。
2、將sql語句硬編碼到Java代碼中,如果sql語句修改,需要對Java代碼重新編譯,不利於系統維護;
解決:將sql語句設置在xml配置文件中,即使sql變化,也無需重新編譯。
3、向preparedStatement中設置參數,對占位符位置和設置參數值,硬編碼到Java文件中,不利於系統維護;
解決:將sql語句及占位符,參數全部配置在xml文件中。
4、從resultSet中遍歷結果集數據時,存在硬編碼,將獲取表的字段進行硬編碼,不利於系統維護;
解決:將查詢的結果集,自動映射成Java對象。
·mybatis工作原理:
·mybatis通過配置文件創建sqlSessionFactory,sqlSessionFactory根據配置文件,配置文件來源於兩個方面:一個是xml,一個是Java中的注解,獲取sqlSession。SqlSession包含了執行sql語句的所有方法,可以通過SqlSession直接運行映射的sql語句,完成對數據的增刪改查和事物的提交工作,用完之后關閉SqlSession。
3、Mybatis的核心技術:
·Mybatis輸入映射:
·通過parameterType指定輸入參數的類型,類型可以是簡單類型、hashmap、pojo包裝類型;
·Mybatis輸出映射:
·一、resultType
·作用:將查詢結果按照sql列名、pojo屬性名一致性映射到pojo中;
·使用resultType進行輸出映射,只有查詢出來的列名和pojo中的屬性名一致,該列才可以映射成功;
·如果查詢出來的列名和pojo中的屬性名全部不一致,則不會創建pojo對象;
·只要查詢出來的列名和pojo中的屬性有一個一致,就會創建pojo對象;
·如果查詢出來的列名和pojo的屬性名不一致,通過定義一個resultMap對列名和pojo屬性名之間作一個映射關系。
·二、resultMap
·使用association和collection完成一對一和一對多高級映射(對結果有特殊的映射要求)。
·association:
·作用:將關聯查詢信息映射到一個pojo對象中;
·場合:為了方便查詢關聯信息可以使用association將關聯訂單信息映射為用戶對象的pojo屬性中,比如:查詢訂單及關聯用戶信息。
·使用resultType無法將查詢結果映射到pojo對象的pojo屬性中,根據對結果集查詢遍歷的需要選擇使用resultType還是resultMap。
·collection:
·作用:將關聯查詢信息映射到一個list集合中;
·場合:為了方便查詢遍歷關聯信息可以使用collection將關聯信息映射到list集合中,比如:查詢用戶權限范圍模塊及模塊下的菜單,可使用collection將模塊映射到模塊list中,將菜單列表映射到模塊對象的菜單list屬性中,這樣做的目的也是方便對查詢結果集進行遍歷查詢。如果使用resultType將無法將查詢結果映射到list集合中。
·Mybatis的動態sql
·什么是動態sql?
·mybatis核心:對sql語句進行靈活操作,通過表達式進行判斷,對sql進行靈活拼接、組裝;
·包括,where,if,foreach,choose,when,otherwise,set,trim等標簽的使用。
·數據模型分析思路:
·1、每張表記錄的數據內容
·分模塊對每張表記錄的內容進行熟悉,相當於你學習系統需求(功能)的過程;
2、每張表重要的字段設置
·非空字段、外鍵字段
·3、數據庫級別表與表之間的關系
·外鍵關系
·4、表與表之間的業務關系
·在分析表與表之間的業務關系時一定要建立在某個業務意義基礎上去分析。