ssm基础笔记
第三章 ssm
1 spring
1.1 IOC
什么是IOC? IOC 含義: 全稱 Inverse Of Control:控制反轉(zhuǎn),指的是將 bean 對象的創(chuàng)建、對象關聯(lián)關系的維護由原來我們自己去創(chuàng)建一個對象,自己通過硬編碼的方式維護對象之間的關聯(lián)關系,反轉(zhuǎn)給 spring 的容器來創(chuàng)建對象,及維護對象之間的關聯(lián)關系[屬性賦值]。IOC 作用: 解決了上層建筑嚴重依賴下層建筑的問題,實現(xiàn)了上層建筑對下層建筑的控制。 IOC底層原理:xml 解析+反射+容器+設計模式1.2 獲取容器的三種方式
獲取容器的三種方式: 第一種:ClassPathXmlApplicationContext,默認是去src目錄下找配置文件,必須掌握 第二種:FileSystemXmlApplicationContext:默認是去本地磁盤中找對應的配置文件 第三種:XmlBeanFactory:已過時,了解即可。1.3 從容器中獲取 bean 對象的兩種方式及區(qū)別
從容器中獲取bean對象的兩種方式: 1.通過字節(jié)碼的方式 eg:Test.class2.通過容器中bean對象的id值或者name(name相當于別名)值的方式區(qū)別:第一個:參數(shù)類型不同,一個是字符串類型,一個是字節(jié)碼類型第二個:返回值類型,一個是Object類型,一個是指定字節(jié)碼類型第三個:如果我們傳遞的參數(shù)是字節(jié)碼類型:要求容器中有該類型的唯一bean對象,沒有:報NoSuchBeanDefinitionException有一個:就將容器中的該類型的唯一bean對象賦值給該變量有多個[兩個及以上]:報 NoUniqueBeanDefinitionException bean標簽:每一個bean標簽都對應一個類對象,相當于以前new 類屬性:class屬性:指定對象的全類名[包名+類名]id屬性:全稱identifier,唯一標識符,必須在當前配置文件中保持唯一,不能重復,方便其它對象引用當前對象name屬性:當前bean對象的別名,和id屬性的作用一致,一般也是要保持唯一,可以隨便寫實際開發(fā)中,id屬性和name屬性沒有必要都存在,只需要存在一個即可。1.4 在 spring 容器中創(chuàng)建 bean 對象的三種方式
<!--在容器中創(chuàng)建bean對象的三種方式: 第一種:構(gòu)造器【無參、有參構(gòu)造器】,最常用 第二種:靜態(tài)工廠:指的通過類的靜態(tài)方法返回的對象 第三種:實例工廠:通過類對象的普通方法的得到的對象 --><!-- 第一種:構(gòu)造器【無參、有參構(gòu)造器】 --> <bean id="book2" class="com.atguigu.bean.Book"> <constructor-arg name="bid" value="120"></constructor-arg> <constructor-arg name="bookname" value="斗破蒼穹"></constructor-arg> <constructor-arg name="price" value="199.8"></constructor-arg> </bean><!-- 靜態(tài)工廠:指的通過類的靜態(tài)方法返回的對象 --> <bean id="book3" class="com.atguigu.web.StaticFactory" factory-method="getBook"></bean><!-- 實例工廠:通過類對象的普通方法的得到的對象 --> <bean id="instanceFactory" class="com.atguigu.web.InstanceFactory" ></bean> <bean id="book4" factory-bean="instanceFactory" factory-method="getBook02"></bean>Book.class
public class Book { //getter/setter方法 private Integer bid; private String bookname; private double price; public Book(Integer bid, String bookname, double price) { this.bid = bid;this.bookname = bookname;this.price = price; }}StaticFactory:
public class StaticFactory { public static Book getBook(){ return new Book(101,"斗羅大陸",199); }}InstanceFactory:
public class InstanceFactory { public Book getBook02(){ return new Book(102,"三體",90); }}1.5 基于注解的方式給對象的屬性賦值
不用提供屬性對應的 setter 方法
@Value:取代 xml 文件中的 value 屬性的,給基本類型的屬性賦值的。
@Autowired:取代 xml 文件中的 ref 屬性的,給引用類型的屬性賦值,spring 中的
@Resource:取代 xml 文件中的 ref 屬性的,給引用類型的屬性賦值,jdk 自帶的
@Autowired 注解的原理: 先根據(jù)該屬性的類型去容器中找類型的唯一bean對象第一種:如果容器中沒有該類型的唯一bean對象,報錯BeanCreationException第二種:如果容器中有該類型的唯一bean對象,就將容器中的對象賦值該屬性第三種:如果容器中有多個該類型的bean對象:1) 在根據(jù)當前屬性的名字去容器中看看有沒有一個bean對象的id值和當前屬性名保持一致,如果有就將容器中的對象賦值給該屬性2) 如果容器中沒有一個bean對象id值和當前屬性的名字保持一致,再檢查當前屬性有沒有@Qualifer,如果沒有,直接報錯,如果有,會再根據(jù)@Qualifer 的 value 屬性值去容器中找一個 id 為@Qualifer的 value 屬性值對象,如果能找到,就將這個對象賦值給該屬性,如果找不著,報錯@Autowired(根據(jù)屬性類型注入)
@Qualifer(根據(jù)id值從容器中進行匹配)
1.6 AOP
什么是aop? AOP含義: 全稱:Aspect Oreinted Programming:面向切面編程,AOP和OOP不存在誰取代誰的情況,他們之間是相互補充,相互促進的,Aop是在不改變原有OOP類代碼的前提下,對原來類的功能進行拓展。AOP作用:解決了軟件工程中提出的關注點分離問題,讓系統(tǒng)的架構(gòu)變得高內(nèi)聚低耦合。AOP底層原理:動態(tài)代理[jdk動態(tài)代理+cglib動態(tài)代理]AOP具體應用:聲明式事務、通用緩存、通用日志、全局異常處理。aop涉及的概念
通知[advice]:拓展的功能稱之為通知[本質(zhì):方法] 切面[aspect]: 通知所在的類,稱之為切面[本質(zhì):類] 切入點[PointCut]:用來確定對誰進行拓展的[本質(zhì):表達式] 連接點[JoinPoint]:通知和目標方法的交點稱之為連接點 目標對象[Target]:目標方法所在的類對象稱之為目標對象 織入[Weaving]:將通知應用到目標方法的過程,稱之為織入步驟
1.將被拓展的類和拓展的類加入到容器中,掃描包+類上加注解
2.在 spring 的配置文件開啟基于注解的切面支持,并在拓展的類上@Aspect
3.在拓展的類的方法上指定切入點表達式。
@Component @Aspect//該注解標記在類上,表示當前類是一個切面類 public class LogAspect { //目標方法簽名 @Before(value = "execution(public int com.atguigu.aop.CaculatorImpl.add(int,int))") public void beforeLog(){ System.out.println("目標方法執(zhí)行之前輸出的日志"); }}aop底層原理
靜態(tài)代理
是指只能代理某一個接口的類對象
Payment 接口:
public interface Payment { public void pay(double money); }RealPayment 實現(xiàn)類:
public class RealPayment implements Payment { @Override public void pay(double money) { System.out.println("作為真實用戶,我們只關注付了"+money); }}AliPay 代理類:
public class AliPay implements Payment { private Payment payment;public AliPay(Payment payment) { this.payment=payment; }public void beforePay() { System.out.println("支付寶把錢從銀行取出來"); }@Override public void pay(double money) { beforePay(); this.payment.pay(money); afterPay(); }public void afterPay() { System.out.println("支付寶把錢支付給商家"); }}測試代碼:
@Test public void testPay(){ //只能代理Payment類型的 AliPay aliPay = new AliPay(new RealPayment()); aliPay.pay(30); }動態(tài)代理
動態(tài)代理:可以代理任意接口的類對象
public void testDynamicProxy(){ /************************************************************ 1.Proxy.newProxyInstance方法可以創(chuàng)建任意接口的代理類對象參數(shù): 第一個參數(shù):被代理類的類加載器 第二個參數(shù):被代理類的實現(xiàn)的接口 第三個參數(shù): InvocationHandler接口的實現(xiàn)類對象,在InvocationHandler接口的實現(xiàn)類我們可以對被代理類進行拓展返回值:代理類對象 ************************************************************/ // RealPayment realPayment = new RealPayment(); WeiPayImpl weiPay=new WeiPayImpl(); //代理類對象WeiPay o =(WeiPay)Proxy.newProxyInstance(weiPay.getClass().getClassLoader(),weiPay.getClass().getInterfaces(), new MyInvocationHandler(weiPay)); o.pay(40.3); }InvocationHandler 接口實現(xiàn)類:
public class MyInvocationHandler implements InvocationHandler { private Object target;public MyInvocationHandler(Object target) { this.target=target;} /************************************************************ method:被代理類的方法 args:調(diào)用被代理類方法的時候傳遞的參數(shù) proxy:不適用,不用管。 ************************************************************/ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("動態(tài)代理把錢從銀行取出來......"); //調(diào)用被代理的方法 Object result = method.invoke(target, args); System.out.println("動態(tài)代理把錢付給商家......"); return result; }}靜態(tài)代理和動態(tài)代理的區(qū)別
相同點:
? 第一點:都是在不改變原有類代碼的基礎之上對被代理類進行拓展
? 第二點:都需要實現(xiàn)接口,都要求被代理類和代理類實現(xiàn)相同接口
不同點:
? 靜態(tài)代理只能代理某一個接口的類對象,動態(tài)代理可以代理任意接口的類對象
1.7 切面中的五種通知
前置通知[@Before]:在目標方法執(zhí)行之前執(zhí)行 后置通知[@After]:無論目標方法有沒有執(zhí)行成功,后置通知都會執(zhí)行 返回通知[@AfterReturning]:在目標方法之后,只有目標方法執(zhí)行成功的情況下,返回通知才執(zhí)行 異常通知[@AfterThrowing]:在目標方法之后, 只有目標方法執(zhí)行出現(xiàn)異常的情況下,異常通知才執(zhí)行環(huán)繞通知[@Around]:以一抵四通知的底層原理
切入點表達式
作用:在切面中用來定位對誰進行拓展的
語法:
execution([權(quán)限修飾符] [返回值類型] [全類名].[方法名] ([參數(shù)類型列表]))
最簡潔:
execution(* *.*(..)) 注意:權(quán)限修飾符和返回值類型只能合用一個*,兩個會報錯 ..代表多參,相當于args ...最復雜:
execution(public int com.fjw.Test.add(int,int))切入點重用
支持 && || !操作
execution(* *.add(int,int)) || execution(* *.sub(int,int))獲取目標方法的信息
獲取目標方法的返回結(jié)果
注意:returning的result和下面的形參必須保持一致,且形參類型必須為object
1.8 環(huán)繞通知
@Component @Aspect public class TransactionAspect { /************************************************************ 環(huán)繞通知要求: 1.方法返回值類型必須為Object類型 2.參數(shù)類型:ProceedingJoinPoint 3.要求獲取到目標方法的結(jié)果之后一定要返回 ************************************************************/ @Around(value = "com.atguigu.aop.LogAspect.myPoint()")public Object around(ProceedingJoinPoint joinPoint){String name = joinPoint.getSignature().getName(); Object[] args = joinPoint.getArgs();Object proceed = null; try{try{System.out.println("事務切面 前置通知,目標方法名為:"+name+",傳遞給目標方法的參數(shù)值為:"+ Arrays.asList(args));//調(diào)用目標方法proceed = joinPoint.proceed();}finally {System.out.println("事務切面 后置通知"); } System.out.println("事務切面 返回通知,目標方法的返回結(jié)果為:"+proceed); }catch (Throwable ex){ex.printStackTrace();System.out.println("事務切面 異常通知,目標方法的異常信息為:"+ex.getMessage()); }return proceed;} }1.9 多切面優(yōu)先級
多切面情況下,各個切面的優(yōu)先級是由切面類上的@Order 注解的 value
屬性值決定的,誰的 value 屬性值越小,優(yōu)先級越高。
1.10聲明式事務
在 spring 的配置文件配置數(shù)據(jù)源事務管理器,開啟基于注解的事務支持,在 service 層的類上或者方法上加@Transactional 注解
<!--1.配置掃描包 --> <context:component-scan base-package="com.atguigu"></context:component-scan> <!-- 2.加載 properties 文件 --><context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder><!-- 3.配置數(shù)據(jù)源 --> <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="username" value="${abc.userName}"/> <property name="password" value="${abc.password}"/> <property name="url" value="${abc.jdbcUrl}"/> <property name="driverClassName" value="${abc.driverClass}"/> </bean><!-- 4.配置 JdbcTemplate --> <bean class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="druidDataSource"></property> </bean><!-- 5.配置數(shù)據(jù)源事務管理器 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="druidDataSource"></property> </bean><!--6.開啟基于注解的事務支持 --> <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>1.11聲明式事務的五大屬性
1、傳播機制
propagation:指的一個帶有事務的方法 A 運行在另一個帶有事務的方法 B 的內(nèi)部時候,內(nèi)層方法 A 是使用自己的事務還是使用外層方法 B 的事務,這就是事務的傳播機制。
propagation:常用取值有Required、supports、requires_newRequired【默認值】:如果外層方法B有事務,內(nèi)層方法A 就用外層方法B的事務。如果外層方法B沒有事務,內(nèi)層方法A 就用自己的事務 requires_new:無論外層方法有沒有事務,內(nèi)層方法都使用自己的事務。 supports:如果外層方法B有事務,內(nèi)層方法A 就用外層方法B的事務如果外層方法B沒有事務,內(nèi)層方法A 不用事務了。結(jié)論:多個內(nèi)層方法,最后一個內(nèi)層方法前面的事務的傳播機制不能設置requires_new,有可能導致前面的事務提交,后面的錯誤導致回滾不了。
2、隔離級別
isolation:主要是針對并發(fā)訪問的
READ_UNCOMMITED: 讀未提交 READ_COMMITED: 讀已提交,在一個事務A操作過程中,如果其它事務B修改了某個數(shù)據(jù),并且已經(jīng)提交了,事務A就可以讀取到。 REPEATABLE_READ: 可重復讀(默認):在一個事務內(nèi)部多次讀取的結(jié)果永遠是一致的 SERIALIZABLE: 序列化讀,不允許并發(fā)不同的數(shù)據(jù)庫默認的隔離級別不一樣,mysql默認的隔離級別是可重復讀,oracle默認的隔離級別是讀已提交。3、回滾屬性:rollbackFor
事務默認只是在遇到運行時異常的時候才會回滾,遇到編譯時異常,不會回滾。
注意:在 spring 框架底層將 SQLException 轉(zhuǎn)換為 RuntimeException!
? spring 框架并沒有將 IOException 轉(zhuǎn)換為 RuntimeException (rollbackFor可以處理異常回滾)
rollbackFor:針對的主要是非運行時異常 noRollbackFor:針對運行時異常的4、超時屬性
事務在執(zhí)行過程中,勢必會占用著數(shù)據(jù)庫資源,為了防止一個事務長時間占用著數(shù)據(jù)庫資源, 導致其它事務無法進行,有必要給事務設置一個超時時間,一旦一個事務超過了指定的超時時間,就可以讓事務進行回滾。
timeout:指的在當前事務內(nèi)部,多次對數(shù)據(jù)表的增刪改操作的之間的總時間不能超過指定值。(從開始對庫的操作到結(jié)束對庫的操作)
5、只讀屬性
readOnly:為了加快查詢效率,如果我們給事務設置 readOnly=true,就意味著在當前方法只能有對數(shù)據(jù)表的查詢操作,不能有增刪改操作。告訴數(shù)據(jù)庫把鎖設置為共享鎖;
1.12基于 xml 配置的聲明式事務
<aop:config> <!-- 指定切入點表達式 --> <aop:pointcut id="myPointCut" expression="execution(* com.atguigu.service.BookService.*(..))"/> <!-- 2. 將切入點表達式和事務聯(lián)系起來--> <aop:advisor advice-ref="dsada" pointcut-ref="myPointCut"></aop:advisor> </aop:config> <!-- 配置事務 --> <tx:advice id="dsada" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="buyBook"/> <tx:method name="get*" read-only="true"/> <tx:method name="find*" read-only="true"/> <tx:method name="query*" read-only="true"/> <tx:method name="update*" ></tx:method> <tx:method name="insert*" ></tx:method> <tx:method name="delete*" ></tx:method> </tx:attributes> </tx:advice>2 springMVC
2.1 基本配置
2.1.1在 web.xml 文件中配置 springmvc 的前端控制器
<!-- 1.配置springmvc的前端控制器 --> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class > <!--2.加載springmvc的配置文件 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!--3.用來映射瀏覽器請求的 --> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>2.1.2在 springmvc.xml 文件中配置內(nèi)部資源視圖解析器和掃描包
<!--1.配置掃描包 --> <context:component-scan base-package="com.atguigu"></context:component-scan> <!--2.配置內(nèi)部資源視圖解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/"/> <property name="suffix" value=".jsp"/> </bean>2.2 常見問題
web.xml 文件中
2.2.1 load-on-startup:
0 和正整數(shù):在 tomcat 服務器啟動的時候,當前 servlet 對象就被創(chuàng)建了
負整數(shù): 在第一次請求到達的時候,當前 servlet 對象才被創(chuàng)建。
2.2.2 url-pattern 值:
/:攔截當前項目下所有的請求, 不包括 jsp
/*:攔截當前項目下所有的請求,包括 jsp
2.2.3 InternalResourceViewResolver:內(nèi)部資源視圖解析器
作用一:將邏輯視圖解析為物理視圖
prefix+returnval+suffix
作用二:轉(zhuǎn)發(fā)到對應的 jsp 頁面
2.3 請求相關操作
2.3.1 @RequestMapping
2.3.2 @RequestParam
可以接收數(shù)組,集合,如果寫了,前端必須有對應的字段(required默認),否則報錯
2.3.3 @PathVariable [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-EZwPmleV-1660813088288)(./image/image-20220228100600224.png)]
2.3.4 @RequestHeader
2.3.5 @CookieValue
如上類似
2.3.6 原生API
HttpServletRequest、HttpServletResponse、HttpSession
2.3.7 支持數(shù)據(jù)、pojo對象
數(shù)組:
POJO對象:
2.3.8 @RequestBody
將http的輸入流裝配到目標類,會根據(jù)json字符串中的key來匹配對應實體類的屬性,通過無參構(gòu)造調(diào)用setter賦值給屬性
2.3.9 @ResponseBody
@ResponseBody的作用其實是將java對象轉(zhuǎn)為json格式的數(shù)據(jù)
2.4 處理post請求亂碼
2.5 <mvc:view-controller path=“”/>標簽
2.6 類型轉(zhuǎn)換器
Springmvc 實際上自帶了簡單的類型轉(zhuǎn)換器,例如:
String ----> Integer/double
String–> true/false
2.6.1 全局類型轉(zhuǎn)換器
全局類型轉(zhuǎn)換器:在 springmvc.xml 文件中配置一次,對所有 controller 層代碼都起作用
實現(xiàn)全局類型轉(zhuǎn)換器: 1. 自定義類型轉(zhuǎn)換器類,實現(xiàn) converter<S,T>接口,并加入到容器中 2. 在 springmvc.xml 文件中配置一個 注意dateTimeConverter是自定義Converter接口的實現(xiàn)類,spring管理2.6.2 局部類型轉(zhuǎn)換器
局部類型轉(zhuǎn)換器:在每個方法使用的時候,使用一次配置一次
2.7 靜態(tài)資源的訪問
不加annotation-driven 接口無法訪問
2.8 后端返回json數(shù)據(jù)
第一步:導入 json 的 jar 包 第二步:在方法上加@ResponseBody注解 第三步:在 springmvc.xml 配置文件中配置<mvc:annotation-driven>標簽返回的 json 數(shù)據(jù)類型:Map:必須是自己 new 出來的 Map,不能是參數(shù)中的 map(異步接收不了map) POJO:json對象List<Pojo>:json數(shù)組StringInteger2.9 文件上傳與下載
2.9.1 上傳
前端要求:
form 表單請求方式為 POST
form 表單的 encytype 屬性值:multipart/form-data
type=file
后端要求:
必須在 springmvc.xml 文件中配置多媒體解析器
在目標 handler 方法使用 MultiPartFile 類型的參數(shù)來接收文件
導入文件上傳所需的 jar 包 commons-fileupload、commons-io 包
2.9.2 文件下載
要求:
目標方法返回值類型為:ResponseEntity<byte[]>
設置響應頭:2 個
2.10 攔截器
攔截器類似于我們 javaweb 部分學過的 Filter,都是在請求到達目標方法之前攔截請求,對請求進行過濾操作。
攔截器作用:權(quán)限驗證、記錄日志。
2.10.1 自定義攔截器
自定義一個攔截器類,實現(xiàn) HanlderInceptor 接口,實現(xiàn)接口中的方法
在 springmvc.xml 文件中配置mvc:interceptors標簽自定義攔截器類
在 springmvc.xml 文件中配置:
流程:
2.10.2 多攔截器
誰在 springmvc.xml 文件的 mvc:interceptors 標簽內(nèi)部先聲明,就會先執(zhí)行誰。
對攔截器詳細設置時:
2.11 異常處理
2.11.1 基于注解的統(tǒng)一異常處理
加上mvc:annotation-driven標簽
在全局異常處理類上加@ControllerAdvice 注解
全局異常處理類方法上加@ExceptionHandler 注解,用于處理異常信息!注意:
2.11.2 基于 xml 配置的異常處理
如果希望對所有異常進行統(tǒng)一處理,可以使用 SimpleMappingExceptionResolver,它將異常類名映射為 視圖名,即發(fā)生異常時使用對應的視圖報告異常
2.12 父子容器
mvc是子容器里面放的是controller,spring是父容器,里面放的是service和dao
子容器可以調(diào)父容器,父容器不可以調(diào)子容器
2.13 掃描包問題
spring.xml
<context:component-scan base-package="com.xx"><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/><context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/> </context:component-scan>springmvc.xml
<!--use-default-filters="false"不在全包掃描,只掃下面包括的--> <context:component-scan base-package="com.xx" use-default-filters="false"><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/><context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/> </context:component-scan>2.14 mvc運行流程圖
3 mybatis
3.1 二級緩存
3.1.1一級緩存
SqlSession 級別的,默認是開啟的。
一級緩存失效的四種情況: 1.SqlSession對象不同 2.SqlSession對象相同,但是查詢條件不同 3.SqlSession對象相同,查詢條件也相同,但是在兩次查詢之間做了增刪改操作 4.SqlSession對象相同,查詢條件也相同,但是在兩次查詢之間手動清理了緩存3.1.2二級緩存
Mapper[namespace]級別,默認是關閉的,需要手動開啟。
二級緩存使用前提條件【4 個】: 1. 必須在 mybatis-config.xml 文件中開啟二級緩存 2. 在對應 mapper 接口的 SQL 映射文件中加一個 cache 標簽 3. 放入到二級緩存中的數(shù)據(jù)必須實現(xiàn)序列化接口 4. 必須是一級緩存關閉的情況下,一級緩存中的數(shù)據(jù)才會跑到二級緩存中。3.2 mybatis優(yōu)勢
第一個:MyBatis 本身是一個框架,除了對數(shù)據(jù)表的數(shù)據(jù)進行增刪改查之外,還有緩存、字段映射等機制。 第二個:MyBatis 支持動態(tài) SQL【根據(jù)傳遞不同字符串生成不同的 SQL 語句】 第三個:MyBatis 支持將 java 代碼和 SQL 語句進行分離開來。 第四個:MyBatis 支持將表的關聯(lián)關系直接映射為 POJO 對象的關聯(lián)關系。 第五個: MyBatis 是一個半自動化 ORM 框架 。 ORM 全稱: Object RelationShip Mapping:3.3 mybatis全局配置文件(了解)
需要注意:在全局配置文件中的這些標簽是有順序的
1. properties
作用:加載 properties 文件的。
<!--1.properties標簽是用來加載properties文件的 resource:默認就是去加載src目錄下的properties文件url:本地磁盤或者網(wǎng)絡資源--> <properties resource="jdbc.properties" ></properties>2. settings
settings 標簽有多個 setting 標簽,每個 setting 標簽都對應 mybatis 的一項配置
<settings> <!-- 1.可以將表中以下劃線分隔的列(img_path)映射到pojo對象的駝峰式命名的屬性(imgPath)中 --> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>3. typeAliases
作用:該標簽底下有多個 typeAlias 標簽,每個 typeAlias 對應一種類型別名
<!--類型別名處理器:實際開發(fā)中,不建議使用。 --> <typeAliases> <!-- 該typeAlias標簽可以為類型起別名, type:指定類的全類名,默認的別名是:簡類名,別名不區(qū)分大小寫 alias:指定類的別名,一旦自己指定了別名,再使用別名的時候,就只能使用自己指定的別名 批量起別名:package,指定一個包名,表示為這個包下的所有類都起一個別名,默認的別名是: 簡類名 --> <package name="com.atguigu.bean"/> </typeAliases>
4. typeHandlers
作用:將數(shù)據(jù)庫中的類型轉(zhuǎn)換為 java 中的類型
5. environments
environments 標簽中有很多個 environment 標簽,每個 environment 標簽都對應一種環(huán)境。
<!-- 1.environments標簽的default屬性值:可以切換為environment標簽的id值,表示當前使用是哪種環(huán)境 在每個environment標簽底下又有transactionManager和dataSource兩個子標簽: transactionManager:標簽進行事務管理,type屬性指定管理事務的類取值:JDBC: 支持事務MANAGED:不支持事務 dataSource: 取值:UNPOOLED: 不支持數(shù)據(jù)庫連接池POOLED: 支持數(shù)據(jù)庫連接池,性能比較高JNDI: 過時的,過。 --> <environments default="development"> <!-- 1.開發(fā)人員使用的開發(fā)環(huán)境:開發(fā)人員的數(shù)據(jù)庫 --> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"><property name="driver" value="${jdbc.driverClass}"/> <property name="url" value="${jdbc.jdbcUrl}"/> <property name="username" value="${jdbc.userName}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment><!-- 2.測試人員使用的測試環(huán)境:測試人員的數(shù)據(jù)庫 --> <environment id="test"> <transactionManager type="JDBC"/> <dataSource type="POOLED"><property name="driver" value="${jdbc.test.driverClass}"/> <property name="url" value="${jdbc.test.jdbcUrl}"/> <property name="username" value="${jdbc.test.userName}"/> <property name="password" value="${jdbc.test.password}"/> </dataSource> </environment> </environments>6. databaseIdProvider
該標簽的作用:是給數(shù)據(jù)庫廠商服務器起別名。mysql、oracle、sqlserver、db2
<databaseIdProvider type="DB_VENDOR"> <!-- 指定數(shù)據(jù)庫廠商服務器的別名:name表示服務器的名字, value表示的服務器的別名,可以自己隨意指定--> <property name="SQL Server" value="sqlserver"/> <property name="DB2" value="db2"/> <property name="Oracle" value="oracle" /> <property name="MySQL" value="mysql"/> </databaseIdProvider>在 SQL 映射文件中引用數(shù)據(jù)庫服務器的別名即可:databaseId
<select id="selectBlog" resultType="com.atguigu.bean.Book" databaseId="mysql"> select id,title,author,price,sales,stock,img_path from book where id = #{id} </select><select id="selectBlog" resultType="com.atguigu.bean.Book" databaseId="oracle"> select id,title,author,price,sales,stock,img_path from book where id = #{id} </select>7. mappers
<!-- mappers里面可以有多個mapper標簽,每個mapper標簽都可以加載SQL映射文件或者Mapper接口 每個mapper標簽: 屬性: resource:用來加載SQL映射文件 url:一般不用 class:加載Mapper接口,有兩個要求: 要求:1.Mapper接口和SQL映射文件必須在同一個包下2.要求Mapper接口的名字和SQL映射文件的名字必須相同。 package標簽:批量加載mapper接口 要求:1.Mapper接口和SQL映射文件必須在同一個包下2.要求Mapper接口的名字和SQL映射文件的名字必須相同。 --> <mappers> <package name="com.atguigu.dao"/> </mappers>3.4 sql映射文件(重要)
1. 插入數(shù)據(jù)的時候獲取數(shù)據(jù)表的自增主鍵
有兩種方式:都要求參數(shù)類型為 pojo 類型: 第一種方式:只適用于數(shù)據(jù)表能自增主鍵的數(shù)據(jù)庫:mysql、sqlserver 在 insert 標簽上指定 useGeneratedKeys="true" keyProperty="id"(bean屬性)第二種方式:適用于所有的數(shù)據(jù)庫: <insert id="insert"> <!-- selectKey專門用來查詢主鍵 屬性: keyColumn:查詢數(shù)據(jù)表的哪個列 keyProperty:將查詢出來的主鍵封裝到pojo類的哪個屬性上 resultType: 主鍵的類型 order:表示該sql語句的執(zhí)行順序,AFTER表示在insert語句執(zhí)行之后執(zhí)行--> <selectKey keyProperty="id" keyColumn="id" resultType="integer" order="AFTER"> select last_insert_id() </selectKey> insert into book values(null,#{title},#{author},#{price},#{sales},#{stock},#{imgPath}) </insert>2. sql標簽
該標簽的作用:做 SQL 語句重用的
<!-- sql片段做sql語句重用 --> <sql id="querySql"> id,title,author,price,sales,stock,img_path </sql><select id="getBookById" resultType="com.atguigu.bean.Book"> select <include refid="querySql"></include> from book where id = #{id} </select>3. resultMap 標簽
當表的列名和 pojo 類的屬性名不對應的時候,怎么能映射上?
第一種方案:給表的列名起別名 第二種方案:在 mybatis-config.xml 配置 mapUnderscoreToCamelCase 設置 第三種方案:ResultMap 標簽 <!-- resultMap:做查詢結(jié)果映射--> <resultMap id="getBookByBidResultMap" type="com.atguigu.bean.Book"> <!-- 主鍵映射用id標簽:column屬性對應著數(shù)據(jù)表的列名,property對應著pojo類的屬性名 --> <id column="id" property="id"></id> <!-- 普通字段映射用result標簽 --><result column="title" property="title"></result><result column="author" property="author"></result><result column="price" property="price"></result><result column="sales" property="sales"></result> <!-- 當表的列名和pojo類的屬性名一致的時候,默認就能映射上,雖然這樣,但是實際開發(fā)中,建議寫出來了--> <result column="img_path" property="imgPath"></result> </resultMap><!--注意:select標簽的resultType屬性和resultMap屬性只能同時存在一個。--> <select id="getBookByBid" resultMap="getBookByBidResultMap"> select id,title,author,price,sales,stock,img_path from book where id = #{id} </select>ResultMap 標簽作用:
? 第一個:做結(jié)果映射
? 第二個:處理關聯(lián)表的映射的時候就必須使用這個標簽,這個功能是resultType屬性鎖不具備的,resultType屬性只能處理單表的映射。
4. #{}與${}的區(qū)別
${}類似于 javaweb 部分學過的 statement,是將參數(shù)直接拼接到 SQL 語句中的,這種是存在 SQL 注入問題的,是不安全的。#{}類似于 javaweb 部分學過的 preparestatement 對象,是以占位符、預編譯的方式將參數(shù)設置到 SQL 語句中的,不存在 SQL 注入問題.實際開發(fā)中,大部分情況,都使用#{},但是特殊情況下,就必須使用${},比如:獲取表名、排序字段、模糊查詢的時候也會用到${}。mapper接口:
public Book getBookByBid(@Param("id") Integer id,@Param("da") String tablename,@Param("orderByField")String orderByField,@Param("title")String title);sql 映射文件:
<select id="getBookByBid" resultMap="getBookByBidResultMap"> select id,title,author,price,sales,stock,img_path from ${da} where title like concat(concat('%','${title}'),'%') order by ${orderByField} desc limit 0,1 </select>接口參數(shù)
接口中各種各樣的參數(shù): 1.一個基本數(shù)據(jù)類型: int、Integer、String、boolean、float、double, :#{隨便寫} 2.多個基本類型的參數(shù)[兩個、兩個以上]:建議在每個普通參數(shù)前面加一個@Param注解,:#{@Param的value屬性值} 3.Bean對象 :#{bean對象的屬性名} 4.List<Bean>、Collection<Bean>、 :#{list[下標]} 5.Map: :#{map的key} 6.數(shù)組: :#{array[下標]} 7.復雜類型:上面任意組合得到:建議在每個普通參數(shù)前面加一個@Param注解, :#{param注解的value屬性值}接口的返回值
/** 1.基本類型:int、Integer、double、Double、boolean 增刪改: 只需要在接口中聲明返回值類型,在SQL映射文件中無須指定resultType屬性 查詢: 需要在接口中聲明返回值類型,在SQL映射文件中需要指定resultType屬性 2.pojo對象: 只需要在接口中聲明返回值類型,在SQL映射文件中的resultType屬性指定為pojo類的全類名 3.POJO對象列表:只需要在接口中聲明返回值類型,在SQL映射文件中的resultType屬性指定集合中元素的數(shù)據(jù)類型 4.Map類型: : 返回單行數(shù)據(jù):在接口中聲明返回值類型Map<String,Object>,,在SQL映射文件中的resultType屬性值為MAP類型返回多行數(shù)據(jù):在接口中聲明返回值類型Map<表中主鍵的類型,POJO類>,在SQL映射文件中的resultType屬性值為MAP **/ @MapKey("uid")//專門用來指定將表的哪一列作為Map的key map多行 public Map<Integer,User> getAllUsers();3.5 關聯(lián)查詢(重要)
表與表的關聯(lián)關系:一對一、一對多、多對一、多對多四種關聯(lián)關系
1 x對一[三種解決方案]
一對一
多對一:訂單項和訂單、員工和部門
需求:以員工和部門為例講解 x 對一的關聯(lián)關系。當查詢員工信息的時候,把該員工所屬的部門信息一起查詢出來。
表:
create table dept( did int primary key auto_increment comment '部門id', dept_name varchar(30) not null comment '部門名稱')create table employee( eid int primary key auto_increment comment '員工id', ename varchar(30) not null comment '員工名稱', did int, FOREIGN key(did) REFERENCES dept(did) )bean:
public class Department { //提供getter、setter、toString()private Integer did;private String deptName; }public class Employee {//提供getter、setter、toString()private Integer eid;private String ename;private Department department; }第一種解決方案:
<resultMap id="getEmployeeByEidResultMap" type="com.atguigu.bean.Employee"> <id column="eid" property="eid"/><result column="ename" property="ename"/> <!-- 第一種解決方案:連綴的方式 --> <result column="did" property="department.did"></result> <result column="dept_name" property="department.deptName"></result> </resultMap><select id="getEmployeeByEid" resultMap="getEmployeeByEidResultMap"> select e.eid,e.ename,d.did,d.dept_name from employee e left join dept d on e.did = d.did where e.eid =#{eid} </select>第二種解決方案:使用 association 標簽
<resultMap id="getEmployeeByEidResultMap" type="com.atguigu.bean.Employee"> <id column="eid" property="eid"/><result column="ename" property="ename"/> <!-- 第二種解決方案:使用association標簽:解決對x一關聯(lián)關系屬性: property:指定關聯(lián)的屬性名 javaType: 指定關聯(lián)屬性的類型 --><association property="department" javaType="com.atguigu.bean.Department"> <id column="did" property="did"></id><result column="dept_name" property="deptName"></result> </association> </ResultMap>第三種解決方案:分步查詢
EmployeeMapper.xml
<resultMap id="getEmployeeByEidResultMap" type="com.atguigu.bean.Employee"> <id column="eid" property="eid"/> <result column="ename" property="ename"/> <!--第三種解決方案:使用association標簽 select:表示將哪個select語句的返回結(jié)果賦值給關聯(lián)的屬性 column:當前sql語句調(diào)用另一個Sql的時候,傳遞的列名 --> <association property="department" select="com.atguigu.dao.DepartmentMapper.dddd" column="did"></association> </resultMap><select id="getEmployeeByEid" resultMap="getEmployeeByEidResultMap"> select eid,ename,did from employee where eid= #{eid} </select>DepartmentMapper.xml
<select id="dddd" resultType="com.atguigu.bean.Department"> select did,dept_name deptName from dept where did = #{did} </select>注意:對于分步查詢,存在懶加載機制。
懶加載分為:局部懶加載+全局懶加載兩種
局部懶加載:適合當前項目中只有個別 SQL 需要懶加載的時候使用。
在 association 標簽設置 fetchType:lazy[懶加載] | eager[立即加載,默認值]
全局懶加載: 適合當前項目中有較多的 SQL 需要懶加載的時候使用
在 mybatis 的全局配置文件中設置:
<settings> <!--開啟全局懶加載 --><setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings>2 X 對多[兩種解決方案]
x 對多關聯(lián)關系:
一對多:部門和員工、訂單和訂單項
多對多:學生和老師【中間表】
需求:以部門和員工為例,講解對多的關聯(lián)關系。對多的關聯(lián)關系都有兩種解決方案。查詢部門信息的時候,將該部門所有的員工信息一起查詢出來。
表:
create table dept( did int primary key auto_increment comment '部門id', dept_name varchar(30) not null comment '部門名稱' )create table employee( eid int primary key auto_increment comment '員工id', ename varchar(30) not null comment '員工名稱', did int, FOREIGN key(did) REFERENCES dept(did) )bean:
//員工表 public class Employee { //提供getter、setter、toString方法 private Integer eid;private String ename; }//部門表 public class Department {private Integer did;private String deptName;private List<Employee> emps; }第一種方案:
<resultMap id="getDepartmentWithEmployeesByDidResultMap" type="com.atguigu.bean.Department"> <result column="did" property="did"/><result column="dept_name" property="deptName"/> <!-- collection標簽用于處理對多的關聯(lián)關系。 屬性: property:指定關聯(lián)屬性的名字 ofType: 指定集合中元素的數(shù)據(jù)類型 --> <collection property="emps" ofType="com.atguigu.bean.Employee"> <result column="eid" property="eid"/><result column="ename" property="ename"/> </collection> </resultMap><select id="getDepartmentWithEmployeesByDid"resultMap="getDepartmentWithEmployeesByDidResultMap"> select d.did,d.dept_name,e.eid,e.ename from dept d left join employee e on d.did = e.did where d.did = #{dsdsds} </select>第二種解決方案:
<select id="queryEmployeesByDid" resultType="com.atguigu.bean.Employee"> select eid,ename from employee where did= #{ddsdsdsdsds} </select><resultMap id="getDepartmentWithEmployeesByDidResultMap" type="com.atguigu.bean.Department"> <result column="did" property="did"/><result column="dept_name" property="deptName"/> <!-- collection標簽用于處理對多的關聯(lián)關系。 屬性: property:指定關聯(lián)屬性的名字 ofType: 指定集合中元素的數(shù)據(jù)類型 select: 指定要引用的Select語句的id值 column: 調(diào)用另一條SQL語句的時候,要傳遞的數(shù)據(jù)列 --> <collection property="emps" select="queryEmployeesByDid" column="did"> </collection> </resultMap><select id="getDepartmentWithEmployeesByDid" resultMap="getDepartmentWithEmployeesByDidResultMap"> select did,dept_name from dept where did = #{did} </select>3.6 多對多 一對一表創(chuàng)建
1 多對多表的創(chuàng)建:
create table student( sid int primary key auto_increment, sname varchar(30) not null )create table teacher( tid int primary key auto_increment, tname varchar(30) not null )create table student_teacher( sid int, tid int, primary key(sid,tid), FOREIGN key(sid) REFERENCES student(sid), FOREIGN key(tid) REFERENCES teacher(tid) )2 一對一表的創(chuàng)建:
第一種方式:(在多對一的基礎上,對多的一端的外鍵加 unique 約束即可)
create table wife( id int primary key auto_increment, wifename varchar(30) not null )create table husband( hid int primary key auto_increment, husband_name varchar(30) not null, wid int unique, FOREIGN key(wid) REFERENCES wife(id) )第二種
create table wife( wid int primary key auto_increment, wname varchar(30) not null )create table husband( hid int primary key, husband_name varchar(30) not null, FOREIGN key(hid) REFERENCES wife(wid) )3.7 動態(tài)sql
所謂動態(tài) SQL:是指根據(jù)傳遞過來的不同參數(shù)生成不同的 SQL 語句。動態(tài) SQL 中主要包含以下標簽: ? if :相當于javaweb學過的<c:if>進行單分支判斷 ? choose (when, otherwise):相當于javaweb學過的<c:choose>進行多分支判斷 ? trim (where, set):trim可以對sql語句修改,where標簽可代替sql中where關鍵字,set標簽可代替sql語句中的set關鍵字。 ? foreach:類似javaweb學過的<c:foreach>遍歷集合使用的1 if 標簽
作用:相當于 javaweb 學過的<c:if>進行單分支判斷
需求:如果攜帶了標題,就用標題查,如果攜帶了作者信息,就用作者查詢,如果攜帶了價格查詢,如果這些參數(shù)都攜帶了,就用所有的參數(shù)查詢。總之,攜帶了哪些條件,就使用哪些條件查詢
<select id="getBookByMap" resultType="com.atguigu.bean.Book"> select id,title,author,price,sales,stock,img_path imgPath from book where <if test="title != null and title != '' "> title = #{title} </if> <if test="author != null and author != '' "> and author = #{author} </if> <if test="price > 0.0"> and price = #{price} </if> </select>注意:上述的 SQL 語句還是有問題的。當我們不傳遞 title 過來的時候,where 后面會多出一個 and 關鍵字,
解決:
第一種解決方案:在 where 關鍵字后面加一個 1=1
<select id="getBookByMap" resultType="com.atguigu.bean.Book"> select id,title,author,price,sales,stock,img_path imgPath from book where 1=1 <if test="title != null and title != '' "> and title = #{title} </if> <if test="author != null and author != '' "> and author = #{author} </if> <if test="price > 0.0"> and price = #{price} </if> </select>第二種解決方案:使用 where 標簽代替 where 關鍵字
2 where 標簽
where 標簽就是專門用來代替 where 關鍵字的,where 標簽默認能將 where 標簽內(nèi)部的 sql 語句最前面的 and 或者 or 關鍵字給去掉。
<select id="getBookByMap" resultType="com.atguigu.bean.Book"> select id,title,author,price,sales,stock,img_path imgPath from book <where> <if test="title != null and title != '' "> title = #{title} </if> <if test="author != null and author != '' "> and author = #{author} </if> <if test="price > 0.0"> and price = #{price} </if> </where> </select>注意:目前還有問題,就是如果 and 或者 or 關鍵字不是寫在前面,而是寫在后面,where標簽也不能將 where 標簽內(nèi)部的 sql 語句中的最后面的 and 或者 or 關鍵字給去掉。那如果就像把它去掉,怎么辦呢?這里可以借助于 trim 標簽
3 trim 標簽
trim 標簽類似于 java 基礎中字符串的 trim 方法,可以對 sql 語句最前面或者最后面進行修改
<select id="getBookByMap" resultType="com.atguigu.bean.Book"> select id,title,author,price,sales,stock,img_path imgPath from book where <!-- trim標簽可以修改sql語句 屬性: prefix:前綴,表示trim標簽內(nèi)部的sql拼接完畢之后,最前面加的關鍵字 prefixOverrides:前綴覆蓋,表示可以指定一個sql關鍵字將trim標簽內(nèi)部的 sql拼接完畢之后最前面多出來的指定關鍵字給刪除掉。suffix;后綴,表示trim標簽內(nèi)部的sql拼接完畢之后,最后面加的關鍵字 suffixOverrides:后綴覆蓋。表示可以指定一個sql關鍵字將trim標簽內(nèi)部的 sql拼接完畢之后最后面多出來的指定關鍵字給刪除掉。 --> <trim prefixOverrides="and|or" suffixOverrides="and|or"> <if test="title != null and title != '' ">title = #{title} and</if><if test="author != null and author != '' "> author = #{author} and</if><if test="price > 0.0">price = #{price}</if> </trim> </select>4 set 標簽
set 標簽作用:可以代替 set 關鍵字,set 標簽可以將 set 標簽內(nèi)部最后面的,給去掉
需求:如果攜帶了標題就修改標題,如果攜帶了作者信息就修改作者,如果都攜帶了,都修改。
<update id="updateBookByMap"> update book set <if test="title != null and title != '' "> title = #{title}, </if> <if test="author != null and author != '' "> author= #{author} </if> where id=#{id} </update>針對這種問題,有兩種解決方案:
第一種解決方案:使用 set 標簽代替 set 關鍵字
<update id="updateBookByMap"> update book <set> <if test="title != null and title != '' "> title = #{title}, </if> <if test="author != null and author != '' "> author= #{author} </if> </set> where id=#{id} </update>第二種解決方案:使用 trim 標簽
<update id="updateBookByMap"> update book <trim prefix="set" prefixOverrides="," suffixOverrides=","> <if test="title != null and title != '' ">title = #{title},</if><if test="author != null and author != '' "> author= #{author}</if> </trim> where id=#{id} </update>5 choose (when, otherwise)
choose (when, otherwise):相當于 javaweb 學過的<c:choose>進行多分支判斷需求:如果攜帶書名,就用書名查詢,如果攜帶了作者就用作者查詢,如果攜帶了價格,就用價格查詢。如果這三個條件都攜帶了,就按著順序查詢(只能走其中條件。) choose、when、otherwise 使用是有順序的。只會走其中一個條件
<select id="getBooksByMap" resultType="com.atguigu.bean.Book"> select id,title,author,price,sales,stock,img_path imgPath from book where <choose> <when test="title != null and title != ''"> title = #{title} </when> <when test="author != null and author != ''"> author = #{author} </when> <when test="price != null ">price = #{price} </when> <otherwise>1=1 </otherwise> </choose> </select>6 foreach 標簽
foreach 標簽:類似 javaweb 學過的<c:foreach>遍歷集合|數(shù)組使用的
批量查詢操作:
遍歷集合
<select id="getBooksByIds" resultType="com.atguigu.bean.Book"> select id,title,author,price,sales,stock,img_path imgPath from book where id in <!-- foreach標簽:遍歷集合和數(shù)組 collection:表示要遍歷的集合 item:指定一個變量接收集合中遍歷出來的元素 separator:指定元素與元素之間的分隔符 open:當foreach標簽遍歷完集合中所有的元素之后,在元素的最前面加的sql字符串 close:當foreach標簽遍歷完集合中所有的元素之后,在元素的最后面加的sql字符串 --> <foreach collection="list" item="id" separator="," open="(" close=")"> #{id} </foreach> </select>遍歷數(shù)組:
<select id="getBooksByIds" resultType="com.atguigu.bean.Book"> select id,title,author,price,sales,stock,img_path imgPath from book where id in <foreach collection="array" item="id" separator="," open="(" close=")"> <!--array-->#{id} </foreach> </select>批量插入操作
<insert id="batchInsert"> insert into user values <foreach collection="list" item="user" separator="," > <!--按照表的順序-->(#{user.uid},#{user.username},#{user.password},#{user.email}) </foreach> </insert>7 特殊字符
遇到&,“”,<等 mybatis 不支持的特殊字符,換成他們的實體名稱。(W3SCHOOL 手冊)
針對 SQL 語句中的特殊字符,有兩種解決方案:
第一種:使用特殊字符的實體名稱
第二種:使用<![CDATA[sql 語句]]>
3.8 逆向工程
generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><!-- 無Example等內(nèi)容<context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat"> --><!-- 有Example查詢條件內(nèi)容 --><context id="testTables" targetRuntime="MyBatis3"><commentGenerator ><!-- 是否去除自動生成的注釋 true:是 : false:否 --><property name="suppressAllComments" value="true" /></commentGenerator><!--數(shù)據(jù)庫連接的信息:驅(qū)動類、連接地址、用戶名、密碼 --><jdbcConnection driverClass="com.mysql.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/bookstore?serverTimezone=GMT%2B8&useSSL=false"userId="root"password="abc123"></jdbcConnection><!-- 默認false,把JDBC DECIMAL 和 NUMERIC 類型解析為 Integer,為 true時把JDBC DECIMAL 和NUMERIC 類型解析為java.math.BigDecimal --><javaTypeResolver><property name="forceBigDecimals" value="false" /></javaTypeResolver><!-- targetProject:生成Entity類的路徑 --><javaModelGenerator targetProject=".\src\main\java" targetPackage="com.fjw.bean"><!-- enableSubPackages:是否讓schema作為包的后綴 --><property name="enableSubPackages" value="false" /><!-- 從數(shù)據(jù)庫返回的值被清理前后的空格 --><property name="trimStrings" value="true" /></javaModelGenerator><!-- targetProject:XXXMapper.xml映射文件生成的路徑 --><sqlMapGenerator targetProject=".\src\main\java" targetPackage="com.fjw.dao"><!-- enableSubPackages:是否讓schema作為包的后綴 --><property name="enableSubPackages" value="false" /></sqlMapGenerator><!-- targetPackage:Mapper接口生成的位置 --><javaClientGenerator type="XMLMAPPER" targetProject=".\src\main\java" targetPackage="com.fjw.dao"><!-- enableSubPackages:是否讓schema作為包的后綴 --><property name="enableSubPackages" value="false" /></javaClientGenerator><!-- 數(shù)據(jù)庫表名字和我們的entity類對應的映射指定 --><table tableName="books" domainObjectName="Book"/><!-- 有些表的字段需要指定java類型<table schema="" tableName=""><columnOverride column="" javaType="" /></table> --></context> </generatorConfiguration>pom.xml
<dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.38</version></dependency><!-- mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.6</version></dependency><!-- mybatis-generator-core --><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.3.7</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.7</version><configuration><configurationFile>src/main/resources/generatorConfig.xml</configurationFile><verbose>true</verbose><overwrite>true</overwrite></configuration><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.38</version></dependency></dependencies></plugin></plugins></build>在maven的plugins 點擊即可生成
4 ssm整合
第一步:導入 jar 包: Spring+SpringMVC+MyBatis+MyBatis-spring 、 mysql 、 druid 、 JSTL 、Commons-fileupload、Commons-io、Json 的 3 個 jar 包、log4j第二步:在 web.xml 文件中配置 Spring 的 ContextLoaderListener,SpringMVC的前端控制器、兩個 Filter第三步: 創(chuàng)建 springmvc.xml掃描包[@controller+@ControllerAdvice]配置內(nèi)部資源視圖解析器 mvc:default-servlet-handler mvc:annotation-driven創(chuàng)建 applicationContext.xml掃描包[除了@controller+@ControllerAdvice] context:property-placeholder location 屬性配置數(shù)據(jù)源對象配置數(shù)據(jù)源事務管理器tx:annotation-driven transaction-manager=”” SqlSessionFatcoryBean 對象dataSource:configLocation:加載 mybatis 的全局配置文件的MapperScannerConfigurer 對象:批量掃描 dao 層的 mapper 接口創(chuàng)建 mybatis-config.xml需要在配 第四步:編寫軟件三層架構(gòu),并進行測試web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><!--1 配置spring的ContextLoaderListener--><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></context-param><!--2 配置springmvc前端控制器--><servlet><servlet-name>DispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>DispatcherServlet</servlet-name><url-pattern>/</url-pattern><!--不會匹配到*.jsp--></servlet-mapping><!--3 配置字符編碼攔截器--><filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!--4 將post轉(zhuǎn)換為put|delete--><filter><filter-name>HiddenHttpMethodFilter</filter-name><filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class></filter><filter-mapping><filter-name>HiddenHttpMethodFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping> </web-app>applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"><!--1 配置掃描包--><context:component-scan base-package="com.xx"><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/><context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/></context:component-scan><!--2 加載jdbc配置文件--><context:property-placeholder location="classpath:jdbc.properties"/><!--3 配置數(shù)據(jù)源信息--><bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource" ><property name="url" value="${jdbc.jdbcUrl}"/><property name="driverClassName" value="${jdbc.driverClass}"/><property name="username" value="${jdbc.userName}"/><property name="password" value="${jdbc.password}"/></bean><!--4 配置數(shù)據(jù)源事務管理器--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="druidDataSource"></property></bean><!--5 開啟基于注解的事務支持--><tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven><!--6 sqlSessionFactoryBean--><bean class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="druidDataSource"></property><property name="configLocation" value="classpath:mybatis-config.xml"></property></bean><!--7 MapperScannerConfigurer 掃描--><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.xx.dao"></property></bean> </beans>springMVC.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--1 配置掃描controller use-default-filters="false"不在全包掃描,只掃下面包括的--><context:component-scan base-package="com.xx" use-default-filters="false"><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/><context:include-filter type="annotation"expression="org.springframework.web.bind.annotation.ControllerAdvice"/></context:component-scan><!--2 配置內(nèi)部資源視圖解析器--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/"></property><property name="suffix" value=".jsp"></property></bean><!--多部件解析器 文件上傳 id值是固定,變了就錯--><bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!--指定文件上傳的編碼格式--><property name="defaultEncoding" value="UTF-8"></property><!--指定文件上傳文件的最大值--><property name="maxUploadSize" value="#{500*1024*1024}"></property></bean><!--3 處理靜態(tài)資源--><mvc:default-servlet-handler/><!--4.處理靜態(tài)資源帶來的接口不能訪問--><mvc:annotation-driven/> </beans>rScannerConfigurer">
總結(jié)
- 上一篇: [《回家寄事》闲笔记事集]2010年1月
- 下一篇: 计算机家庭网络共享,教大家家庭局域网如何