前语

本文对Spring、Mybatis相关常识做了一个相对完整的总结,涉及到Spring IOC\DI、Bean、AOP、一二三级缓存、Mybatis运转原理、组件等。特别注意,口语化陈腔滥调文系列,仅作突击温习中心常识点用,引荐有一定陈腔滥调根底的人食用,更细的点需求咱们自行查询相关具体图文材料

正文

Spring的IOC和DI

IOC意为控制反转,在Spring中便是用户将Bean的管理权限交给Spring,由Spring IOC容器来创立、装备和毁掉Bean。DI意为依靠注入,Spring IOC容器将外部的文件、方针、数据等资源注入给程序中的方针。IOC是规划思想,DI便是它的具体完结。

BeanFactory、FactoryBean、ApplicationContext差异

BeanFactory是Spring IOC容器的顶层接口,界说了一些根底功用和标准,内部只包含getBean、contains等获取和判断Bean的接口,装载Bean时是懒加载

ApplicationContext是它的子类,在BeanFactory根底上有更丰厚的功用,选用预加载,在发动时创立一切Bean。

FactoryBean同样也是一个接口,用来生成复杂的bean,独自用意义不大,一般合作Bean生命周期中的InitializingBean、BeanNameAware等接口,完结更复杂的操作。

@Component 和 @Bean 的差异是什么?

  1. 效果方针不同,@Component注解效果于类,@Bean效果于办法。
  2. @Component注解的类,需求经过@ComponentScan注解指定途径扫描到才干装载到Spring IOC容器中。@Bean除了需求在扫描途径下,还需求当时类加上@Configuration注解。
  3. @Bean比@Component更加灵活,比方引证三方库中的类来创立bean只能经过@Bean完结,由于咱们不能直接在三方库的类上注解。

解释 Spring 支撑的几种 Bean 的效果域

Spring 结构支撑以下五种 bean 的效果域:

  • singleton : bean 在每个 Spring ioc 容器中只要一个实例。
  • prototype:一个 bean 的界说能够有多个实例。
  • request : 每 次 http 请 求 都 会 创 建 一 个 bean , 该 作 用 域 仅 在 基 于 web 的Spring ApplicationContext 景象下有用。
  • session:在一个 HTTP Session 中,一个 bean 界说对应一个实例。该效果域仅在依据web 的 Spring ApplicationContext 景象下有用。
  • global-session:在一个全局的 HTTP Session 中,一个 bean 界说对应一个实例。该效果域仅在依据 web 的 Spring ApplicationContext 景象下有用。缺省的 Spring bean 的效果域是 Singleton。

Bean生命周期

总结一下,Bean容器查找并加载Spring管理的Bean,进行实例化,然后进行特点赋值,假如完结了BeanNameAware之类的以Aware为后缀的接口,则调用对应的办法。假如有完结BeanPostProcessor接口,则在Bean调用初始化办法的前后履行BeanPostProcessor的前后置办法。当要毁掉Bean,调用对应的毁掉办法。个人在运用时,比较常见的是完结BeanDefinitionRegistryPostProcessor接口,重写办法将IOC容器中的某个Bean给移除,一般是将三方结构中的某些装备类给干掉。

  • Bean 容器找到装备文件中 Spring Bean 的界说。
  • Bean 容器运用 Java Reflection API 创立一个Bean的实例。
  • 假如涉及到一些特点值 运用set()办法设置一些特点值。
  • 假如 Bean 完结了BeanNameAware接口,调用setBeanName()办法,传入Bean的姓名。
  • 假如 Bean 完结了BeanClassLoaderAware接口,调用setBeanClassLoader()办法,传入ClassLoader方针的实例。
  • 假如Bean完结了BeanFactoryAware接口,调用setBeanClassLoader()办法,传入ClassLoader方针的实例。
  • 与上面的相似,假如完结了其他*.Aware接口,就调用相应的办法。
  • 假如有和加载这个 Bean 的 Spring 容器相关的BeanPostProcessor方针,履行postProcessBeforeInitialization()办法
  • 假如Bean完结了InitializingBean接口,履行afterPropertiesSet()办法。
  • 假如 Bean 在装备文件中的界说包含 init-method 特点,履行指定的办法。
  • 假如有和加载这个 Bean的 Spring 容器相关的BeanPostProcessor方针,履行postProcessAfterInitialization()办法
  • 当要毁掉 Bean 的时分,假如 Bean 完结了DisposableBean接口,履行destroy()办法。
  • 当要毁掉 Bean 的时分,假如 Bean 在装备文件中的界说包含 destroy-method 特点,履行指定的办法。

