可以简单的理解为springIoc和DI都是一种思想,而DI是springIoc的具体实现。以往我们创建对象都需要通过new关键字进行对象的创建,随着对象的依赖关系逐渐复杂,new的方式让代码显得更加繁琐。而springIoc(控制反转)的出现可以让开发者只关注代码逻辑的开发,而将所有的对象统一交给Spring容器进行管理,而spring容器管理对象的方式就是通过DI达到的,DI(依赖注入)的方式有三种:Setter、构造方法、接口;具体实现可参照:Spring-Ioc-DI的三种注入方式:_暇光署墨的博客-CSDN博客_spring ioc注入的三种方式
- singleton:使用该属性定义bean时,IOC容器仅创建一个Bean实例,IOC容器每次返回的是同一个Bean实例
- prototype:使用该属性定义bean时,IOC容器可以创建多个Bean实例,每次返回都是一个新的Bean实例
- request:该属性仅对http请求产生作用,使用该属性定义Bean时,每次HTTP请求都会创建一个新的Bean,使用WebApplicationContext环境
- session:该属性仅使用于HTTP session,同一个session共享一个Bean实例,不同的session使用不同的实例
- global-session:该属性仅使用于HTTP session,同session不同的是,不同的session共享同一个实例
spring的Bean默认是单例模式的,单例bean是指IOC容器中就只有这么一个bean,是全局共享的,有多少个线程来访问用的都是这个bean。由于框架并没有对bean进行多线程的封装处理,所以单例模式的bean不是线程安全的;最简单的办法就是改变bean的作用域 把 "singleton"改为’‘protopyte’ 这样每次请求Bean就相当于是 new Bean() 这样就可以保证线程的
安全了。
spring 配置文件中 节点的 autowire 参数可以控制 bean 自动装配的方式:
- default - 默认的方式和 “no” 方式一样
- no - 不自动装配,需要使用 节点或参数
- byName - 根据名称进行装配
- byType - 根据类型进行装配
- constructor - 根据构造函数进行装配
JDK动态代理的实现是通过被代理对象实现的接口产生其代理对象的;带定义getProxy()方法的时候通过类加载器获取被代理对象实现的接口,通过被代理对象的类加载器以及实现的接口创建并返回代理对象。
CGLIB动态代理是通过创建被代理对象的子类来创建代理对象的;在定义getProxy()方法的时候,代理对象是通过创建并代理的子类来创建的,使用Enhancer来创建对象,并制定父类,并进行setCallBack进行回调,使用create()创建并返回getProxy。
spring底层会根据类是否实现接口来进行判断,是使用jdk还是cglib。
AOP(面向切面编程),是一种“横切”的技术(底层实现是动态代理),对原油的业务逻辑进行拦截,并对原有的业务逻辑进行增强,在不改变原有业务的情况下对业务逻辑进行增强。有几个名词专有名词要注意:
JoinPoint-连接点:在应用执行过程中能够插入切面(Aspect)的一个点
Pointcut-切入点:实际被增强的方法,就是切入点,比如说有俩方法,一个方法被增强了一个没被增强,则被增强的方法叫做切入点,没被增强的方法就不能叫做切入点
通知/增强:真正被增强的逻辑部分称为通知
切点:添加到切入点的新增的业务方法
切面:定义切点方法的类
使用场景:异常处理、事务提交/回滚、检验是否登陆
1、前端发送请求被前端控制器DispatcherServlet拦截
2、前端控制器调用处理器映射HandlerMapping对请求URL进行解析,解析之后返回给前端控制器
3、前端控制器调用处理器适配器处理调用链
4、处理器适配器基于反射通过适配器设计模式完成处理器(控制器)的调用,处理用户请求
5、处理器适配器将控制器返回的视图和数据信息封装成ModelAndVIew响应给前端控制器
6、前端控制器调用视图解析器ViewResolve对ModelAndView进行解析,将解析结果(视图资源和数据)响应给前端控制器
7、前端控制器调用视图view组件将数据进行渲染,将渲染的结果(静态资源)响应给前端控制器
8、前端控制器响应用户请求
#{}:
(1)、编译好SQL后语句再去取值
(2)、将传入的数据都当成一个字符串,会对传入的变量自动加一个单引号。如:user_id = #{userId},如果传入的值是111,那么解析成sql时的值为user_id = ‘111’,如果传入的值是id,则解析成的sql为user_id = ‘id’。
(3)、参数占位符,即预编译
${}:
(1)取值以后再去编译SQL语句
(2)将传入的参数直接显示生成在sql中,且不加任何引号。如:user_id = ${userId},如果传入的值是111,那么解析成sql时的值为user_id = 111 , 如果传入的值是id,则解析成的sql为user_id = id。
(3)字符串替换符,即SQL拼接
自增主键:
第一种方式是使用
useGeneratedKeys + keyProperty组合的方式,其中userGeneratedKeys代表是告诉mybatis要使用自增生成的主键,keyProperty是告诉mybatis主键字段是哪个,如下:
"insert" parameterType="Person" useGeneratedKeys="true" keyProperty="id"> INSERT INTO person(name, pswd) VALUE (#{name}, #{pswd})第二种方式是通过
来指定sql语句获取生成的主键ID,如下:
"insert" parameterType="Person"> "id" resultType="long" order="AFTER"> SELECT LAST_INSERT_ID() INSERT INTO person(name, pswd) VALUE (#{name}, #{pswd})
第 1 种: 通过在查询的 sql 语句中定义字段名的别名,让字段名的别名和实体类 的属性名一致。
select order_id id, order_no orderno ,order_price price form orders where order_id=#{id};第 2 种: 通过来映射字段名和实体类属性名的一一对应的关系。
select * from orders where order_id=#{id} <result property = “orderno” column =”order_no”/>
在实体类中加入对应的关联查询的字段或集合;
(1)、一对多的关系映射使用的是collection
(2)、一对一的关系映射使用的是association
1、Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能。
2、Mybatis 提 供 了 9 种 动 态 sql 标 签 : trim|where|set|foreach|if|choose|when|otherwise|bind。
3、其执行原理为,使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。
(1)支持!MyBatis 有两种加载方式:立即加载和延迟加载。
MyBatis 只支持 association 关联对象和 collection 关联集合对象的延迟加载,association 指的是一对一关联查询的,collection 指的是一对多关联查询。
(2)在 MyBatis 配置文件中,有两种方式可以配置是否启用延迟加载:
第一种是在配置文件的
标签中为所有嵌套查询设为延迟加载 第二种是在
、 中添加 < fetchType > 设置
"lazyLoadingEnabled" value="true"/> "lazyLoadTriggerMethods" value=""/> (3)一般情况下,一对多查询使用延迟加载,一对一查询使用立即加载。因为一对多可能有上万甚至更多的数据,如果立即加载的话会很占用空间,所以使用延迟加载;而一对一查询的话,只有一条数据,立即加载也不会有什么影响,所以可以立即加载。
使用Mybatis框架批量插入的3种方法:多次调用insert方法、foreach标签、batch模式
Mybatis在插入单条数据的时候有两种方式返回自增主键:
1、对于支持生成自增主键的数据库:增加 useGenerateKeys和keyProperty ,
标签属性。 2、不支持生成自增主键的数据库:使用
标签。
一级缓存为 sqlsesson 缓存,缓存的数据只在 SqlSession 内有效。在操作数据库的时候需要先创建 SqlSession 会话对象,在对象中有一个 HashMap 用于存储缓存数据,此 HashMap 是当前会话对象私有的,别的 SqlSession 会话对象无法访问。
二级缓存是 mapper 级别的缓存,也就是同一个 namespace 的 mapper.xml ,当多个 SqlSession 使用同一个 Mapper 操作数据库的时候,得到的数据会缓存在同一个二级缓存区域
二级缓存默认是没有开启的。需要在 setting 全局参数中配置开启二级缓存
开启二级缓存步骤:
1、conf.xml 配置全局变量开启二级缓存
"cacheEnabled" value="true"/>默认是false:关闭二级缓存