SSM总结()

  本篇文章为你整理了SSM总结()的详细内容,包含有 SSM总结,希望能帮助你了解 SSM总结。

  目录SSMSpringIOC(控制反转) DI(依赖注入)Bean注入方式AOP(面向切面编程)一、AOP编程思想1.1 什么是AOP1.2 为什么需要AOP1.3 AOP实现方法分类二、AOP的专有名词三、认识SpringAOP3.1 SpringAOP的特点3.2 SpringAOP使用与实现代理模式静态代理JDK动态代理CGlib动态代理SPring MVCSpringMVC核心组件SpringMVC第一个程序处理请求以及响应参数传递响应 页面跳转SpringMVC基本配置SpringMVC文件上传Restful风格接口SpringMVC工作流程MyBAtis实现原理:工厂模式简单工厂工厂方法抽象工厂MyBatis基本应用MyBatis的基本配置(MyBatis-config.xml)MyBatis数据源配置数据库连接池 (druid c3p0)映射文件配置其他配置MyBatis整合Log4JMyBatis主要构件MyBatis映射文件基本标签动态SQLResultMap基础查询 - 基本映射外联查询 - 一对一查询外联查询 - 一对多查询MyBatis 一级缓存与二级缓存事务管理Spring事务管理事务的特性(ACID)事务的隔离级别Spring事务编程式事务声明式事务事务传播机制

  Spring

  IOC(控制反转) DI(依赖注入)

  IOC是容器,用来装Spring创建的Bean对象。

  Bean注入方式

  Set方法注入

  构造器注入

  @Autowared自动注入

  

 !-- SpringBean的注入方式 -- 

 

   !-- 手动装配 --

   !-- == set方法注入 --

   bean id="hello"

   property name="userCode" value="hello" /property

   property name="userName" value="Spring" /property

   property name="role"

   bean

   property name="roleCode" value="这里是注入的实例对象" /property

   property name="roleName" value="这里是注入的实例对象的值" /property

   /bean

   /property

   property name="role" ref="myRole" /property

   /bean

   bean name="myRole"

   property name="roleName" value="管理员" /property

   property name="roleCode" value="SMBMS_ADMIN" /property

   /bean

   !-- == 带参构造器注入 --

   bean name="constructor"

   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框架在运行阶段动态生成代理对象。即在内存中以JDK动态代理的方式,或CGlib动态生成AOP代理类,典型的技术如:SpringAOP。

  
在编译前,切面直接以字节码的形式编译入目标代码的字节码文件中,对性能无影响,但灵活性不够。

  
JDK动态代理

  在运行期间,目标类加载之后为接口动态生成代理类,将切面织入到代理类中,相对于静态AOP更灵活一些。但切入点需要实现接口,对系统的性能有一定影响。

  
CGlib

  在运行期间,目标类加载之后,动态生成目标类的子类,然后将切面的逻辑加入到子类中,相对于JDK动态代理的方式,CGlib不需要接口也可以实现织入,但是当扩展类的实例方法使用final修饰时无法进行织入。

  
增强建议(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通水管

  水管打不通

  够不着旗杆,游戏结束 //原始内容

  什么破游戏!

  

 

  ​ 由上述代码不难看出,动态代理的实现需要以下几点:

  JDK动态代理需要声明接口。想要创建一个动态代理类,就必须给这个类声明一个接口,否则无法在Proxy.newProxyInstance时传入对应的接口类字节码文件。

  在代理类中需要通过构造传入原有的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。

  复杂数据类型:

  对象:对象在进行参数传递时,参数列表中声明的为对象,在传参的过程中,传递的是对象中声明的属性名。

  数组:数组在进行传参时,数组的参数名需要多次出现,每次出现给数组赋一个 值。

  http://localhost:9999/ssm/arr?arr=name1 arr=name2 arr=name3

  
List集合:在进行参数传递时,因为List集合是个接口,所以需要在List类型的参数前加上@RequestParam注解,在参数传递时,与数组传参方式一致。

  map集合:在进行参数传递时,需要加上@RequestParam注解,参数在拼接时,只需将key和value的值按照普通传参的方式拼接在地址栏或参数列表中。

  
只响应数据:数据接口,在Handler方法上需要添加@ResponseBody注解,添加完成后,返回值不会被视图解析器进行解析,在返回时可以按照正常的数据进行返回。

  默认页面返回:默认的响应方式,本质上是请求转发,在Handler方法进行return后,会将返回的数据转发至DispatcherServlet,然后由DispatcherServlet调度视图解析器,解析返回值中的数据与视图并响应。

  重定向:重定向可以重定向到任意路径,只需要在返回值上、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

  
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

  
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

  
!-- 最大支持文件大小,此处配置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:请求处理流程

  DispathcerServlet(前端控制器)接收请求 :DispatcherServlet 通过 doService()方法 接收用户请求。调用 doDispatch() 方法进行请求调度。

  DispatcherServlet(前端控制器)调用HandlerMapping(处理器映射器):DispatcherServlet 通过getHandler() 调用HandlerMapping获取HandlerExecutionChain

  HandlerMapping将(HandlerExecutionChain)处理器执行链返回给DispatcherServlet

  DispathcerServlet(前端控制器)通过HandlerAdapter(处理器适配器),获取对应的Handler处理器方法。

  HandlerAdapter(处理器适配器)调用Handler处理器方法,处理用户请求。

  Handler处理器方法将返回值返回给HandlerAdapter(处理器适配器)

  HandlerAdapter将Handler处理器方法的返回值以ModelAndView的形式返回给DispatherServlet:

  DispatcherServlet将ModelAndView交给ViewResolver(视图解析器)解析。

  ViewResolver(视图解析器)将ModelAndView中的数据渲染到View(视图)中。

  ViewResolver返回的视图信息到DispatcherServlet。

  DispatcherServlet将视图信息及返回值返回给客户端。

  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种。

  requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,(事务默认传播机制)。supports:支持当前事务,如果没有当前事务,就以非事务方法执行。mandatory:使用当前事务,如果没有当前事务,就抛出异常。required_new:新建事务,如果当前存在事务,把当前事务挂起。not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。never:以非事务方式执行操作,如果当前事务存在则抛出异常。nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作 posted @ 2022-12-09 09:39sailing_miles_away

  阅读(45)

  评论(0)

  编辑

  收藏

  举报

  以上就是SSM总结()的详细内容,想要了解更多 SSM总结的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: