SSM總結

来源:https://www.cnblogs.com/ATRIQAQ/archive/2022/12/09/16967996.html
-Advertisement-
Play Games

SSM Spring IOC(控制反轉)& DI(依賴註入) IOC是容器,用來裝Spring創建的Bean對象。 Bean註入方式 Set方法註入 構造器註入 @Autowared自動註入 <!-- SpringBean的註入方式 --> <!-- 手動裝配 --> <!-- == set方法註入 ...


SSM

目錄

Spring

IOC(控制反轉)& DI(依賴註入)

IOC是容器,用來裝Spring創建的Bean對象。

Bean註入方式

  • Set方法註入
  • 構造器註入
  • @Autowared自動註入
<!--     SpringBean的註入方式  -->
<!--      手動裝配  -->
<!--      ==  set方法註入    -->
    <bean id="hello" class="com.dzqc.smbms.entity.SUser">
        <property name="userCode" value="hello"></property>
        <property name="userName" value="Spring"></property>
        <property name="role">
            <bean class="com.dzqc.smbms.entity.SRole">
                <property name="roleCode" value="這裡是註入的實例對象"></property>
                <property name="roleName" value="這裡是註入的實例對象的值"></property>
            </bean>
        </property>
        <property name="role" ref="myRole"></property>
    </bean>

    <bean name="myRole" class="com.dzqc.smbms.entity.SRole">
        <property name="roleName" value="管理員"></property>
        <property name="roleCode" value="SMBMS_ADMIN"></property>
    </bean>

<!--      ==  帶參構造器註入  -->
    <bean name="constructor" class="com.dzqc.smbms.entity.SUser">
        <constructor-arg name="userName" value="這是通過構造器註入的userName"></constructor-arg>
        <constructor-arg name="userCode" value="這是通過構造器註入的userCode"></constructor-arg>
    </bean>

    <!--  自動裝配  -->
    <!--  ==  配置包掃描,並使用註解進行註入  -->
    <context:component-scan base-package="com.dzqc.smbms">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

IOC和DI的區別:

IOC是什麼:是控制反轉,將new對象的權力由調用程式交給第三方IOC容器,控制權被轉移給了IOC容器,在調用程式看來,new對象的動作由主動變成了被動,所以叫做控制反轉。

DI是什麼:依賴註入,將IOC容器中new出來的對象註入進調用程式。

IOC和ID的區別:IOC和DI是一體的,DI是IOC的另一種表現形式,是同一事件不同層面的解讀。

AOP(面向切麵編程)

一、AOP編程思想

1.1 什麼是AOP

​ AOP (Aspect Orient Programming),直譯過來就是 面向切麵編程。AOP是一種編程思想,基於面向對象編程思想(OOP)的補充。面向對象編程將程式抽象成了各個切麵。

1.2 為什麼需要AOP

​ 在開發過程中,存在某段多次重覆的代碼,以面向過程編程方式的話,我們會將這段代碼抽象成一個方法,在需要的位置調用該方法。當這段代碼需要修改時,我們就只需要改變這一個方法就夠了。

​ 但需求不是一成不變的,如果後期需要新增一個需求,又需要在多處進行修改,就需要再抽象一個方法,然後在需要的位置再分別調用這個方法。又或者,我們在業務過程中刪除這個方法,我們就需要刪除掉每一個地方的調用。

​ 在這種情況之下,我們就可以通過使用AOP來解決。

1.3 AOP實現方法分類

​ 首先我們要知道AOP的目的,AOP要達到在開發者不修改源代碼的前提下,去為系統中的業務添加某種通用的功能。

​ AOP的實現方式大致可以分為兩類:

  • 靜態AOP實現
    • 靜態AOP實現是在編譯階段就對程式源代碼進行修改,生成了靜態的AOP代理類,即生成的*.class文件已經被修改,需要使用特定的編譯方式進行編譯。代表性的靜態AOP實現方式如:AspectJ
  • 動態AOP實現
    • AOP框架在運行階段動態生成代理對象。即在記憶體中以JDK動態代理的方式,或CGlib動態生成AOP代理類,典型的技術如:SpringAOP。