Spring 为何需求三级缓存处理循环依靠

Spring有三级缓存,其实便是三个Map,一级缓存存储实例化和初始化都完结的成品Bean。二级缓存存的是半成品,仅完结实例化,没有完结特点注入和初始化,用以处理方针创立时的循环依靠问题。三级缓存存储Bean工厂方针,用来生成半成品Bean放入二级缓存中,这一级缓存用来处理存在AOP时的循环依靠问题。

一般循环依靠,a依靠b,b依靠a。获取a,先看一级缓存有没有数据,没有的话将a的BeanFactory方针放入三级缓存。a开端特点注入,发现b没有创立,实例化b,同样将b的BeanFactory方针放入三级缓存。b也开端特点注入,发现一、二级缓存没有a,调用三级缓存中a的BeanFactory.getObject办法,将a放入二级缓存并铲除三级缓存(一二三次序获取,铲除开释空间)。此刻b成功注入a,完结初始化,放入一级缓存,并铲除二三级缓存。继续a特点注入,此刻从一级缓存中获取b,完结初始化,并铲除a的二三级缓存。最终获取b,从一级缓存中取出即可。

干掉二级缓存,只用一三级行不行?不行,假如一级缓存中没有值,从BeanFactory.getObject中每次都拿到新的署理方针,假如有二级缓存,那么就会有单例的方针放入二级缓存中,依据一二三次序获取,就不会每次在三级缓存中重新生成一个新的。

假如干掉三级缓存,只要一二级行不行?假如存在AOP则不行,由于三级缓存生成的方针可能是原始的,而不是咱们想要的署理增强方针,从而导致初始化反常。

Spring运用三级缓存处理循环依靠?总算彻底弄明白了_spring三级缓存怎么处理循环依靠_三七有脾气的博客-CSDN博客

Spring规划形式

工厂规划形式 : Spring运用工厂形式经过 BeanFactory、ApplicationContext 创立 bean 方针。

署理规划形式 : Spring AOP 功用的完结。

单例规划形式 : Spring 中的 Bean 默认都是单例的。

模板办法形式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 完毕的对数据库操作的类,它们就运用到了模板形式。

包装器规划形式 : 咱们的项目需求连接多个数据库,而且不同的客户在每次拜访中依据需求会去拜访不同的数据库。这种形式让咱们能够依据客户的需求能够动态切换不同的数据源。

观察者形式: Spring 事情驱动模型便是观察者形式很经典的一个运用。

适配器形式 :Spring AOP 的增强或告诉(Advice)运用到了适配器形式、spring MVC 中也是用到了适配器形式适配Controller。

AOP原理(Cglib和JDK动态署理)

  1. 解析AOP装备,注册切面类,读取增强办法,获取切入点等等
  2. spring容器发动,创立bean时,对契合条件的bean生成署理类和增强办法链
  3. bean办法被调用时,署理类的增强链办法顺次履行

署理分为静态和动态两种,动态署理依据完结办法细分为Cglib和JDK两种。静态署理需求完结接口,将原接口的完结类放入署理类作为署理方针,再重写接口的每个办法做增强。一般不会用静态署理,耦合严重,一般运用动态署理。JDK动态署理是用过反射机制生成一个和被署理类完结相同接口且承继Proxy类的署理类,完结InvocationHandler接口重写invoke办法进行署理增强。Cglib动态署理经过运用ASM开源包,加载被署理方针的class文件,并修正其字节码文件生成一个承继被署理方针的子类来作为署理方针,并重写署理办法使其调用自界说的办法阻拦器去履行。

两种动态署理的差异:

  • JDK动态署理要求⽬标方针完结⼀个接⼝,可是有时分⽬标方针仅仅⼀个独自的方针,并没有完结任何的接⼝,这个时分就能够⽤CGLib动态署理
  • CGLib动态署理,它是在内存中构建⼀个⼦类方针从⽽完结对⽬标方针功用的扩展 ,依据承继来完结署理,所以⽆法对final类、private⽅法和static⽅法完结署理
  • JDK动态署理是⾃带的,CGlib需求引⼊第三⽅包

Spring AOP中的署理使⽤的默认战略:

  • 假如⽬标方针完结了接⼝,则默认采⽤JDK动态署理
  • 假如⽬标方针没有完结接⼝,则采⽤CgLib进⾏动态署理
  • 假如⽬标方针完结了接⼝,程序⾥⾯仍旧能够指定使⽤CGlib动态署理

注解 @Autowired 和 @Resource 有什么差异?

  1. Resource 是 JDK 供给的,而 Autowired 是 Spring 供给的
  2. Resource 不答应找不到 bean 的情况,而 Autowired 答应(@Autowired(required = false))
  3. 指定 name 的办法不一样,@Resource(name = “baseDao”),@Autowired()@Qualifier(“baseDao”)
  4. Resource 默认经过 name 查找,而 Autowired 默认经过 type 查找

Spring业务的种类、业务传播行为、阻隔等级

Spring支撑编程式业务管理和声明式业务管理两种办法:

  • 编程式业务管理运用TransactionTemplate。
  • 声明式业务管理建立在AOP之上的。其本质是经过AOP功用,对办法前后进行阻拦,将业务处理的功用织造到阻拦的办法中,也便是在方针办法开端之前参加一个业务,在履行完方针办法之后依据履行情况提交或许回滚业务。

声明式业务最大的长处便是不需求在业务逻辑代码中掺杂业务管理的代码,只需在装备文件中做相关的业务规则声明或经过@Transactional注解的办法,便能够将业务规则运用到业务逻辑中。唯一缺乏地方是,声明式业务管理最细粒度只能效果到办法等级,无法做到像编程式业务那样能够效果到代码块等级。

spring的业务传播行为

spring业务的传播行为说的是,当多个业务一起存在的时分,spring怎么处理这些业务的行为。

① PROPAGATION_REQUIRED:假如当时没有业务,就创立一个新业务,假如当时存在业务,就参加该业务,该设置是最常用的设置。

② PROPAGATION_SUPPORTS:支撑当时业务,假如当时存在业务,就参加该业务,假如当时不存在业务,就以非业务履行。‘

③ PROPAGATION_MANDATORY:支撑当时业务,假如当时存在业务,就参加该业务,假如当时不存在业务,就抛出反常。

④ PROPAGATION_REQUIRES_NEW:创立新业务,不管当时存不存在业务,都创立新业务。

⑤ PROPAGATION_NOT_SUPPORTED:以非业务办法履行操作,假如当时存在业务,就把当时业务挂起。

⑥ PROPAGATION_NEVER:以非业务办法履行,假如当时存在业务,则抛出反常。

⑦ PROPAGATION_NESTED:假如当时存在业务,则在嵌套业务内履行。假如当时没有业务,则按REQUIRED特点履行。

Spring中的阻隔等级

① ISOLATION_DEFAULT:这是个 PlatfromTransactionManager 默认的阻隔等级,运用数据库默认的业务阻隔等级。

② ISOLATION_READ_UNCOMMITTED:读未提交,答应另外一个业务能够看到这个业务未提交的数据。

③ ISOLATION_READ_COMMITTED:读已提交,确保一个业务修正的数据提交后才干被另一业务读取,而且能看到该业务对已有记载的更新。

④ ISOLATION_REPEATABLE_READ:可重复读,确保一个业务修正的数据提交后才干被另一业务读取,可是不能看到该业务对已有记载的更新。

⑤ ISOLATION_SERIALIZABLE:一个业务在履行的进程中彻底看不到其他业务对数据库所做的更新。

Spring MVC 恳求处理流程

  1. 客户端(浏览器)发送恳求,直接恳求到 DispatcherServlet。
  2. DispatcherServlet 依据恳求信息调用 HandlerMapping,解析恳求对应的 Handler。
  3. 解析到对应的 Handler(也便是咱们往常说的 Controller 控制器)后,开端由 HandlerAdapter 适配器处理。
  4. HandlerAdapter 会依据 Handler来调用真正的处理器开处理恳求,并处理相应的业务逻辑。
  5. 处理器处理完业务后,会回来一个 ModelAndView 方针,Model 是回来的数据方针,View 是个逻辑上的 View。
  6. ViewResolver 会依据逻辑 View 查找实际的 View。
  7. DispaterServlet 把回来的 Model 传给 View(视图烘托)。
  8. 把 View 回来给恳求者(浏览器)

Spring MVC 九大组件

HandlerMapping(处理器映射器)

HandlerMapping 是⽤来查找 Handler 的,也便是处理器,具体的体现形式能够是类,也能够是 ⽅法。⽐如,标注了@RequestMapping的每个⽅法都能够看成是⼀个Handler。Handler担任具 体实际的恳求处理,在恳求抵达后,HandlerMapping 的作⽤便是找到恳求相应的处理器 Handler 和 Interceptor.

HandlerAdapter(处理器适配器)

HandlerAdapter 是⼀个适配器。由于 Spring MVC 中 Handler 能够是恣意形式的,只要能处理恳求即可。可是把恳求交给 Servlet 的时分,由于 Servlet 的⽅法结构都是 doService(HttpServletRequest req,HttpServletResponse resp)形式的,要让固定的 Servlet 处理 ⽅法调⽤ Handler 来进⾏处理,便是 HandlerAdapter 的职责。

HandlerExceptionResolver

HandlerExceptionResolver ⽤于处理 Handler 产⽣的反常情况。它的作⽤是依据反常设置 ModelAndView,之后交给烘托⽅法进⾏烘托,烘托⽅法会将 ModelAndView 烘托成⻚⾯。

ViewResolver

ViewResolver即视图解析器,⽤于将String类型的视图名和Locale解析为View类型的视图,只要⼀ 个resolveViewName()⽅法。从⽅法的界说能够看出,Controller层回来的String类型视图名 viewName 终究会在这⾥被解析成为View。View是⽤来烘托⻚⾯的,也便是说,它会将程序回来 的参数和数据填⼊模板中,⽣成html⽂件。ViewResolver 在这个进程首要完结两件事情: ViewResolver 找到烘托所⽤的模板(第⼀件⼤事)和所⽤的技能(第⼆件⼤事,其实也便是找到 视图的类型,如JSP)并填⼊参数。默认情况下,Spring MVC会⾃动为咱们装备⼀个 InternalResourceViewResolver,是针对 JSP 类型视图的。

RequestToViewNameTranslator

RequestToViewNameTranslator 组件的作⽤是从恳求中获取 ViewName.由于 ViewResolver 依据 ViewName 查找 View,但有的 Handler 处理完结之后,没有设置 View,也没有设置 ViewName, 便要经过这个组件从恳求中查找 ViewName。

LocaleResolver

ViewResolver 组件的 resolveViewName ⽅法需求两个参数,⼀个是视图名,⼀个是 Locale。 LocaleResolver ⽤于从恳求中解分出 Locale,⽐如中国 Locale 是 zh-CN,⽤来表明⼀个区域。这 个组件也是 i18n 的根底。

ThemeResolver

ThemeResolver 组件是⽤来解析主题的。主题是款式、图⽚及它们所形成的显现效果的调集。 Spring MVC 中⼀套主题对应⼀个 properties⽂件,⾥⾯存放着与当时主题相关的一切资源,如图 ⽚、CSS款式等。创立主题⾮常简单,只需预备好资源,然后新建⼀个“主落款.properties”并将资 源设置进去,放在classpath下,之后便能够在⻚⾯中使⽤了。SpringMVC中与主题相关的类有 ThemeResolver、ThemeSource和Theme。ThemeResolver担任从恳求中解分出主落款, ThemeSource依据主落款找到具体的主题,其笼统也便是Theme,能够经过Theme来获取主题和 具体的资源。

MultipartResolver

MultipartResolver ⽤于上传恳求,经过将一般的恳求包装成 MultipartHttpServletRequest 来完结MultipartHttpServletRequest 能够经过 getFile() ⽅法 直接取得⽂件。假如上传多个⽂件,还 能够调⽤ getFileMap()⽅法得到Map这样的结构,MultipartResolver 的作⽤就 是封装一般的恳求,使其拥有⽂件上传的功用。

FlashMapManager

