目录
目录
通过spring的注解完成java对象的创建,属性,替代xml文件
3.通常使用JDBC访问数据库, 还是mybatis访问数据库怎么处理事务
事务的传播行为 : 控制业务方法是不是有事务的, 是什么样的事务的。
spring全家桶:spring , springmvc ,spring boot , spring cloud
spring: 出现是在2002左右,解决企业开发的难度。减轻对项目模块之间的管理, 类和类之间的管理, 帮助开发人员创建对象,管理对象之间的关系。
spring核心技术 ioc , aop 。能实现模块之间,类之间的解耦合。
依赖:classa中使用classb的属性或者方法, 叫做classa依赖classb
学习内容:
1、分析程序存在的问题(以往的三层架构)出现的原因就是我们在new 接口的实现类时给new 死了。相当于右边是写死的。
private UserDao userDao = new UserDaoImplMySql();
如果我们后期想修改的话,那么就必须修改这行代码,但是这样的话就会修改原有的程序。违反了OCP开闭原则。
2、OCP开闭原则什么是OCP开闭原则?---》OCP是软件七大开发原则当中最基本的一个原则,开闭原则。对什么开?对扩展开放对什么关闭?对修改关闭。OCP原则是最核心的,最基本的,其他六个原则都是为这个原则服务的。
OCP原则的核心是什么?只要你在扩展系统功能的时候,没有修改以前写好的代码,那么你就是符合OCP原则的。反之,如果在扩展系统功能的时候,你修改了之前的代码,那么这个设计是失败的,违反了OCP原则。当进行系统功能扩展的时候,如果动了之前稳定的程序,修改了之前的程序,之前所有的程序都要进行重新测试,这是我们不想看到的,因为非常麻烦。
3、什么是控制反转?控制反转:IoC(Inversion of Control)反转是什么呢? 反转的是两件事:第一件事:我不在程序中采用硬编码的方式来new对象了。(new对象我不管了,new对象的权利交出去了。)第二件事:我不在程序中采用硬编码的方式来维护对象的关系了。(就是在一个具体的实现类中出现了另一个实现类的对象,比如业务层实现类出现了数据访问层的实现类,因为这个时候就违反了DIP原则,因为这时候如果数据访问层的实现类一旦改变,那么就会影响到业务层实现类的改变,打破了原有的类与类之间的关系)(对象之间关系的维护权,我也不管了,交出去了。)
重点:其实这就是出现了后来了控制反转和依赖注入,控制反转是将new 对象的权力交给springIOC容器,然后依赖注入就是维护对象之间的关系(其实就是给类中的引用变量属性赋值 ,因为注入的是另一个类,所以涉及到类与类之间的关系),这就是维护类与类之间的关系控制反转:是一种编程思想。或者叫做一种新型的设计模式。由于出现的比较新,没有被纳入GoF23种设计模式范围内。
IoC
IoC是Spring的两个核心功能之一。
容器:是一个服务器软件, 一个框架(spring)
为什么要使用 ioc : 目的就是减少对代码的改动, 也能实现不同的功能。 实现解耦合。
java中创建对象有哪些方式:
1. 构造方法 , new Student()
2. 反射
3. 序列化
4. 克隆
5. ioc :容器创建对象
6. 动态代理
ioc的体现:
servlet
1. 创建类继承HttpServlet
2. 在web.xml 注册servlet , 使用 myservlet
com.bjpwernode.controller.MyServlet1
3. 没有创建 Servlet对象, 没有 MyServlet myservlet = new MyServlet()
4. Servlet 是Tomcat服务器它为你创建的。 Tomcat也称为容器
Tomcat作为容器:里面存放的有Servlet对象, Listener , Filter对象
IoC的技术实现 ,
DI 是ioc的技术实现
DI(Dependency Injection) :依赖注入, 只需要在程序中提供要使用的对象名称就可以, 至于对象如何在容器中创建, 赋值,查找都由容器内部实现。
spring的第一个核心功能 ioc
ioc (Inversion of Control) : 控制反转, 是一个理论,概念,思想。
描述的:把对象的创建,赋值,管理工作都交给代码之外的容器实现,也就是对象的创建是有其它外部资源完成。
控制: 创建对象,对象的属性赋值,对象之间的关系管理。
反转: 把原来的开发人员管理,创建对象的权限转移给代码之外的容器实现。 由容器代替开发人员管理对象。创建对象,给属性赋值。
正转:由开发人员在代码中,使用new 构造方法创建对象, 开发人员主动管理对象。
public static void main(String args[]){
Student student = new Student(); // 在代码中, 创建对象。--正转。
}
spring是使用的di(依赖注入)实现了ioc的功能, spring底层创建对象,使用的是反射机制。
spring是一个容器,管理对象,给属性赋值, 底层是反射创建对象。
Spring 八大模块
Spring Core(8大模块的基石):控制反转IoC。
Spring Aop:面向切面编程。
Spring Web MVC:Spring自己提供了一套MVC框架。
Spring ORM:Spring支持集成常见的ORM框架:Mybatis、Hibernate...。
Spring DAO:提供了单独的支持JDBC操作的API。
Spring Web:支持集成常见的Web框架:struts、webwoek。
Spring Webflux:Spring提供响应式web框架 (spring5之后新加的模块)。
Spring Context:国际化消息、事件传播、验证的支持、企业服务、Velocity和FreeMarker集成的支持。
Spring的特点:
------------------------------------------------------------------------------
框架怎么学: 框架是一个软件,其它人写好的软件。
1)知道框架能做什么, mybatis--访问数据库, 对表中的数据执行增删改查。
2)框架的语法, 框架要完成一个功能,需要一定的步骤支持的,
3)框架的内部实现, 框架内部怎么做。 原理是什么。
4)通过学习,可以实现一个框架。
Spring框架的步骤:
1.pom.xml文件中加入依赖
2.创建类:接口,实现类,实体类
3.创建spring的配置文件,使用声明对象
4.使用容器中的对象,通过ApplicationContext接口和他的实现类ClassPathXmlApplicationContext("spring配置文件路径")的方法getBean();
获取容器对象 context = new ClassPathXmlApplicationContext("xml文件");
context.getBean("bean名称");//获取bean对象
//执行这行代码,就相当于启动spring容器了。可以指定多个配置文件 , 分隔("","","")
Application applicationContext = new ClassPathXmlApplicationContext("类路径下的spring配置文件");
//获取bean对象
applicationContext.getBean("bean的id");
Spring配置文件:
命名可以自定义,文件最好放在类路径中,方便后期的移植。放在resources根目录下,就相当于放到了类的根路径下。
beans配置文件中,创建对象。
一个bean就是一个对象。
id:是这个bean的标识,不能重复,是唯一的标识
class:必须是类的全路径,全限定类型(带包的类名)
<property>标签属性:
name:set方法去掉set,首字母小写的值。(因为我们JavaBean规范下set方法,是属性名首字母大写,加set前缀,所以如果set方法符合JavaBean规范的话,这个name就直接填属性名)。
value:注入简单类型的值
ref:当值不是简单类型时用这个
方法一:set注入:
spring容器创建对象默认用的是通过反射机制执行类的无参数构造方法 ,通过<property />标签对对象进行赋值,使用的是类的setting方法,所以类中一定要有属性对应的setting方法。
简单数据类型有:
方法二:构造注入:
spring调用类有参数的构造方法,在创建对象的时候,在构造方法中给对象赋值。
构造注入使用: <constructor-arg>标签
<constructor-arg>标签:一个<constructor-arg>表示构造方法一个参数
<constuctor-arg>标签属性:
name:表示构造方法的形参名
index:表示构造方法的参数的位置,参数从左往右位置是0,1,2的顺序
value:构造方法的形参类型是简单类型,使用value
ref:构造方法的形参类型是引用类型的,使用ref
<bean id="student" class="org.example.Student"> //推荐使用name属性,可读性更高
<constuctor-arg name="myname" value="张三" />
<constuctor-arg name="myage" value="20" />
<constuctor-arg name="myschool" value="myxuexiao" />
</bean>
以上,spring会去类中去找有3个参数的构造方法( 有多少个 标签就去找有几个参数的构造方法),name对应该方法的形参参数名,简单类型用value,引用类型用ref
index指定属性名
<bean id="student" class="org.example.Student">
<!--使用index属性-->
<constructor-arg index= “1” value=“张三” />
<constructor-arg index= “0" value=“20” />
<constructor-arg index= “2” ref=“myXueXiao” />
</bean>
<!-- 以上,spring会去类中去找有3个参数的构造方法( 有多少个<constructor-arg/> 标签就去找有几个参数的构造方法),index对应该方法的形参排列顺序,简单类型用value,引用类型用ref-->
//省略index,默认按照index=0,1,2来赋值
<bean id="student" class="org.example.Student">
<constuctor-arg value="张三" />
<constuctor-arg value="20" />
<constuctor-arg value="myxuexiao" />
</bean>
构造注入创建文件对象:
<bean id="mufile" class=java.io.File">
<constructor-arg name="parent" value=“电脑中的父路径” />
<constructor-arg name="child" value=“加后缀的文件名字” />
</bean>
自动装配:
如何引入外部的Properties文件:
第一步:引入context命名空间:
在beans 标签内 加入 xmlns:context="http://www.springframework.org/schema/context
第二步:使用标签
<context:property-placeholder localhost="properties文件路径">
第三步:取值
"${properties文件的key}"
---------------------------------------------------------------------------------------------
多个配置文件优势
1.多个文件的大小比一个文件要小很多。效率高
2.避免多人竞争带来的冲突。
如果你的项目有多个模块(相关的功能在一起) ,一个模块一个配置文件。
学生考勤模块一个配置文件, 张三
学生成绩一个配置文件, 李四
可以用一个配置文件包含其他的配置文件
classpath:类路径(target后的class文件下的路径)
多文件的分配方式:
1. 按功能模块,一个模块一个配置文件
2. 按类的功能,数据库相关的配置一个文件配置文件, 做事务的功能一个配置文件, 做service功能的一个配置文件等
bean的作用域(八种)
singleton(单例):一个容器里面只有一个这个bean对象
prototype(原型/多例):容器种有多个这个bean对象,每次需要用的时候就去创建一个新的。
以下两个要求是web项目才可以使用。
request(请求):为每个请求保留一个这个bean对象
session(会话):为每个会话保留一个这个bean对象
Bean的实例化方式
Spring为Bean提供了多种实例化方式,通常包括4种方式。(也就是说在Spring中为Bean对象的创建准备了多种方案,目的是:更加灵活)
* 第一种:通过构造方法实例化
* 第二种:通过简单工厂模式实例化(定义一个类的静态方法返回一个Bean对象)
* 第三种:通过factory-bean实例化 (定义一个类创建实例Bean,通过实例方法返回一个Bean对象)
前3种:
* 第四种:(定义FactoryBean,通过FactoryBean对象的实例方法生成Bean对象,这种方式可以在实例方法中将Bean对象进行加工后创建出来)通过FactoryBean接口实例化(第四种方式,就是通过代码的形式,原理和第三种方法一样)
PersonFactoryBean实现FactoryBean接口的三个实现方法:
BeanFactory和FactoryBean的区别:
BeanFactory:是一个Bean工厂,是用于创建Bean对象的
FactoryBean:是一个Bean,是一个特殊的Bean,是实现了FactoryBean的Bean,我们可以通过FactoryBean创建出加工后的Bean对象。
Bean的生命周期:
参考源码:AbstractAutoWireCapableBeanFactory类的doCreateBean()的方法
生命周期五步(Bean生命周期浅程度理解)
第一步:实例化Bean(调用无参数构造方法)
第二步:Bean属性赋值(set方法注入)
第三步:初始化Bean(Bean的init方法,这个init方法需要自己写,自己配)
第四步:使用Bean
第五步:销毁Bean(关闭spring容器的时候会调用Bean的destroy方法,这个destroy方法需要自己写自己配)
对于init方法和destroy,在类中写好,配置文件指定对应的init方法是哪个,destroy方法是哪个。
下图的初始化方法(init)是initBean方法, 销毁方法(destroy)是destroyBean方法
声明周期七步(Bean生命周期中程度理解)
在初始化Bean的前和后分别添加一步 (Bean后处理器)
编写一个类实现BeanPostProcessor类i,并且重写before和after方法。
第一步:实例化Bean(调用无参数构造方法)
第二步:Bean属性赋值(set方法注入)
第三步:执行Bean后处理器的before方法
第四步:初始化Bean(Bean的init方法,这个init方法需要自己写,自己配)
第五步:执行Bean后处理器的after方法
第六步:使用Bean
第七步:销毁Bean(关闭spring容器的时候会调用Bean的destroy方法,这个destroy方法需要自己写自己配)
这两步是针对所有的Bean的,不是指定的某一个Bean。
声明周期十步(Bean生命周期深程度理解)
检查Bean是否实现了某些特定的接口,如果实现了相关的接口,就会调 用相关的实现方法。
第一步:实例化Bean(调用无参数构造方法)
第二步:Bean属性赋值(set方法注入)
第三步:检查Bean是否实现了Aware的相关接口(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware),并设置相关依赖
第四步:执行Bean后处理器的before方法
第五步:检查Bean是否实现了InitializingBean接口,并调用接口方法
第六步:初始化Bean(Bean的init方法,这个init方法需要自己写,自己配)
第七步:执行Bean后处理器的after方法
第八步:使用Bean
第九步:检查Bean是否实现了DisPosableBean接口,并调用接口方法
第十步:销毁Bean(关闭spring容器的时候会调用Bean的destroy方法,这个destroy方法需要自己写自己配)
如何将我们new的对象交给spring管理:
DefaultListableBeanFactory factory = new DefaultListableBeanFactory()
factory.registerSingleton("Bean的id",要放入的对象);
Bean的循环依赖问题:
基于注解的di: 通过注解完成java对象创建,属性赋值。
使用注解的步骤:
1.加入maven的依赖 spring-context ,在你加入spring-context的同时, 间接会加入spring-aop的依赖。使用注解必须使用spring-aop依赖
2.在类中加入spring的注解(多个不同功能的注解)
3.在spring的配置文件中,加入一个组件扫描器的标签,说明注解在你的项目中的位置
2、学习的注解:
1.@Component(创建普通对象的注解)
2.@Respotory(放在dao层的实现类上面的,写法和Component一样)
3.@Service(放在service层的实现类上面的,写法和Component一样)
4.@Controller(放在controller层控制器上面的,写法和Component一样)
2、3、4其实就是一个Component,只是一个别名,为了区分MVC三层架构,有挺好的可读性。
5.@Value(用于赋简单类型的值)这个注解可以出现在属性、set方法、构造方法、形参上
6.@Autowired (赋引用类型对象,默认是byType来赋值的,如果想指定哪一个对象要在这个注解下面添加@Qualifier("对象名"))这个注解可以出现在属性、set方法、构造方法、形参上。
7.@Resource(赋引用类型对象 默认是byName来赋值的,这个注解不属于spring的注解,是JDK扩展包中的。) 这个注解可以出现在属性、set方法上
@Resource(name="对象名")
@Component(value = "myStudent")
@Component 创建对象的,等同于的功能
属性:value 就是对象的名称,也就是bean的id值 如果不写,自动生成的id值是类名并且首字母小写
value的值是唯一的,创建的对象在整个spring容器中就一个
位置:在类的上面 @Component(value = "myStudent")等同于
3、spring.xml配置文件中
spring框架中如果使用注解创建对象需要通过声明组件扫描器给容器添加对象
声明组件扫描器(component-scan),组件就是java对象
base-package:指定注解在你的项目中的包名。
component-scan工作方式:spring会扫描遍历base-package指定的包,在包中和子包中的所有类,找到类中的注解,按照注解的功能创建对象,或给对象赋值。
指定多个包的三种方式:
<context:component-scan base-package="com.wangkaiping.ba01" />
<context:component-scan base-package="com.wangkaiping.ba02" />
<context:component-scan base-package="com.wangkaiping.ba03" />
2.用(;或者,分隔)
<context:component-scan base-package="com.wangkaiping.ba01;com.wangkaiping.ba02" />
3.直接指定父包
<context:component-scan base-package="com.wangkaiping" />
如何只让包中的指定注解生效呢? 
通过spring的注解完成java对象的创建,属性,替代xml文件
实现步骤:
1.加入依赖
2.创建类,在类中加入注解
3.创建spring的配置文件,声明组件扫描器的标签,指名注解在你的项目中的位置。(也可以创建一个配置类,加@Configuration,代替配置文件。@ComponentScan包扫描注解指定需要扫码的包)
4.使用注解创建对象,创建容器ApplicationContext
如果是注解的方式配置的话,需要通过另外一种方式获取容器。
new AnnotationConfigApplicationContext(配置类.class)
JdbcTemplate
Jdbc是Spring提供的一个JDBC的模板类,是对JDBC的封装,简化JDBC代码(也可以不使用,可以让Spring去集成ORM框架:如Mybatis等...)。
创建数据源Jdbc指定数据源使用。
数据源可以使用德鲁伊、C3P0、等等,也可以自己写一个类,实现DateSource接口,重新方法。
aop
1.动态代理
实现方式:jdk动态代理,使用jdk中的Proxy,Method,InvocaitonHanderl创建代理对象。
jdk动态代理要求目标类必须实现接口
cglib动态代理:第三方的工具库,创建代理对象,原理是继承。 通过继承目标类,创建子类。
子类就是代理对象。 要求目标类不能是final的, 方法也不能是final的
2.动态代理的作用:
1)在目标类源代码不改变的情况下,增加功能。
2)减少代码的重复
3)专注业务逻辑代码
4)解耦合,让你的业务功能和日志,事务非业务功能分离。
3.Aop:面向切面编程, 基于动态代理的,可以使用jdk,cglib两种代理方式。
Aop就是动态代理的规范化, 把动态代理的实现步骤,方式都定义好了,
让开发人员用一种统一的方式,使用动态代理。
4. AOP(Aspect Orient Programming)面向切面编程
Aspect: 切面,和业务逻辑没有关系的部分,给你的目标类增加的功能,就是切面。 像上面用的日志,事务都是切面。
切面的特点: 一般都是非业务方法,独立使用的。
用一句话总结AOP:将于核心业务无关的代码提取出来,形成一个独立的组件,然后以横向交叉的方式应用到业务流程当中的过程被称为AOP
AOP的优点:
*第一:代码复用性增强。
*第二:代码易维护。
*第三:使开发者更关注业务逻辑。
Orient:面向, 对着。
Programming:编程
oop: 面向对象编程
怎么理解面向切面编程 ?
1)需要在分析项目功能时,找出切面。
2)合理的安排切面的执行时间(在目标方法前, 还是目标方法后)
3)合理的安全切面执行的位置,在哪个类,哪个方法增加增强功能
术语:
1)Aspect:切面,表示增强的功能, 就是一堆代码,完成某个一个功能。非业务功能,常见的切面功能有日志, 事务, 统计信息, 参数检查, 权限验证。
2)JoinPoint:连接点 ,连接业务方法和切面的位置。 就某类中的业务方法 JoinPoint在增强方法的形参里。增强方法需要用到目标类方法中的内容的话,就在增强方法里加入参数 doSome(JoinPoint jp),JoinPoint必须放在形参里的第一位 jp.getSignature()就是目标类方法,可以通过这个jp获得目标类方法的内容,如方法名,实参、修饰符等等....
3)Pointcut : 切入点 ,指多个连接点方法的集合。多个方法
4)目标对象: 给哪个类的方法增加功能, 这个类就是目标对象
5)Advice:通知,通知表示切面功能执行的时间。
说一个切面有三个关键的要素:
1)切面的功能代码,切面干什么
2)切面的执行位置,使用Pointcut表示切面执行的位置
3)切面的执行时间,使用Advice表示时间,在目标方法之前,还是目标方法之后。
5.aop的实现
aop是一个规范,是动态的一个规范化,一个标准
aop的技术实现框架:
1.spring:spring在内部实现了aop规范,能做aop的工作。
spring主要在事务处理时使用aop。
我们项目开发中很少使用spring的aop实现。 因为spring的aop比较笨重。
2.aspectJ: 一个开源的专门做aop的框架。spring框架中集成了aspectj框架,通过spring就能使用aspectj的功能。
aspectJ框架实现aop有两种方式:
1.使用xml的配置文件 : 配置全局事务
2.使用注解,我们在项目中要做aop功能,一般都使用注解, aspectj有5个注解。
目标类必须实现接口
如果想要给一个目标类的方法增强,定义一个增强方法的切面类,切面类中定义的是一些增强的方法。然后在该切面类的上面加@Aspect。在切面类方法中添加相应的注解,表示在哪个类或者哪个类的方法执行时,在其前或后添加这些增强功能。 这个切面类类也要添加到容器中管理(通过注解或者xml文件都可以),最后还要在xml文件中添加 自动生成代理对象。
获取目标对象会得到目标类的代理类对象,执行方法,就会执行代理对象对应的方法。
aop功能步骤:
步骤:
1.在pom文件中添加依赖
2.在切面类中添加注解@Aspect,也需要@Component注解加入spring容器。
3.将切面类添加到容器中。
在xml文件中要添加自动代理生成标签<aop:aspectj-autoproxy />通过这个标签之后才会生成代理类
全注解式开发(不使用xml文件)
6.学习aspectj框架的使用。
切面的执行时间, 这个执行时间在规范中叫做Advice(通知,增强),有以下注解,放在切面的方法上面。
在aspectj框架中使用注解表示的。也可以使用xml配置文件中的标签
1)@Before (前置通知定义方法 有一个参数value="" 是切入点表达式)
2)@AfterReturning (后置通知定义方法,有两个参数,一个value="" 是切入点表达式,另一个是returning="在后置方法中的参数名")//这个参数是目标方法的返回值,目标类方法有返回值的时候用
@AfterReturning(value="",returning="res")
res是简单类型的话,相当于传递一个值参数,不会对目标方法返回的结果造成影响。
res如果是一个引用对象,后置通知方法执行的操作这个对象会影响到目标方法返回的结果
public void doOther(Object res){
这里的res就是目标类方法的返回值。
}
3)@Around(环绕通知经常做事务,在目标方法之前开启事务,方法执行,提交事务),范围最大,前环绕在前置(Before)之前,后环绕在后置(AfterReturning)和最终通知之后。
4)@AfterThrowing (异常通知) (程序发生异常后会出现异常通知,后置和后环绕都没有了)
5)@After (最终通知)
以上5种通知都可以在方法中添加一个参数 JoinPoint joinPoint,可以通过joinPoint获取目标方法的方法名,返回值类型,修饰符等。
当同一个目标方法被多个切面织入的话,谁先执行呢?
这时候就要通过一个注解 @Order(i) i是一个数字,数值越小越先执行。(加在切面类上面)
2)表示切面执行的位置,使用的是切入点表达式。
execution(* *..service.*.*(..)),指定这个需要执行这个通知的切点
切入点表达式:
execution ( 修饰符 返回值类型 ..service.类名.方法名(参数)[异常] )
execution ( * *..service..*.*(..) )
切入点表达式复用:
本类使用:
跨类使用:
AOP通知的执行顺序
①环绕通知:@Around
②前置通知:@Before
③执行连接点方法
④环绕通知:@Around
⑤后置通知:@After
⑥正常返回通知:@AfterReturning,如果发生异常那么就是异常通知@AfterThrowing
Spring对事物的支持
1.什么是事务
讲mysql的时候,提出了事务。 事务是指一组sql语句的集合, 集合中有多条sql语句
可能是insert , update ,select ,delete, 我们希望这些多个sql语句都能成功,
或者都失败, 这些sql语句的执行是一致的,作为一个整体执行。
2.在什么时候想到使用事务
当我的操作,涉及得到多个表,或者是多个sql语句的insert,update,delete。需要保证
这些语句都是成功才能完成我的功能,或者都失败,保证操作是符合要求的。
在java代码中写程序,控制事务,此时事务应该放在那里呢?
service类的业务方法上,因为业务方法会调用多个dao方法,执行多个sql语句
3.通常使用JDBC访问数据库, 还是mybatis访问数据库怎么处理事务
jdbc访问数据库,处理事务 Connection conn ; conn.commit(); conn.rollback();
mybatis访问数据库,处理事务, SqlSession.commit(); SqlSession.rollback();
hibernate访问数据库,处理事务, Session.commit(); Session.rollback();
4.3问题中事务的处理方式,有什么不足
1)不同的数据库访问技术,处理事务的对象,方法不同,
需要了解不同数据库访问技术使用事务的原理
2)掌握多种数据库中事务的处理逻辑。什么时候提交事务,什么时候回顾事务
3)处理事务的多种方法。
总结: 就是多种数据库的访问技术,有不同的事务处理的机制,对象,方法。
5.怎么解决不足
spring提供一种处理事务的统一模型, 能使用统一步骤,方式完成多种不同数据库访问技术的事务处理。
使用spring的事务处理机制,可以完成mybatis访问数据库的事务处理
使用spring的事务处理机制,可以完成hibernate访问数据库的事务处理。
6.处理事务,需要怎么做,做什么
spring处理事务的模型,使用的步骤都是固定的。把事务使用的信息提供给spring就可以了
1)事务内部提交,回滚事务,使用的事务管理器对象,代替你完成commit,rollback
事务管理器是一个接口和他的众多实现类。
接口:PlatformTransactionManager ,定义了事务重要方法 commit ,rollback
实现类:spring把每一种数据库访问技术对应的事务处理类都创建好了。
mybatis访问数据库---spring创建好的是DataSourceTransactionManager
hibernate访问数据库----spring创建的是HibernateTransactionManager
怎么使用:你需要告诉spring 你用是那种数据库的访问技术,怎么告诉spring呢?
声明数据库访问技术对于的事务管理器实现类, 在spring的配置文件中使用声明就可以了
例如,你要使用mybatis访问数据库,你应该在xml配置文件中
2)你的业务方法需要什么样的事务,说明需要事务的类型。
说明方法需要的事务:
事务的隔离级别:有4个值。
DEFAULT:采用 DB 默认的事务隔离级别。MySql 的默认为 REPEATABLE_READ; Oracle默认为 READ_COMMITTED。
➢ READ_UNCOMMITTED:读未提交。未解决任何并发问题。
➢ READ_COMMITTED:读已提交。解决脏读,存在不可重复读与幻读。
➢ REPEATABLE_READ:可重复读。解决脏读、不可重复读,存在幻读
➢ SERIALIZABLE:串行化。不存在并发问题。
2) 事务的超时时间: 表示一个方法最长的执行时间,如果方法执行时超过了时间,事务就回滚。
单位是秒, 整数值, 默认是 -1.
事务的传播行为 : 控制业务方法是不是有事务的, 是什么样的事务的。
7个传播行为,表示你的业务方法调用时,事务在方法之间是如果使用的。
PROPAGATION_REQUIRED:(必须要有事物) A方法调用B方法
PROPAGATION_REQUIRES_NEW
PROPAGATION_SUPPORTS
以上三个需要重点掌握的
PROPAGATION_MANDATORY
PROPAGATION_NESTED
PROPAGATION_NEVER
PROPAGATION_NOT_SUPPORTED
3)事务提交事务,回滚事务的时机
1)当你的业务方法,执行成功,没有异常抛出,当方法执行完毕,spring在方法执行后提交事务。事务管理器commit
2)当你的业务方法抛出运行时异常或ERROR, spring执行回滚,调用事务管理器的rollback
运行时异常的定义: RuntimeException 和他的子类都是运行时异常, 例如NullPointException , NumberFormatException
3) 当你的业务方法抛出非运行时异常, 主要是受查异常时,提交事务
受查异常:在你写代码中,必须处理的异常。例如IOException, SQLException
总结spring的事务
1.管理事务的是 事务管理和他的实现类
2.spring的事务是一个统一模型
1)指定要使用的事务管理器实现类,使用
2)指定哪些类,哪些方法需要加入事务的功能
3)指定方法需要的隔离级别,传播行为,超时。
你需要告诉spring,你的项目中类信息,方法的名称,方法的事务传播行为。
spring框架中提供的事务处理方案
1.适合中小项目使用的, 注解方案。
spring框架自己用aop实现给业务方法增加事务的功能, 使用@Transactional注解增加事务。
@Transactional注解是spring框架自己注解,放在public方法的上面,表示当前方法具有事务。
可以给注解的属性赋值,表示具体的隔离级别,传播行为,异常信息等等
使用@Transactional的步骤:
1.需要声明事务管理器对象
<bean id="transactionManager" class="org.springframework.jdbc.DataSourceTransactionManager">
<property name="dataSource" ref="DataSource"/>
</bean>
2.开启事务注解驱动, 告诉spring框架,我要使用注解的方式管理事务。
tx的约束是:xmlns:tx="http://www.springframework.org/schema/tx“
<tx:annotation-driven transaction-manager="transactionManager"/>
然后在类或者方法上加@Transactional
3.在你的方法的上面加入@Transactional
spring使用aop机制:
创建@Transactional所在的类代理对象,给方法加入事务的功能。
spring给业务方法加入事务:
在你的业务方法执行之前,先开启事务,在业务方法之后提交或回滚事务,使用aop的环绕通知
@Around("你要增加的事务功能的业务方法名称")
Object myAround(){
开启事务,spring给你开启
try{
buy(1001,10);
spring的事务管理器.commit();
}catch(Exception e){
spring的事务管理器.rollback();
}
}
mybatis使用步骤,对象
第一步:准备数据库表
第二步:引入依赖 spring-context、spring-jdbc、mysql驱动、mybatis、mybatis-spring(Mybatis提供的与spring框架集成的依赖)、德鲁伊连接池、
第三步:基于三层架构实现,所以提前创建好所有的包mapper包、server包、impl包、domain包
domain包:放数据库映射的实体类,提供set、get、toString方法
mapper包、定义Mapper接口 ,定义方法
server包、impl包:放业务接口和业务实现类
第四步:.定义mapper文件 StudentDao.xml,在配置文件中配置命名空间,以及每一个方法对应的sql
第五步:编写jdbc.properties配置文件,指定数据库连接的信息
第六步:定义mybatis的主配置文件 mybatis.xml,指定mapper文件所在的路径
主配置文件:
1.数据库信息
<environment id="mydev">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--数据库的驱动类名-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--连接数据库的url字符串-->
<property name="url" value="jdbc:mysql://localhost:3306/springdb"/>
<!--访问数据库的用户名-->
<property name="username" value="root"/>
<!--密码-->
<property name="password" value="123456"/>
</dataSource>
2. mapper映射文件的位置
<mappers>
<mapper resource="com/bjpowernode/dao/StudentDao.xml"/>
<!--<mapper resource="com/bjpowernode/dao/SchoolDao.xml" />-->
</mappers>
第七步:编写spring.xml配置文件
扫描组件
引入外部的属性文件
数据源
SqlSessionFactoryBean配置
*注入mybatis核心配置文件路径
*指定别名包
*注入数据源
Mapper扫描配置器
*指定扫描的包(这里xml文件和Mapper接口放同一个包里)
事务管理器DataSourceTransactionManager
*注入数据源
启动事务注解
*注入事务管理器
Spring中的八大设计模式:
1、简单工厂模式
BeanFactory的getBean()方法,通过唯一标识来获取Bean对象,是典型的简单工厂模式(静态工厂模式)
2、工厂方法模式
FactoryBean是典型的工厂方法模式,在配置文件中通过factory-method属性来指定工厂方法,该方法时一个实例方法
3、单例模式
Spring用的是双重判断加锁的单例模式,
4、代理模式
Spring的AOP就是使用动态代理实现的
5、装饰器模式
6、观察者模式
7、策略模式
8、模板方法模式