類別 機制 原理
靜態AOP 靜態織入 在編譯前,切麵直接以位元組碼的形式編譯入目標代碼的位元組碼文件中,對性能無影響,但靈活性不夠。
動態AOP JDK動態代理 在運行期間,目標類載入之後為介面動態生成代理類,將切麵織入到代理類中,相對於靜態AOP更靈活一些。但切入點需要實現介面,對系統的性能有一定影響。
動態位元組碼生成 CGlib 在運行期間,目標類載入之後,動態生成目標類的子類,然後將切麵的邏輯加入到子類中,相對於JDK動態代理的方式,CGlib不需要介面也可以實現織入,但是當擴展類的實例方法使用final修飾時無法進行織入。

二、AOP的專有名詞

AOP中的特性術語大致有一下幾種:

  • 增強|建議(Advice):AOP框架中的增強處理,通知表述了切麵在何時執行以及如何執行增強處理。
  • 連接點(join point) :連切點表示應用程式執行過程中能夠插入切麵的一個點,這個點可以是方法的調用、異常的拋出。在SpringAOP中,連接點總是方法的調用。
  • 切點(PointCut):可以插入增強處理的連接點。
  • 切麵(Aspect):切麵是增強和切點的結合。
  • 引入(Introduction):引入允許我們想現有的類添加新的方法或屬性。
  • 織入(Weaving):將增強處理添加到目標對象中,並創建一個被增強對象,這個過程就是織入。
  • 目標對象(Target):增強的目標對象,原始對象。
  • 代理對象(Proxy):加入了增強的對象,是由AOP增強後生成的代理對象。

SpringAOP在AOP的基礎上又多出幾個延伸概念:

  • 前置增強(MethodBeforeAdvice):在連接點執行前進行增強。
  • 環繞增強(MethodInterceptor):在連接點前後都執行增強。
  • 異常增強(ThrowsAdvice):連接點拋出異常時進行增強。
  • 返回值增強(AfterReturingAdvice):連接點產生返回值後進行增強。

三、認識SpringAOP

3.1 SpringAOP的特點

​ AOP的框架有很多,實現方式各不相同,Spring的AOP則是通過動態代理進行實現的。下麵簡單對代理模式進行介紹。

3.2 SpringAOP使用與實現
  • Spring原生API:實現 MethodBeforeAdvice介面、AfterReturningAdvice介面,重寫對應的方法,並配置增強類與切入點類,可以實現AOP操作。
  • 自定義切麵類:自定義切麵類與增強方法,使用配置聲明切麵類並關聯切點,實現AOP
  • 註解實現AOP:使用@Aspect聲明切麵類,@Pointcut聲明切入點,使用@Before@After....註解實現增強方法,並配置自動代理,來實現AOP。

Execution表達式:

​ 聲明具體方法的位置的表達式 :返回值 包路徑.類名.方法名(參數列表)

代理模式

​ 代理模式分為兩種:

  • 靜態代理:需要為每個角色創建對應的代理對象。
  • 動態代理:自動為每個目標角色生成對應的代理對象。

靜態代理

​ 被代理類介面:

package com.dzqc.smbms.proxy;

/**
 * 游戲介面
 */
public interface Game {

    public void gameStart();

    public void gameOver();
}

被代理類:

package com.dzqc.smbms.proxy;

public class Mario implements Game{

    @Override
    public void gameStart() {
        System.out.println("超級馬利奧,游戲開始!");
    }

    @Override
    public void gameOver() {
        System.out.println("夠不著旗桿,游戲結束");
    }
}

代理類:

package com.dzqc.smbms.proxy;