FlashMap ⽤于重定向时的参数传递,⽐如在处理⽤户订单时分,为了避免重复提交,能够处理完 post恳求之后重定向到⼀个get恳求,这个get恳求能够⽤来显现订单概况之类的信息。这样做虽然 能够躲避⽤户重新提交订单的问题,可是在这个⻚⾯上要显现订单的信息,这些数据从哪⾥来取得 呢?由于重定向时么有传递参数这⼀功用的,假如不想把参数写进URL(不引荐),那么就能够通 过FlashMap来传递。只需求在重定向之前将要传递的数据写⼊恳求(能够经过 ServletRequestAttributes.getRequest()⽅法取得)的特点OUTPUT_FLASH_MAP_ATTRIBUTE 中,这样在重定向之后的Handler中Spring就会⾃动将其设置到Model中,在显现订单信息的⻚⾯ 上就能够直接从Model中获取数据。FlashMapManager 便是⽤来管理 FalshMap 的。

监听器、过滤器和阻拦器对比

  • Servlet:处理Request恳求和Response呼应 过滤器(Filter):对Request恳求起到过滤的作⽤,作⽤在Servlet之前,假如装备为/*能够对所 有的资源拜访(servlet、js/css静态资源等)进⾏过滤处理
  • 监听器(Listener):完结了javax.servlet.ServletContextListener 接⼝的服务器端组件,它随 Web应⽤的发动⽽发动,只初始化⼀次,然后会⼀直运⾏监督,随Web应⽤的停⽌⽽毁掉
    • 作⽤⼀:做⼀些初始化⼯作,web应⽤中spring容器发动ContextLoaderListener
    • 作⽤⼆:监听web中的特定事情,⽐如HttpSession,ServletRequest的创立和毁掉;变量的创立、 毁掉和修正等。能够在某些动作前后增加处理,完结监控,⽐如计算在线⼈数,利⽤ HttpSessionLisener等。
  • 阻拦器(Interceptor):是SpringMVC、Struts等体现层结构⾃⼰的,不会阻拦 jsp/html/css/image的拜访等,只会阻拦拜访的控制器⽅法(Handler)。

从装备的⻆度也能够总结发现:serlvet、filter、listener是装备在web.xml中的,⽽interceptor是 装备在体现层结构⾃⼰的装备⽂件中的 在Handler业务逻辑执⾏之前阻拦⼀次 在Handler逻辑执⾏完毕但未跳转⻚⾯之前阻拦⼀次 在跳转⻚⾯之后阻拦⼀次

@SpringBootApplication组成

  • @SpringBootConfiguration
    • @Configuration //经过javaConfig的办法来增加组件到IOC容器中
  • @EnableAutoConfiguration
    • @AutoConfigurationPackage //主动装备包,与@ComponentScan扫描到的增加到IOC
    • @Import(AutoConfigurationImportSelector.class) //到METAINF/spring.factories中界说的bean增加到IOC容器中
  • @ComponentScan //包扫描

项目初始化发动进程

第一步:获取并发动监听器

this.getRunListeners(args)和listeners.starting()办法首要用于获取SpringApplication实例初始化进程中初始化的SpringApplicationRunListener监听器并运转。

第二步:依据SpringApplicationRunListeners以及参数来预备环境

this.prepareEnvironment(listeners, applicationArguments)办法首要用于对项目运转环境进 行预设置,一起经过this.configureIgnoreBeanInfo(environment)办法排除一些不需求的运转环境

第三步:创立Spring容器

依据webApplicationType进行判断, 确认容器类型,假如该类型为SERVLET类型,会经过反射装载对应的字节码,也便是AnnotationConfigServletWebServerApplicationContext,接着运用之前初始化设置的context(运用上下文环境)、environment(项目运转环境)、listeners(运转监听器)、applicationArguments(项目参数)和printedBanner(项目图标信息)进行运用上下文的拼装装备,并改写装备

第四步:Spring容器前置处理

这一步首要是在容器改写之前的预备动作。设置容器环境,包含各种变量等等,其间包含一个非常关键的操作:将发动类注入容器,为后续敞开主动化装备奠定根底

第五步:改写容器

敞开改写spring容器,经过refresh办法对整个IOC容器的初始化(包含bean资源的定位,解析,注册等等),一起向JVM运转时注册一个关机钩子,在JVM关机时会封闭这个上下文,除非当时它现已封闭

第六步:Spring容器后置处理

扩展接口,规划形式中的模板办法,默以为空完结。假如有自界说需求,能够重写该办法。比方打印一些发动完毕log,或许一些其它后置处理。

第七步:发出完毕履行的事情

获取EventPublishingRunListener监听器,并履行其started办法,而且将创立的Spring容器传进去了,创立一个ApplicationStartedEvent事情,并履行ConfigurableApplicationContext 的publishEvent办法,也便是说这里是在Spring容器中发布事情,并不是在SpringApplication中发布事情,和前面的starting是不同的,前面的starting是直接向SpringApplication中的监听器发布发动事情。

第八步:履行Runners

用于调用项目中自界说的履行器XxxRunner类,使得在项目发动完结后立即履行一些特定程序。其间,Spring Boot供给的履行器接口有ApplicationRunner 和CommandLineRunner两种,在运用时只需求自界说一个履行器类完结其间一个接口并重写对应的run()办法接口,然后Spring Boot项目发动后会立即履行这些特定程序

MyBatis的首要成员

  • Configuration MyBatis一切的装备信息都保存在Configuration方针之中,装备文件中的大部分装备都会存储到该类中
  • SqlSession 作为MyBatis工作的首要顶层API,表明和数据库交互时的会话,完结必要数据库增删改查功用
  • Executor MyBatis履行器,是MyBatis 调度的中心,担任SQL语句的生成和查询缓存的保护
  • StatementHandler 封装了JDBC Statement操作,担任对JDBC statement 的操作,如设置参数等
  • ParameterHandler 担任对用户传递的参数转化成JDBC Statement 所对应的数据类型
  • ResultSetHandler 担任将JDBC回来的ResultSet成果集方针转化成List类型的调集
  • TypeHandler 担任java数据类型和jdbc数据类型(也能够说是数据表列类型)之间的映射和转化
  • MappedStatement MappedStatement保护一条节点的封装
  • SqlSource 担任依据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql方针中,并回来
  • BoundSql 表明动态生成的SQL语句以及相应的参数信息

Mybatis工作原理

  1. SqlSessionFactoryBuilder经过Configuration方针生成SqlSessionFactory,用来敞开SqlSession。
  2. SqlSession方针完结和数据库的交互:
  3. 用户程序调用mybatis接口层api(即Mapper接口中的办法)
    1. SqlSession经过调用api的Statement ID找到对应的MappedStatement方针
    1. 经过Executor(担任动态SQL的生成和查询缓存的保护)将MappedStatement方针进行解析,sql参数转化、动态sql拼接,生成jdbc Statement方针,运用Paramterhandler填充参数,运用statementHandler绑定参数。
    1. JDBC履行sql。
    1. 凭借MappedStatement中的成果映射联系,运用ResultSetHandler将回来成果转化成HashMap、JavaBean等存储结构并回来。
    1. 封闭sqlsession会话。

{}和${}的差异是什么?

#{}是预编译处理,${}是字符串替换。运用#{}能够有用的防止 SQL 注入,提高系统安全性。

在处理#{}时,MyBatis会主动生成PreparedStatement,运用参数绑定(?)的办法来设置值;

在处理时,便是把{}时,便是把{}替换成变量的值。

浅析count(1)、count(*)与count(列名)的履行差异

count(1) 包含了忽略一切列,用1代表代码行,在计算成果的时分, 不会忽略列值为NULL

count(*) 包含了一切的列,相当于行数,在计算成果的时分, 不会忽略列值为NULL。MySQL引荐计算行数语法,和count(1)效果一致。

count(列名) 只包含列名那一列,在计算成果的时分,会忽略列值为空(这里的空不是指空字符串或许0,而是表明null)的计数, 即某个字段值为NULL时,不计算。

Mybatis都有哪些Executor履行器?它们之间的差异是什么?

Mybatis有三种基本的Executor履行器,SimpleExecutor、ReuseExecutor、BatchExecutor。

  • SimpleExecutor:每履行一次update或select,就敞开一个Statement方针,用完立刻封闭Statement方针。
  • ReuseExecutor:履行update或select,以sql作为key查找Statement方针,存在就运用,不存在就创立,用完后,不封闭Statement方针,而是放置于Map内,供下一次运用。简言之,便是重复运用Statement方针。
  • BatchExecutor:履行update(没有select,JDBC批处理不支撑select),将一切sql都增加到批处理中(addBatch()),等候统一履行(executeBatch()),它缓存了多个Statement方针,每个Statement方针都是addBatch()完毕后,等候逐个履行executeBatch()批处理。与JDBC批处理相同。

Mybatis是怎么进行分页的?分页插件的原理是什么?Mybatis 的插件运转原理?

Mybatis 分页的三种办法:

  1. RowBounds 方针进行分页
  2. 直接编写 sql 完结分页
  3. 运用Mybatis 的分页插件。

分页插件的原理:

完结 Mybatis 供给的接口,完结自界说插件,在插件的阻拦办法内阻拦待履行的 sql,然后重写 sql。举例:select * from student,阻拦 sql 后重写为:select t.* from (select * from student)t limit 0,10

Mybatis插件

Mybatis 仅能够编写针对 ParameterHandler、ResultSetHandler、StatementHandler、Executor 这 4 种接口的插件,Mybatis 经过动态署理,为需求阻拦的接口生成署理方针以完结接口办法阻拦功用,每逢履行这 4 种接口方针的办法时,就会进入阻拦办法,具体便是InvocationHandler 的 invoke()办法,当然,只会阻拦那些你指定需求阻拦的办法。

Mybatis动态sql有什么用?履行原理?有哪些动态sql?

Mybatis动态sql能够在Xml映射文件内,以标签的形式编写动态sql,履行原理是依据表达式的值 完结逻辑判断并动态拼接sql的功用。

Mybatis供给了9种动态sql标签: trim|where|set|foreach|if|choose|when|otherwise|bind 。其履行原理为,运用 OGNL 从 sql 参数方针中计算表达式的值,依据表达式的值动态拼接 sql,以此来完结动态 sql 的功用。

Mybatis的一级、二级缓存

一级缓存: 依据 PerpetualCache 的 HashMap 本地缓存,其存储效果域为 Session,当 Sessionflush 或 close 之后,该 Session 中的一切 Cache 就将清空,默认翻开一级缓存。

二级缓存与一级缓存其机制相同,默认也是选用 PerpetualCache,HashMap 存储,不同在于其存储效果域为 Mapper(Namespace),而且可自界说存储源,如 Ehcache。默认不翻开二级缓存,要敞开二级缓存,运用二级缓存特点类需求完结Serializable序列化接口(可用来保存方针的状态),可在它的映射文件中装备 ;

对于缓存数据更新机制,当某一个效果域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D操作后,默认该效果域下一切 select 中的缓存将被 clear。

为什么说 Mybatis 是半主动 ORM 映射东西?它与全主动的差异在哪里?

Hibernate 归于全主动 ORM 映射东西,运用 Hibernate 查询相关方针或许相关调集方针时,能够依据方针联系模型直接获取,所以它是全主动的。而 Mybatis 在查询相关方针或相关调集方针时,需求手动编写 sql 来完结,所以,称之为半主动 ORM 映射东西。

Mybatis 是否支撑推迟加载?假如支撑,它的完结原理是什么?

Mybatis 仅支撑 association 相关方针和 collection 相关调集方针的推迟加载,association指的便是1对1,collection 指的便是一对多查询。在 Mybatis 装备文件中,能够装备是否启用推迟加载 lazyLoadingEnabled=true|false。

它的原理是,运用 CGLIB 创立方针方针的署理方针,当调用方针办法时,进入阻拦器办法,比方调用 a.getB().getName(),阻拦器 invoke()办法发现 a.getB()是 null 值,那么就会独自发送事先保存好的查询相关 B 方针的 sql,把 B 查询上来,然后调用 a.setB(b),所以 a 的方针 b 特点就有值了,接着完结 a.getB().getName()办法的调用。这便是推迟加载的基本原理

写在最终

本文后续持续补充中,以上仅为个人对以往材料的粗略整合,留下后续依据实际情况精密整理。2023.04.02晚22点,咱们早些休息,身体健康,日子愉快。朝もお昼も夢の中も-MACO,希望这首歌给咱们朝晨带来快乐