MyBatis
一级缓存
默认是打开的
SqlSession级别的缓存,同一个SqlSession的发起多次同构查询,会将数据保存在一级缓存中。
在sqlsession 中有一个数据结构 是map 结构, 这个区域就是一级缓存区域,一级缓存区域中的 key 是由 sql 语句 方法参数 statement 等 组成的一个唯一值 对应的 value 就是 缓存内容 , 一级缓存 map 的生命周期 和当前 sqlSession 一致
二级缓存
SqlSessionFactory级别的缓存,同一个SqlSessionFactory构建的SqlSession发起的多次同构查询,会将数据保存在二级缓存中。
二级缓存指的是 同一个 namespace 下的 mapper二级缓存的数据结构 也是一个 map 二级缓存 需要 手动开启
<setting name="cacheEnabled" value="true"/> <!-- mybaits-config.xml中开启全局缓存(默认开启) -->
Druid
<!-- https://mvnrepository.com/artifact/com.alibaba/druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.16</version> </dependency>
PageHelper
PageHelper是适用于MyBatis框架的一个分页插件,使用方式极为便捷,支持任何复杂的单表、多表分页查询操作。
** 引入依赖**
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.10</version> </dependency>
配置MyBatis-config.xml
<configuration> <typeAliases></typeAliases> <plugins> <!-- com.github.pagehelper为PageHelper类所在包名 --> <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin> </plugins> <environments>...</environments> </configuration>
** PageHelper应用方式**
@Test public void testPagehelper(){ UserDao userDao = MyBatisUtils.getMapper(UserDao.class); PageHelper.startPage(1,2);//使用PageHelper设置分页条件 List<User> users = userDao.selectAllUsers(); for(User user : users){ System.out.println(user); } }
@Test public void testPageInfo(){ UserDao userDao = MyBatisUtils.getMapper(UserDao.class); PageHelper.startPage(6, 2); List<User> users = userDao.selectAllUsers(); PageInfo<User> pageInfo = new PageInfo<User>(users);//将分页查询的结果集保存在PageInfo对象中 System.out.println(pageInfo); }
传统的web开发中的缺点
缺点一:层与层之间的耦合度(接口与具体实现耦合在一起) 解决方法:不手动new对象,用第三方提供的Bean对象。
缺点二:通用的事务功能耦合在业务代码(第三方根据 要求为程序提供需要的Bean对象的代理对象,代理对象 内部动态结合业务和通用功能)
IOC 思想(控制反转)
“控制反转”或“反转控制”,强调的是原来在程序中创建Bean的权利反转给第三方。
谁是第三方者,工厂设计模式,BeanFactory,
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ThtRyrnL-1684765013985)(https://zhangliuhui.oss-cn-beijing.aliyuncs.com/img/image-20230501113223682.png)]
DI 思想
上面使用BeanFactory的方式已经实现的"控制反转",将Bean的创建权交给了BeanFactory,如果我们想将 UserDao的创建权也反转给BeanFactory,与此同时UserService内部还需要用到UserDao实例对象,
IoC 和 DI 的关系?
首先,先回答IoC和DI的是什么:
IoC:控制反转,将Bean的创建权由原来程序反转给第三方
DI:依赖注入,某个Bean的完整创建依赖于其他Bean(或普通参数)的注入 其次,
再回答IoC和DI的关系:
第一种观点:IoC强调的是Bean创建权的反转,而DI强调的是Bean的依赖关系,认为不是一回事
第二种观点:IoC强调的是Bean创建权的反转,而DI强调的是通过注入的方式反转Bean的创建权,认为DI 是IoC的其中一种实现方式
AOP 面向切面思想
AOP,Aspect Oriented Programming,面向切面编程,是对面向对象编程OOP的升华。OOP是纵向对一个 事物的抽象,一个对象包括静态的属性信息,包括动态的方法信息等。而AOP是横向的对不同事物的抽象,属 性与属性、方法与方法、对象与对象都可以组成一个切面,而用这种思维去设计编程的方式叫做面向切面编程
三种思想总结
1)IoC控制反转,是将程序创建Bean的权利反转给第三方;
2)DI依赖注入,某个完整Bean需要依赖于其他Bean(或属性)的注入;
3)AOP面向切面编程,用横向抽取方法(属性、对象等)思想,组装成一个功能性切面。
IOC 思想基于 IOC 容器完成,IOC 容器底层就是对象工厂
2.Spring 提供 IOC 容器实现两种方式:(两个接口)
BeanFactory:IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用
- 加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象
ApplicationContext:BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人 员进行使用
- 加载配置文件时候就会把在配置文件对象进行创建
Bean细节
- 注意:需要根据场景决定对象的单例、多例模式。
- 可以共用:Service、DAO、SqlSessionFactory(或者是所有的工厂)。
- 不可共用:Connection、SqlSession、ShoppingCart。
普通Bean 和 工厂 Bean
普通的bean : 在配置文件中定义的bean的类型 就是返回类型
工厂bean: 在配置文件中定义的bean类型可以和返回的bean类型不一样
饿汉式创建优势–>为什么spring bean 默认是单例
工厂创建之后,会将Spring配置文件中的所有对象都创建完成(饿汉式)。
提高程序运行效率。避免多次IO,减少对象创建时间。(概念接近连接池,一次性创建好,使用时直接获取)
如果默认是多例bean 首先创建多例bean 会消耗资源 还会占用堆空间
Spring的生命周期
- bean 的实例化 通过构造方法创建bean 的实例 默认是无参构造
- 给bean 的属性赋值 调用 set 方法
- 执行初始化的方法 需要配置初始化方法
- 得到完整的bean 对象 ,这时的bean 对象才能够使用
- 销毁bean 需要配置 销毁的方法
面试答案
- bean 的实例化 通过构造方法创建bean 的实例 默认是无参构造
- 给bean 的属性赋值
- 把 bean 的 实例 传递给 bean的后置处理器的方法 postProcessBeforeInitialization
- 执行初始化的方法
- 把 bean 的 实例 传递给 bean的后置处理器的方法 postProcessAfterInitialization
- 得到完整的bean 对象 ,这时的bean 对象才能够使用
- 销毁bean 当容器关闭的时候 调用销毁的方法
动态代理设计模式
动态创建代理类的对象,为原始类的对象添加辅助功能。
代理对象和真实对象的关系 像是兄弟 代理对象 对真实对象进行增强
CGlib动态代理实现(基于继承) 代理对象和真实对象的关系 就像是 父子
面向切面编程
AOP(Aspect Oriented Programming),即面向切面编程,利用一种称为"横切"的技术,剖开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
1.面向切面编程 利用AOP 可以对业务逻辑的各个部分进行隔离 从而使业务逻辑的各部分之间 耦合度降低,提高程序的可重用性,提好了开发效率,通俗的讲 可以实现不修改源代码的方式,在核心业务里面 添加新的功能
AOP 底层的原理 就是 动态代理 ,真正干活的 bean 是 代理bean , 代理bean 对真实bean 功能增强
- 连接点(Joinpoint):连接点是程序类中客观存在的方法,可被Spring拦截并切入内容。
- 说白了 类中的哪些方法 可以被增强 这些方法 就称为是 连接点
- 切入点(Pointcut):被Spring切入连接点。
- 真正被增强的方法 称为 切入点
- 通知、增强(Advice):可以为切入点添加额外功能,分为:前置通知、后置通知、异常通知、环绕通知,最终通知等。
- 实际增强的逻辑部分 称为通知(增强)
- 目标对象(Target):代理的目标对象 真实对象
- 引介(Introduction):一种特殊的增强,可在运行期为类动态添加Field和Method。
- 织入(Weaving):把通知应用到具体的类,进而创建新的代理类的过程。
- 代理(Proxy):被AOP织入通知后,产生的结果类。
- 切面(Aspect):由切点和通知组成,将横切逻辑织入切面所指定的连接点中。是一个动作 把通知 应用到 切入点的过程
切点: 真正要被增强的方法
通知:增强的业务代码
切面:切点 + 通知
1.如果是单例 bean , 随着容器的创建而创建 即 实例化,多例bean 是 获取的时候 实例化
2.属性注入
3.后处理器前置过程 即在初始化方法之前执行的 方法 postProcessBeforeInitialization
4.初始化方法
5.后处理器后置过程 即在初始化方法之后执行的 方法 postProcessAfterInitialization aop动态代理就在这一步
6.得到最终的 bean
7.销毁
注解开发
使用注解目的:简化 xml 配置
spring针对Bean管理创建对象提供的注解
(1)@Component
(2)@Service
(3)@Controller
(4)@Repository
开启组件扫描
<context:component-scan base-package="com.glls.java2301"></context:component-scan>
<context:component-scan base-package="com.glls" >
</context:component-scan>
@Autowired
先根据类型注入 再根据名字注入
@Qualifier:根据名称进行注入
和@Autowired 一起使用
@Resource
先根据名字注入 再根据类型注入
bean中属性值的注入
- @Autowired 基于类型自动注入 先根据类型注入 如果找到多个 再根据名称注入
- @Resource 基于名称自动注入 先根据名称注入 如果根据名称没找到 则根据类型找 根据类型 找到多个 则报错 找到一个则注入
- @Qualifier(“userDAO”) 限定要自动注入的bean的id,一般和@Autowired联用
- @Value 注入简单类型数据 (jdk8种+String)
Json处理
@RequestBody
可以获取请求体 需要在控制器的方法形参上使用 使用请求体中的参数 给当前形参赋值 将请求体中的json数据转为java对象
@ResponseBody
可以将返回的数据转为json类型
也可放在返回值上。
如果返回值是字符串就不用转为json了
@RestController
类上加了@RestController注解,等价于在类中的每个方法上都加了@ResponseBody
@RequestBody
@RequestBody, 接收Json参数
记住:
js 对象 转为 json 串 方法: JSON.stringify(user);
json串转为 js 对象的方法 : JSON.parse(jsonstr);
Jackson常用注解
@JsonFormat(pattern=“yyyy-MM-dd HH:mm:ss”,timezone = “GMT+8”)
属性名修改:@JsonProperty(“new_name”)
属性忽略:@JsonIgnore
FastJson
导入依赖
<!-- FastJson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
** 安装FastJson**
<mvc:annotation-driven>
<!-- 安装FastJson,转换器 -->
<mvc:message-converters>
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<!-- 声明转换类型:json -->
<property name="supportedMediaTypes">
<list>
<value>application/json</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>