/**
 * 本類為 靜態代理 類
 * 代理類 需要 持有 目標對象
 */
public class GameStaticProxy implements Game{
    private Game targetGame;

    public Game getProxy(Game targetGame){
        this.targetGame = targetGame;
        return this;
    }
    @Override
    public void gameStart() {
        System.out.println("游戲機啟動");
        System.out.println("游戲啟動!");
        targetGame.gameStart();
        System.out.println("游戲進行中,mario他跳起來了");
    }
    @Override
    public void gameOver() {
        System.out.println("mario 打敗了魔王,找到了旗桿,要爬旗桿。 ");
        targetGame.gameOver();
        System.out.println("真菜,不玩了,破游戲什麼時候關服!");
    }
}

測試類:

package com.dzqc.smbms.proxy;

import org.junit.Test;

import java.lang.reflect.Proxy;

public class ProxyTest {

    @Test
    public void staticProxy(){
        Mario mario = new Mario();
        GameStaticProxy gameStaticProxy = new GameStaticProxy();
        Game marioProxy = gameStaticProxy.getProxy(mario);

        marioProxy.gameStart();

        marioProxy.gameOver();

    }
}

測試結果:

游戲機啟動
游戲啟動!
超級馬利奧,游戲開始!						//原始內容
游戲進行中,mario他跳起來了
mario 打敗了魔王,找到了旗桿,要爬旗桿。 
夠不著旗桿,游戲結束						 //原始內容
真菜,不玩了,破游戲什麼時候關服!

JDK動態代理

​ JDK動態代理的實現邏輯大致如下:

介面與被代理類與上述一致

代理類:

package com.dzqc.smbms.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * JDK代理類
 */
public class GameJDKProxy implements InvocationHandler {

    private Game targetGame;
    public GameJDKProxy(Game targetGame){
        this.targetGame = targetGame;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String name = method.getName();

        if (name.equals("gameStart")){
            Object o = gameStart(method, args);
        }else {
            Object o = gameOver(method, args);
        }
        return null;
    }
    private Object gameStart(Method method , Object[] args) throws Throwable{
        System.out.println("mario游戲啟動了");
        Object invoke = method.invoke(targetGame, args);
        System.out.println("正在操作mario通水管");
        return null;
    }
    private Object gameOver(Method method , Object[] args) throws Throwable{
        System.out.println("水管打不通");
        Object invoke = method.invoke(targetGame, args);
        System.out.println("什麼破游戲!");
        return null;
    }

}

測試類:

package com.dzqc.smbms.proxy;

import org.junit.Test;

import java.lang.reflect.Proxy;

public class ProxyTest {
    @Test
    public void jdkProxy(){
        Mario mario = new Mario();
        GameJDKProxy gameJDKProxy = new GameJDKProxy(mario);
//        使用JDK動態代理類獲取代理對象
        Game marioProxy  = (Game) Proxy.newProxyInstance(
                this.getClass().getClassLoader(), //類載入器
                new Class[]{Game.class},  // 代理介面的位元組碼文件
                gameJDKProxy// 自己的代理類,進行目標方法擴充
        );
        marioProxy.gameStart();
        marioProxy.gameOver();
    }
}

測試結果

mario游戲啟動了
超級馬利奧,游戲開始!				//原始內容
正在操作mario通水管
水管打不通
夠不著旗桿,游戲結束				 //原始內容
什麼破游戲!

​ 由上述代碼不難看出,動態代理的實現需要以下幾點:

  1. JDK動態代理需要聲明介面。想要創建一個動態代理類,就必須給這個類聲明一個介面,否則無法在Proxy.newProxyInstance時傳入對應的介面類位元組碼文件。
  2. 在代理類中需要通過構造傳入原有的bean,因為處理完附加功能外,需要執行原有bean中的方法,以實現代理的目的。

CGlib動態代理

代理類:

package com.dzqc.smbms.proxy;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class GameCglibProxy implements MethodInterceptor {

    private Game targetGame;
    public GameCglibProxy(Game targetGame){
        this.targetGame = targetGame;
    }

    /**
     * 獲取代理對象
     * @return
     */
    public Game getProxy(){
//        獲取cglib操作類
        Enhancer enhancer = new Enhancer();
//        指定代理類 的 父類類型,要代理哪個類就使用哪個類做代理類的父類
        enhancer.setSuperclass(Mario.class);
//        指定代理對象,把當前代理類作為代理對象
        enhancer.setCallback(this);
//        創建並返回代理對象
        return (Game) enhancer.create();
    }

    /**
     * 代理增強的實際操作處
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        String name = method.getName();
        if (name.equals("gameStart")){
            gameStart(method , objects);
        }else {
            gameOver(method , objects);
        }
        return null;
    }

    private Object gameStart(Method method , Object[] args) throws Throwable{
        System.out.println("魂鬥羅啟動!!!!");
        Object invoke = method.invoke(targetGame, args);
        System.out.println("正在操作Mario和魂鬥羅兄弟決鬥");
        return null;
    }
    private Object gameOver(Method method , Object[] args) throws Throwable{
        System.out.println("Mario挖了下水道,坑了魂鬥羅兄弟");
        Object invoke = method.invoke(targetGame, args);
        System.out.println("不要串台!");
        return null;
    }

}

測試類:

package com.dzqc.smbms.proxy;

import org.junit.Test;

import java.lang.reflect.Proxy;

public class ProxyTest {
    @Test
    public void cglibProxy(){
        Mario mario = new Mario();
        GameCglibProxy gameCglibProxy = new GameCglibProxy(mario);
        Game proxy = gameCglibProxy.getProxy();
        proxy.gameStart();
        proxy.gameOver();
    }
}

測試結果:

魂鬥羅啟動!!!!
超級馬利奧,游戲開始!					//原始內容
正在操作Mario和魂鬥羅兄弟決鬥
Mario挖了下水道,坑了魂鬥羅兄弟
夠不著旗桿,游戲結束					 //原始內容
不要串台!

​ 由上述代碼不難看出,CGlib在進行動態代理的過程中,對被實現的類要求較少,而且更為靈活,使用者可以根據實際情況進行選擇。

SPring MVC

MVC是什麼?MVC是設計模式,包含Model(模型)、View(視圖)、Controller(控制器)。

SpringMVC就是基於MVC設計模式創建的一個控制層框架,用來簡化視圖與後臺的數據交互工作,並且規範開發方式。SpringMVC是對Servlet的封裝,可將SpringMVC的本質看作Servlet。

SpringMVC核心組件

  • 前端控制器|中央處理器(DispatcherServlet):用來調度整個MVC的請求走向。
  • 處理器適配器(HandlerAdapter):用來適配請求路徑對應的處理器
  • 處理器映射器(HandlerMapping):用來查找請求路徑對應的處理器方法
  • 處理器(Controller | Handler):處理請求的方法
  • 視圖解析器(ViewResolver):解析視圖、返迴路徑、請求轉發與響應的解析器
  • 視圖(View):頁面
  • 攔截器(Interceptor):攔截請求

SpringMVC第一個程式

處理請求以及響應

參數傳遞

類需要使用@Controller註解,在類中聲明一個Handler方法,在方法的參數列表中聲明需要的參數,在Handler方法被調用時,就可以正確傳入對應的參數。

  • 常用簡單數據類型:String,Integer,Char,Boolean,Byte,Short,Long,Float,Double。
  • 複雜數據類型:
    • 對象:對象在進行參數傳遞時,參數列表中聲明的為對象,在傳參的過程中,傳遞的是對象中聲明的屬性名。
    • 數組:數組在進行傳參時,數組的參數名需要多次出現,每次出現給數組賦一個 值。
    • List集合:在進行參數傳遞時,因為List集合是個介面,所以需要在List類型的參數前加上@RequestParam註解,在參數傳遞時,與數組傳參方式一致。
    • map集合:在進行參數傳遞時,需要加上@RequestParam註解,參數在拼接時,只需將key和value的值按照普通傳參的方式拼接在地址欄或參數列表中。

響應 頁面跳轉

  1. 只響應數據:數據介面,在Handler方法上需要添加@ResponseBody註解,添加完成後,返回值不會被視圖解析器進行解析,在返回時可以按照正常的數據進行返回。
  2. 預設頁面返回:預設的響應方式,本質上是請求轉發,在Handler方法進行return後,會將返回的數據轉發至DispatcherServlet,然後由DispatcherServlet調度視圖解析器,解析返回值中的數據與視圖並響應。
  3. 重定向:重定向可以重定向到任意路徑,只需要在返回值上、ModelAndView的視圖名前 加上 redirect,這裡的重定向與Servlet的重定向功能保持一致,流程有變動。在Handler(處理器)方法進行返回後,將請求轉發至DispatcherServlet(中央處理器),由DispatcherServlet(中央處理器)調度HttpServletResponse(響應),由HttpServletResponse(響應)進行重定向操作。

SpringMVC基本配置

在web.xml種配置 dispatcherServlet

  <!--  配置中央處理器,與Servlet一起初始化  -->
  <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*:spring-mvc.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>



  <!--  配置SpringIOC容器  -->
  <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>

在Spring文件當中配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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
">
    <!--  配置包掃描,掃描所有使用Controller註解的類  -->
    <context:component-scan base-package="com.dzqc.smbms">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    

    <!--  處理器適配器  -->
    <bean name="handlerAdapter"
          class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>

    <!--  處理器映射器  -->
    <bean name="handlerMapping"
          class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>


    <!--  視圖解析器  -->
    <bean name="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/views/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--  配置靜態資源過濾器  -->
    <mvc:default-servlet-handler/>
    <mvc:resources location="/statics/" mapping="/static/*"></mvc:resources>


    <!--  文件上傳解析器  -->
    <bean name="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--  最大支持文件大小,此處配置50MB大小限制  -->
        <property name="maxUploadSize" value="52428800"></property>
    </bean>
</beans>

SpringMVC文件上傳

依賴:

<!--  文件上傳  -->
<dependency>
  <groupId>commons-fileupload</groupId>
  <artifactId>commons-fileupload</artifactId>
  <version>1.4</version>
</dependency>

Restful風格介面

Rest註解:

  • @RestController
  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PathVariable

SpringMVC工作流程

準備工作:

/*  在SpringMVC首次刷新或重新載入時,會調用SpringMVC初始化策略  */
protected void onRefresh(ApplicationContext context) {
    this.initStrategies(context);
}
/**  初始化策略方法  */
protected void initStrategies(ApplicationContext context) {
    this.initMultipartResolver(context);       		// 初始化文件上傳解析器
    this.initLocaleResolver(context); 	 			// 初始化本地解析器
    this.initThemeResolver(context);	 			// 初始化中心解析器
    this.initHandlerMappings(context);   			// 初始化處理器映射器
    this.initHandlerAdapters(context);   			// 初始化處理器適配器
    this.initHandlerExceptionResolvers(context);    // 初始化處理器異常解析器
    this.initRequestToViewNameTranslator(context);  // 初始化 請求視圖 翻譯器
    this.initViewResolvers(context);				// 初始化視圖解析器
    this.initFlashMapManager(context);				// 初始化 映射刷新管理器
}

2:請求處理流程

  1. DispathcerServlet(前端控制器)接收請求DispatcherServlet 通過 doService()方法 接收用戶請求。調用 doDispatch() 方法進行請求調度。
  2. DispatcherServlet(前端控制器)調用HandlerMapping(處理器映射器):DispatcherServlet 通過getHandler() 調用HandlerMapping獲取HandlerExecutionChain
  3. HandlerMapping將(HandlerExecutionChain)處理器執行鏈返回給DispatcherServlet
  4. DispathcerServlet(前端控制器)通過HandlerAdapter(處理器適配器),獲取對應的Handler處理器方法。
  5. HandlerAdapter(處理器適配器)調用Handler處理器方法,處理用戶請求。
  6. Handler處理器方法將返回值返回給HandlerAdapter(處理器適配器)
  7. HandlerAdapter將Handler處理器方法的返回值以ModelAndView的形式返回給DispatherServlet:
  8. DispatcherServlet將ModelAndView交給ViewResolver(視圖解析器)解析。
  9. ViewResolver(視圖解析器)將ModelAndView中的數據渲染到View(視圖)中。
  10. ViewResolver返回的視圖信息到DispatcherServlet。
  11. DispatcherServlet將視圖信息及返回值返回給客戶端。

image-20221204094023826

MyBAtis

​ MyBatis是一款輕量級的ORM(對象關係映射)(持久化)框架,能夠將JDBC相關的持久化代碼通過配置文件的形式實現,提高開發效率。

實現原理:工廠模式

手機工廠:MI,IPHONE,HUAWEI

簡單工廠

工廠對象

抽象實體

具體實體

工廠方法

抽象工廠

抽象產品

實體工廠

實體產品

抽象工廠

MyBatis基本應用

MyBatis使用分為

  • 配置文件(mybatis-config.xml)
  • mapper介面
  • 與mapper介面對應的mapper.xml映射文件

MyBatis的基本配置(MyBatis-config.xml)

MyBatis數據源配置
<!--  環境配置標簽 default中引用的為預設使用的環境  -->
<environments default="development">
    <!--  環境標簽 id 唯一,不可重覆  -->
    <environment id="development">
        <!--  事務管理器配置  -->
        <transactionManager type="JDBC"/>
        <!--  數據源配置 type預設為POOLED(預設啟用資料庫連接池模式) ,UNPOOLED 不啟用連接池  -->
        <dataSource type="POOLED">
            <!--  屬性標簽,該處屬性為數據源配置屬性  -->
            <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/smbms_3"/>
            <property name="username" value="root"/>
            <property name="password" value="root"/>
        </dataSource>
    </environment>
</environments>
資料庫連接池 (druid c3p0)
映射文件配置
<mappers>
    <!--  映射文件的地址,引用相對路徑  -->
    <mapper resource="mappers/SUserMapper.xml"></mapper>
</mappers>
其他配置
    <!--  MyBatis別名配置 只能配置實體類  -->
    <typeAliases>
<!--        <typeAlias type="com.dzqc.smbms.entity.SUser" alias="u"></typeAlias>-->
        <package name="com.dzqc.smbms.entity"/>
    </typeAliases>

    <settings>
        <!--  配置控制台日誌組件  -->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
MyBatis整合Log4J

MyBatis主要構件

獲取資源:Resources.getResourceAsStream("MyBatis-config.xml");

SqlSessionFactoryBuilder:構建工廠的建築隊,需要給資源後,調用build方法才能構建工廠。

SqlSessionFactory:工廠建好後,調用openSession方法,產出SqlSession

SqlSession:產出的SqlSession可以通過Mapper介面的位元組碼(.class)來獲取SqlSession中生產的代理對象,從而操作資料庫。

MyBatis映射文件

基本標簽

<select id="唯一,不可重覆" parameterType="參數類型" resultType="返回值類型" resultMap=""
        >查詢SQL</select>

<insert id="唯一,不可重覆" parameterType="" keyColumn="" keyProperty="" useGeneritedKeys="true">插入語句</insert>
<update id="唯一,不可重覆" parameterType="" >修改語句</update>
<delete id="唯一,不可重覆" parameterType="" >刪除語句</delete>

動態SQL

  • 判斷條件成立時,會向SQL後拼接的條件語句
  • 自動判斷,如果where中包含的有任意一個或多個成立,就會自動向SQL後拼接 where , 並將中的拼接語句之前的關鍵字進行適當的截取。
  • :拼接SQL的動態欄位,常用屬性有 perfix , suffix , perfixOverrides,suffixOverrides。
  • :自動拼接Set關鍵字,並截取中的尾碼內容。
  • :column:要遍歷的迴圈體內容,item:每次迴圈到的元素,open:開始時自動拼接的內容,close:結束時自動拼接的內容,seprector:分隔符,自動在每個元素後面拼接的內容。

ResultMap

resultMap是MyBatis實現ORM特性的一個最重要的標簽。

基礎查詢 - 基本映射

代表主鍵列 :column - 資料庫列名 , property:實體類屬性名

普通列 :column - 資料庫列名 , property:實體類屬性名

外聯查詢 - 一對一查詢
<association property="role" javaType="srole" column="u.userRole">
    <id column="userRole" property="id"></id>
    <result column="roleCode" property="roleCode"></result>
    <result column="roleName" property="roleName"></result>
</association>

<association property="role" javaType="srole" column="userRole"
            select="com.dzqc.smbms.mapper.SRoleMapper.selectById" >
</association>

property:實體類的屬性名

column:外關聯欄位的欄位名

javaType:property對應的實體類的類型。

select:外關聯查詢的方法

外聯查詢 - 一對多查詢
<collection property="roleUsers" column="id" javaType="list" ofType="suser"
            select="com.dzqc.smbms.mapper.ISUserMapper.selectByRoleId">
</collection>

property:實體類的屬性名

column:外關聯欄位的欄位名

javaType:一對多關聯集合類型。

ofType:一對多關聯集合中存放的數據的類型。

select:外關聯查詢的方法

MyBatis 一級緩存與二級緩存

事務管理

Spring事務管理

什麼是事務:事務的本身其實就是一組業務邏輯,在業務邏輯當中包含有針對於資料庫持久化的操作。在事務當中的所有業務邏輯被視為一個整體。

事務的特性(ACID)

  • 原子性(Atomicity):事務中所有的操作,被視為一個整體,一組業務邏輯中一旦有一點出現異常或失敗,那麼所有的業務邏輯都被視為失敗。原子性保證了事務當中的業務邏輯要麼全部成功,要麼全部失敗。
  • 一致性(Consistency):事務的操作,不能破壞資料庫中的數據完整性,在事務執行之前或執行之後,資料庫都處於一致的狀態。在事務中一旦對數據進行持久化,那麼持久化的數據一定符合該資料庫的所有規範,不會破壞資料庫中數據的完整性。
  • 持久性(Durability):事務中的數據一旦被提交,在之後的操作中都可以查詢到,無論出現什麼故障都不會導致數據的損壞或丟失(物理損壞除外,存儲介質損壞)。
  • 隔離性(Isolation):資料庫允許多個事務同時執行,事務之間的數據相互不會有影響。

事務的隔離級別

事務不隔離會產生的問題:

臟讀:當前事務讀到了其他事務未提交的數據

幻讀(虛讀):當前事務重覆讀取同樣的數據,讀取到了其他事務新增的數據,導致短時間內兩次讀取的數據不一致。

不可重覆讀:當前事務讀到了其他事務已提交的數據,在短時間,兩次查詢的結果不一致。

  • 讀未提交(read-uncommitted):預設隔離級別,允許當前事務讀取其他事務未提交的數據,在該隔離級別中,臟讀、幻讀、不可重覆讀都有可能出現。
  • 讀已提交(read-committed):允許當前事務讀取其他事務已提交的數據,在該隔離級別下,臟讀不會出現,幻讀和不可重覆讀有可能出現。
  • 可重覆讀(Repeatable-read):允許當前數據讀取其他事務新增的數據,不讀取其他事務提交的修改數據(不允許修改操作)。在該事務隔離級別下,臟讀與不可重覆讀不會出現,幻讀有可能會出現。
  • 串列化(Serializable):最高的事務隔離級別,臟讀、幻讀、不可重覆讀都不會出現,但是運行效率低,一般不使用。

Spring事務

編程式事務

優點:對事務的操作精細,能夠更加精確的對事務進行管理

缺點:對代碼的侵入度高,在後期進行維護、功能變更時會提高維護難度。

聲明式事務

事務傳播機制

事務傳播機制一共有7種。

  1. requierd:如果當前沒有事務,就新建一個事務,如果已存在一個事務中,加入到這個事務中,(事務預設傳播機制)。
  2. supports:支持當前事務,如果沒有當前事務,就以非事務方法執行。
  3. mandatory:使用當前事務,如果沒有當前事務,就拋出異常。
  4. required_new:新建事務,如果當前存在事務,把當前事務掛起。
  5. not_supported:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
  6. never:以非事務方式執行操作,如果當前事務存在則拋出異常。
  7. nested:如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則執行與propagation_required類似的操作

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文揭秘全球數據科學崗位的薪資分佈情況!以及分析崗位、國家、工作經驗、雇佣形式、公司規模對薪資的影響,並貼心提供了求職建議和跳槽Tips! ...
  • 原文:Window系統的mysql資料庫定時備份 - Stars-One的雜貨小窩 最近老大提到了資料庫備份的功能,由於伺服器是window系統的,所以研究了下備份的方案,特此記錄 主要是實現每天定時備份功能,如果還要搞容災的話,就得對mysql資料庫進行主從配置了 cmd命令 核心的cmd命令如下 ...
  • 一、原理: 主要涉及的系統命令:ping -n 1 -w 1 IP地址 -n 為ping的次數,在linux下為-c;-w為等待超時時間; 利用Python多線程縮短時間,提升運行效率。 二、其它說明 DEV_NULL = open(os.devnull, 'w') 是在Python中實現的黑洞,類 ...
  • JZ38 字元串的排列 描述 輸入一個長度為 n 字元串,列印出該字元串中字元的所有排列,你可以以任意順序返回這個字元串數組。 例如輸入字元串ABC,則輸出由字元A,B,C所能排列出來的所有字元串ABC,ACB,BAC,BCA,CBA和CAB。 題目主要信息 給定一個長度為n的字元串,求其中所有字元 ...
  • 簡單記錄一下springboot引用kettle對接數據 第一步(這一步講述了下載kettle、創建資料庫連接、轉換等,如果這一步會的可以略過,直接看第二步) 先從kettle官網下載kettle,官網地址:https://sourceforge.net/projects/pentaho/ 進入官網 ...
  • 1.什麼是python的包 包就是一個文件夾,裡面放著一個個py文件或子包; 在包中可以被調用的一個個py文件,我們叫做模塊; 如上,test就是一個包、two.py就是test下的一個模塊,child是子包,結構和test包一樣; 包的身份證 可以看到test下還有一個__init__.py命名的 ...
  • add add 目的,源 ; 加法指令,結果放入目操作數,操作數的長度必須相同 adc adc 目的,源 ; 帶進位加法,目的=目的+源+CF and and 目的,源 ; 邏輯按位與 指令,結果放到目的操作數。 ; 影響標誌位OF、SF、ZF、PF和CF。 call call s ; 使call ...
  • //最近一個公司項目需要對接firebase推送,官方文檔就是謝特,再網上找了很多大神的資料,還是有很多坑,把自己踩的坑記錄一下,平時都是伸手黨,這次回饋一下 use Google\Client; /** * 註意需要準備vpn * 1.安裝sdk composer require google/a ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...