Spring

1.本章学习内容

1.Spring框架概要

2.IOC容器

3.AOP

4.jdbcTemplate

5.事务管理

6.Spring5新特性

7.Spring整合MyBatis

2.Spring概要

概述:它是轻量级的开源的JavaEE框架

  • 轻量级:他的体积小,依赖的jar包比较少,并且不需要额外依赖其他的组件

  • 开源:免费提供源代码

  • 框架:可以简化我们构建软件的过程

目的:为了解决企业级应用的复杂性

核心:

  • IOC:控制反转- 把创建对象的过程交给Spring进行管理
  • AOP:面向切面编程 - 不修改源码进行功能增强

优点:

  • 方便解耦,简化开发

  • 对AOP编程的支持

  • 方便程序的测试

  • 方便整合其他各种的框架

  • 方便进行事务操作

  • 降低API开发

3.入门案例

4.IOC容器

概述:

  • 控制反转

  • 综上所述:控制反转就是 把创建对象,和对象的调用的过程交给Spring来管理 。目的是为了降低类与类之间的耦合性。

底层原理:

  • XML解析

  • 工厂模式

  • 反射

原理图解:

重要概念:

  1. IOC 容器:IOC的实现,依赖于IOC容器,而IOC容器的本质就是对象工厂

  2. IOC容器的实现:

    • BeanFactory:是最底层的接口,他只提供了最简单的容器功能:加载配置文件 和 创建对象

      • 当加载配置文件时,不会创建被配置的对象,只有在使用时,对象才会创建。

        • 好处:节省内存
        • 坏处:因为在服务器运行的时候去创建对象,会影响执行效率
    • ApplicationContext:应用上下文,它是继承了BeanFactory。它是Spring更高级的一个容器接口,他提供了更多有用的功能

      • 当配置文件的时候,会同时创建被创建配置的对象

        • 好处:效率高,将复杂的创建过程在服务器启动时完成
        • 坏处:耗费资源

3.ApplicationContext的两个实现类

  • ClassPathXmlApplicationContext:从项目中的resources文件中加载配置文件

  • FileSystemXmlApplicationContext:从文件系统读取配置文件(需要访问权限)

  • AnnotionConfigApplicationContext:读取注解配置

5.IOC操作 - Bean管理

概念:IOC操作 - Bean管理是指两个操作: 1.Spring创建对象 2.Spring注入属性(属性赋值)

实现方式:

​ 1.XML方式

​ 2.注解方式

5.1基于XML方式-创建对象

该方式与入门案列方式相同

bean标签中常用属性

  • id:唯一标识,通过该属性可以找到对应的Bean标签
  • class:类的全限定类名

注意事项

​ 创建对象时,默认执行无参构造方法来完成对象的创建(反射)

5.2基于XML方式-注入属性

DI:依赖注入,它是IOC的一个具体操作

分类

  1. 使用Set方法进行注入
  2. 使用构造器方式经行注入

演示:

1.实体类

public class Book {private String name;private String author;public Book(String name, String author) {this.name = name;this.author = author;}public Book() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", author='" + author + '\'' +'}';}
}

2.配置XML文件

Set方法

​ 属性注入通过<property>

name:实体类属性名

value:属性值

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 创建User对象--><bean id="book" class="com.wdzl.pojo.Book"><property name="name" value="Java从入门到入土"></property><property name="author" value="詹姆士"></property></bean>
</beans>

构造器方法

​ 属性注入通过<constructor-arg>

name:实体类属性名 index:通过索引

value:属性值

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 创建User对象--><bean id="book" class="com.wdzl.pojo.Book">
<!--        <constructor-arg name="name" value="Java高级数"></constructor-arg>-->
<!--        <constructor-arg name="author" value="赵子龙"></constructor-arg>--><constructor-arg index="0" value="Java高级数"></constructor-arg><constructor-arg index="1" value="赵子龙"></constructor-arg></bean>
</beans>

P命名空间注入

xmlns:p="http://www.springframework.org/schema/p" 引入约束

<bean id="book" class="com.wdzl.pojo.Book" p:name="Java入门宝典" p:author="詹姆士·赵大帅哥"></bean>

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- P命名空间注入--><bean id="book" class="com.wdzl.pojo.Book" p:name="Java入门宝典" p:author="詹姆士·赵大帅哥"></bean></beans>

3.测试

public class BookTest {@Testpublic void Test(){//1.加载配置文件ApplicationContext context = new ClassPathXmlApplicationContext("Beans2.xml");Book book = context.getBean("book", Book.class);System.out.println(book);}
}

特殊符号注入

​ 1.null

<constructor-arg name="name" ><null></null></constructor-arg>

​ 2.转义字符

<constructor-arg name="author" ><value>"&lt;关羽&gt;"</value></constructor-arg>

​ 3.CDATA

<constructor-arg name="author" ><value><![CDATA[<詹姆斯·屈波>]]></value></constructor-arg>

外部Bean

1.新建Moule,在pom.xml中添加依赖

2.按照三层架构成绩:Dao,Service,Web,在dao层中添加方法,在Service层中添加对Dao层的依赖(dao成员变量,对应的set方法)

3.配置对象信息

内部类

1.再上一个演示案例的基础上,创建两个实体类Emp和Dept,其中Emp包含Dept对象属性

2.配置对象信息

级联操作

1.方式一

2.方式二

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3vApStu1-1617199855683)(D:\图片\20210320162814.png)]

注意事项:

​ 针对方式2:一定要提供get. set方法,否则配置文件中的某些属性就会报红。

(基本数据类型)数组,集合属性的注入

1.创建一个实体类

2.配置对象属性

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="demo" class="com.wdzl.pojo.Demo"><!-- 字符串数组--><property name="strings"><array><value>你好</value><value>小老弟</value></array></property><!-- list集合--><property name="list"><list><value>hello</value><value>people</value></list></property><!-- map集合--><property name="map"><map><entry key="你好" value="世界"></entry><entry key="哈哈" value="屈波"></entry><entry key="好" value="唐康"></entry></map></property></bean></beans>
  • 引用数据类型

城市类:

省类:

2.配置对象信息

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/utilhttps://www.springframework.org/schema/util/spring-util.xsd"><util:list id="cityList"><value>西安</value><value>宝鸡</value><value>延安</value></util:list><bean id="province" class="com.wdzl.pojo.Province"><property name="cities" ref="cityList"></property></bean><!--    <bean id="city" class="com.wdzl.pojo.City">-->
<!--        <property name="cityName" value="西安"></property>-->
<!--    </bean>--><!--    <bean id="city2" class="com.wdzl.pojo.City">-->
<!--        <property name="cityName" value="宝鸡"></property>-->
<!--    </bean>-->
<!--    <bean id="city3" class="com.wdzl.pojo.City">-->
<!--        <property name="cityName" value="安康"></property>-->
<!--    </bean>-->
<!--    <bean id="city4" class="com.wdzl.pojo.City">-->
<!--        <property name="cityName" value="延安"></property>-->
<!--    </bean>--><!--   <bean id="province" class="com.wdzl.pojo.Province">-->
<!--       <property name="cities">-->
<!--           <list>-->
<!--               <ref bean="city"></ref>-->
<!--               <ref bean="city2"></ref>-->
<!--               <ref bean="city3"></ref>-->
<!--               <ref bean="city4"></ref>-->
<!--           </list>-->
<!--       </property>-->
<!--   </bean>--></beans>

FactoryBean:

概述:Spring中有两种类型的Bean,一种是普通Bean,一种是工厂Bean

  • 普通Bean:在配置文件中定义的Bean类型就是返回类型。
  • 工厂Bean:在配置文件中配置bean类型与返回类型不同。

演示:

创建一个工厂类

/*** 工厂Bean类型*/
public class MyBean implements FactoryBean<String> {/*** 获取对象:此方法中定义了注入MyBean时,真正返回的对象* @return* @throws Exception*/@Overridepublic String getObject() throws Exception {return "我是钢铁侠";}/*** 返回对象类型* @return*/@Overridepublic Class<?> getObjectType() {return null;}/*** 是否是单例* @return*/@Overridepublic boolean isSingleton() {return false;}}

配置对象信息

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="myBean" class="com.wdzl.pojo.MyBean"></bean>
</beans>

测试案例

5.3 Bean的作用域

**概述:**在Spring中,设置创建Bean实例是单例还是多例。默认情况,Bean是单例。

注意

Singletonprototype 的区别:

  1. Singleton :在加载配置文件时,对象便会创建,并且,只创建一个对象
  2. prototype :在加载配置文件时,并不会创建对象,在调用getBean方法时,才会创建对象,并且每次调用都会创建。

5.4 Bean的生命周期

概述:

​ 一个对象从创建到销毁的过程

过程:

  1. 通过构造器创建Bean实例
  2. 为Bean的属性设置值或引用其他Bean(调用set)
  3. 调用Bean初始化方法
  4. Bean对象获取
  5. 容器关闭,调用销毁Bean的方法

演示

实体类

public class User {private String name;public User(){System.out.println("第一步:通过构造器创建对象");}public String getName() {return name;}public void setName(String name) {System.out.println("第二步,为Bean属性设置值");this.name = name;}public void init(){System.out.println("第三步:调用Bean初始化方法");}public void destroy(){System.out.println("第五步:调用Bean销毁方法");}}

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="user" class="com.wdzl.pojo.User" init-method="init" destroy-method="destroy"><property name="name" value="周星驰"></property></bean>
<!--    <bean id="myBeanLast" class="com.wdzl.pojo.MyBeanLast"></bean>--></beans>

结果

在Bean的生命周期中,如果配置了后置处理,生命周期会额外增加两步

  1. ​ 通过构造器创建Bean实例
  2. 为Bean的属性设置值或引用其他Bean(调用set)
  3. 执行后置处理
  4. 调用Bean初始化方法
  5. 执行后置处理
  6. Bean对象获取
  7. 容器关闭,调用销毁Bean的方法

演示

​ 在上述演示中再加入一个实体类

/*** 后置处理类*/
public class MyBeanLast implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("第三步:执行后置处理+postProcessBeforeInitialization");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("第五步:执行后置处理+postProcessAfterInitialization");return bean;}
}

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="user" class="com.wdzl.pojo.User" init-method="init" destroy-method="destroy"><property name="name" value="周星驰"></property></bean><bean id="myBeanLast" class="com.wdzl.pojo.MyBeanLast"></bean></beans>

结果

5.5 XML方式-自动装配

概述:

​ 根据指定的装配规则(属性名称,属性类型),Spring自动将匹配的属性经行注入

实现:

​ 借助<bean> 标签里的autowrie属性来实现自定装配,该属性有两个值

  • byName:根据属性名称注入
  • byType:根据属性类型注入

注意

  • byType:如果有多个class属性相同的bean标签,自动装配会报错

5.6 引入外部标签

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!-- 引入外部配置文件-->
<context:property-placeholder location="jdbc.properties"></context:property-placeholder><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${druid.driverClassName}"></property><property name="url" value="${druid.url}"></property><property name="username" value="${druid.username}"></property><property name="password" value="${druid.password}"></property></bean><!-- 直接方式:配置连接信息-->
<!--    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">-->
<!--        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>-->
<!--        <property name="url" value="jdbc:mysql:///test"></property>-->
<!--        <property name="username" value="root"></property>-->
<!--        <property name="password" value="13992794421"></property>-->
<!--    </bean>-->

5.7基于注解方式-创建对象

注解概述:注解是代码的特殊标记

注解格式:@注解名称(属性名=属性值,属性名2=属性值2。。。。)

注解应用:它可以简化XML的配置,注解可以用在类上,属性上,方法上。

Spring针对创建对象提供了4个注解

  • @Component:普通类使用
  • @Service:Service层使用
  • @Controller:Web层使用
  • @Repository:Dao层使用

这四个注解功能是相同的,都可以用来创建Bean实例。

1.新建Model,添加依赖

2.创建Dao层实体类,在该类上添加注解

@Repository(value = "userDao")//相当于配置文件中Bean id属性
public class UserDao {public void addUser(){System.out.println("UserDao:addUser....");}
}

3.在配置文件中开启注解扫描

测试

5.8基于注解方式-属性注入

常用注解:

​ 1.@AutoWired:根据属性类型进行自动重装载

​ 2.@Qualifier :根据属性名进行注入

​ 3.@Resource:根据类型注入,也可以根据名称注入

​ 4.@Value:基本数据类型的注入

演示:

@AutoWired

@Qualifier

  • 要与@AutoWired同时使用
  • 同时使用的目的是为了解决根据属性类型无法自动

@Resource

@Value

6.AOP

概述:

​ 面向切面编程-在不改变源码的情况下,对现有程序功能进行维护。

6.1AOP底层原理

概述:底层实用了动态代理技术

分类:两种情况的动态代理

  • 有接口的情况:使用了JDK的动态代理

    • 代理对象与被代理对象实现相同的接口
  • 没有接口的情况,使用了CGLIB动态代理
    • 通过创建子类对象,在子类中重写方法,并通过super.方法名()调用被代理类中的方法

6.2AOP相关术语

  • 连接点(JoinPoint):类里面那些方法可以被增强,这些方法就叫做连接点
  • 切入点(PoinCut):类中实际被增强的方法,称为切入点
  • 通知/增强(Advice):被增强的方法中增强部分的代码称为通知或者增强
    • 前置增强:在调用被增强方法前执行
    • 后置增强:在调用被增强方法后执行
    • 环绕增强:在调用被增强方法前后都执行
    • 异常增强:在调用被增强方法出现异常时增强
    • 最终增强:在调用被增强方法后,无论是否出现异常,都会被执行
  • 切面(Aspect):切面本身是一个动作,将增强应用到切入点的过程
  • 代理(Proxy)
  • 目标对象(Target)
  • 织入(Weaving)

6.3AspectJ

概述:

​ AspectJ时一个独立的AOP框架,一般开发中将AspectJ 与Spring框架-起使用,进行AOP操作

实现AOP的两种方式:

​ 1.基于XML方式实现

2.基于注解方式实现

相关依赖:

<dependencies>
<!--    Spring依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>5.2.7.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>5.2.7.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.7.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>5.2.7.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.2.7.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.2.7.RELEASE</version></dependency>
<!-- 日志依赖--><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.1.1</version></dependency>
<!-- 测试依赖--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!-- aspectJ依赖--><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.6</version></dependency><dependency><groupId>aopalliance</groupId><artifactId>aopalliance</artifactId><version>1.0</version></dependency><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version></dependency>
</dependencies>

切入点表达式

概述:让Spring框架知道哪个类里面的那个方法需要增强

语法结构:

  • execution([权限修饰符] [返回值类型] [全限定类名] .[方法名]([参数列表]))

    • 权限修饰符 可以省略
    • 返回值*代表任意返回值类型
  • 举例

    • 对com.wdzl.dao.UserDao类中的addUser方法进行增强

    execution(* com.wdzl.dao.UserDao.addUser(…))

6.4AOP的实现方式一

使用原生Spring API接口

1.Service层的接口与实现类

public interface UserService {public void add();public void delete();public void update();public void select();
}
public class UserServiceImpl implements UserService {@Overridepublic void add() {System.out.println("增加了一个用户");}@Overridepublic void delete() {System.out.println("删除了一个用户");}@Overridepublic void update() {System.out.println("修改了一个用户");}@Overridepublic void select() {System.out.println("查询了一个用户");}
}

2.创建日志增强类

public class log implements MethodBeforeAdvice {//method:要执行的目标对象的方法//args: 参数//target:目标对象@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了");}
}
public class AfterLog implements AfterReturningAdvice {//returnValue:返回值@Overridepublic void afterReturning(Object returnValue, Method method, Object[] objects, Object o1) throws Throwable {System.out.println("执行了"+method.getName()+"方法,返回了:"+returnValue);}
}

3.创建配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd">
<!--    注册bean--><bean id="userService" class="com.wdzl.service.impl.UserServiceImpl"></bean><bean id="log" class="com.wdzl.log.log"></bean><bean id="afterLog" class="com.wdzl.log.AfterLog"></bean><!--    方式一:使用原生Spring API接口-->
<!--    配置aop:需要导入aop的约束-->
<!--    配置aop:需要导入aop的约束--><aop:config><!--切入点:expression; 表达式:([权限修饰符] [返回值类型] [全限定类名] .[方法名]([参数列表]))--><aop:pointcut id="pointcut" expression="execution(* com.wdzl.service.impl.UserServiceImpl.*(..))"/><!--执行环绕--><aop:advisor advice-ref="log" pointcut-ref="pointcut"></aop:advisor><aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"></aop:advisor></aop:config></beans>

4.测试

6.5AOP的实现方式二

方式二:自定义类

1.Service层的接口与实现类

public interface UserService {public void add();public void delete();public void update();public void select();
}
public class UserServiceImpl implements UserService {@Overridepublic void add() {System.out.println("增加了一个用户");}@Overridepublic void delete() {System.out.println("删除了一个用户");}@Overridepublic void update() {System.out.println("修改了一个用户");}@Overridepublic void select() {System.out.println("查询了一个用户");}
}

2.自定义类

public class DiyPointCut {public void Before(){System.out.println("==========执行前=====");}public void After(){System.out.println("==========执行后=====");}
}

3.配置配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd">
<!--    注册bean--><bean id="userService" class="com.wdzl.service.impl.UserServiceImpl"></bean><!--   方式二:自定义类--><bean id="diy" class="com.wdzl.diy.DiyPointCut"></bean><aop:config>
<!--        自定义切面, ref 要引用的类--><aop:aspect ref="diy"><!-- 切入点--><aop:pointcut id="point" expression="execution(* com.wdzl.service.impl.UserServiceImpl.*(..))"/><!-- 通知--><aop:before method="Before" pointcut-ref="point"></aop:before><aop:after method="After" pointcut-ref="point"></aop:after></aop:aspect></aop:config>
</beans>

4.测试

6.6注解方式实现AOP

1.创建dao层接口及实现类

public interface UserDao {void addUser();
}
@Repository
public class UserDaoImpl implements UserDao {@Overridepublic void addUser() {System.out.println("天不生我李志刚");}
}

2.创建增强类

@Component
@Aspect//将该类生产代理对象,这个类是一个切面
public class UserDaoProxy {/*** 前置增强*/@Before(value = "execution(* com.wdzl.dao.Impl.UserDaoImpl.addUser(..))")public void before(){System.out.println("before:前置增强.....");}/*** 最终增强*/@After(value = "execution(* com.wdzl.dao.Impl.UserDaoImpl.addUser(..))")public void after(){System.out.println("after:最终增强...");}/*** 后置增强*/@AfterReturning(value ="execution(* com.wdzl.dao.Impl.UserDaoImpl.addUser(..))")public void afterReturning(){System.out.println("AfterReturning:后置增强...");}/*** 异常增强*/@AfterThrowing(value ="execution(* com.wdzl.dao.Impl.UserDaoImpl.addUser(..))")public void afterThrowing(){System.out.println("AfterThrowing:异常增强...");}/*** 环绕增强* 我们可以给定一个参数,代表我们要获取处理切入的点*/@Around(value = "execution(* com.wdzl.dao.Impl.UserDaoImpl.addUser(..))")public void around(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("环绕之前...");joinPoint.proceed();//执行方法System.out.println("环绕之后...");}
}

3.创建配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop ="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"
>
<!-- 开启组件扫描--><context:component-scan base-package="com.wdzl"></context:component-scan><!--生成Aspect生成代理对象  JDK(默认  proxy-target-class="false")  cglib(proxy-target-class="true")--><aop:aspectj-autoproxy></aop:aspectj-autoproxy></beans>

4.测试

7.JDBCTemplate

概述:

​ Spring对JDBC的封装,使用它可以方便的去操作数据库

依赖:

查询:

​ 1.一个值

​ 2.一个对象

​ 3.一个集合

1.实体类

2.dao层及其实现类

/*** 学生持久层*/
public interface StudentDao {/*** 添加学生*/public void addStudent(Student student);/*** 修改*/void  updateStudent(Student student);/*** 删除*/void delStudent(int i);/*** 查询学生列表* @return*/List<Student> findAll();/*** 查询学生总人数*/int findStudentTotal();Student findStudentById(int id);
}
/*** 学生持久层接口实现类*/
@Repository
public class StudentDaoImpl implements StudentDao {//注入JDBCTemplate@Autowiredprivate JdbcTemplate jdbcTemplate;@Overridepublic void addStudent(Student student) {String sql = "insert into student (id,username,gender,birthday,address) values (?,?,?,?,?)";int update = jdbcTemplate.update(sql, student.getId(), student.getUsername(), student.getGender(), student.getBirthday(), student.getAddress());System.out.println(update);}@Overridepublic void updateStudent(Student student) {String sql = "update student set username = ? where id = ?";int update = jdbcTemplate.update(sql, student.getUsername(), student.getId());System.out.println(update);}@Overridepublic void delStudent(int i) {String sql = "delete from student where id = ?";Student student = new Student();student.setId(i);int update = jdbcTemplate.update(sql, i);System.out.println(update);}@Overridepublic List<Student> findAll() {String sql = "select * from student";List<Student> lists = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Student.class));return lists;}@Overridepublic int findStudentTotal() {String sql = "select count(id) from student";Integer total = jdbcTemplate.queryForObject(sql, Integer.class);return total;}/*** queryForObject()三个参数:* sql:sql语句* RowMapper接口:完成属性和字段映射的功能,常用实现类:BeanPropertyRowMapper* 第三个:可变参数* @param id* @return*/@Overridepublic Student findStudentById(int id) {String sql = "select * from student where id = ?";Student student = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(Student.class),id);return student;}
}

3.service层及其实现类

/*** 学生业务层接口*/
public interface StudentService {public void addStudent(Student student);void updateStudent(Student student);void delStudent(int i);int findStudentTotal();Student findStudentById(int id);List<Student> findAll();}
@Service
public class StudentServiceImpl implements StudentService {//注入StudentDao@Autowiredprivate StudentDao studentDao;@Overridepublic void addStudent(Student student) {studentDao.addStudent(student);}@Overridepublic void updateStudent(Student student) {studentDao.updateStudent(student);}@Overridepublic void delStudent(int i) {studentDao.delStudent(i);}@Overridepublic int findStudentTotal() {return studentDao.findStudentTotal();}@Overridepublic Student findStudentById(int id) {return studentDao.findStudentById(id);}@Overridepublic List<Student> findAll() {return studentDao.findAll();}
}

4.编写配置类

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop ="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"
>
<!--    开启组件扫描--><context:component-scan base-package="com.wdzl"></context:component-scan>
<!--数据源--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"><property name="driverClassName" value="com.mysql.jdbc.Driver"></property><property name="url" value="jdbc:mysql:///mybatis?useUnicode=true&amp;characterEncoding=utf-8"></property><property name="username" value="root"></property><property name="password" value="13992794421"></property></bean><!--jdbcTempLate    --><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property></bean></beans>

4.测试

public class MyTest {@Testpublic void test(){//1.读取配置文件ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");//2.创建服务层接口对象StudentService studentServiceImpl = context.getBean("studentServiceImpl", StudentService.class);Student student = new Student(0,"常山赵子龙","2000-02-08","男","长沙");studentServiceImpl.addStudent(student);}@Testpublic void test2(){//1.读取配置文件ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");//2.创建服务层接口对象StudentService studentServiceImpl = context.getBean("studentServiceImpl", StudentService.class);Student student = new Student(4,"王必武","2000-02-08","男","长沙");studentServiceImpl.updateStudent(student);}@Testpublic void Test(){//1.读取配置文件ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");//2.创建服务层接口对象StudentService studentServiceImpl = context.getBean("studentServiceImpl", StudentService.class);studentServiceImpl.delStudent(2);}@Testpublic void Test2(){//1.读取配置文件ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");//2.创建服务层接口对象StudentService studentServiceImpl = context.getBean("studentServiceImpl", StudentService.class);int total = studentServiceImpl.findStudentTotal();System.out.println(total);}@Testpublic void Test3(){//1.读取配置文件ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");//2.创建服务层接口对象StudentService studentServiceImpl = context.getBean("studentServiceImpl", StudentService.class);Student studentById = studentServiceImpl.findStudentById(3);System.out.println(studentById);}@Testpublic void findAllTest4(){//1.读取配置文件ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");//2.创建服务层接口对象StudentService studentServiceImpl = context.getBean("studentServiceImpl", StudentService.class);List<Student> list = studentServiceImpl.findAll();for (Student student : list){System.out.println(student);}}
}

批量添加:

    /*** 批量增加*/void batchAdd(List<Object[]> students);@Overridepublic void batchAdd(List<Object[]> students) {String sql = "insert into student (username,birthday,gender,address) values (?,?,?,?)";/*** 批量添加* 参数一:sql语句* 参数二:*/int[] ints = jdbcTemplate.batchUpdate(sql, students);System.out.println(Arrays.toString(ints));}void batchAdd(List<Object[]> students);@Overridepublic void batchAdd(List<Object[]> students) {studentDao.batchAdd(students);}
    public void Test5(){//1.读取配置文件ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");//2.创建服务层接口对象StudentService studentServiceImpl = context.getBean("studentServiceImpl", StudentService.class);List<Object[]> args = new ArrayList<>();Object[] o1 = {"唐康","2020-2-2","男","安康"};Object[] o2 = {"赵玉斌","2020-2-2","男","安康"};Object[] o3 = {"马超","2020-2-2","男","安康"};Object[] o4 = {"关羽","2020-2-2","男","安康"};args.add(o1);args.add(o2);args.add(o3);args.add(o4);studentServiceImpl.batchAdd(args);}

批量修改:

    /*** 批量修改*/void batchUpdate(List<Object[]> lists);@Overridepublic void batchUpdate(List<Object[]> lists) {String sql = "update student set username = ? where address = ?";int[] ints = jdbcTemplate.batchUpdate(sql, lists);System.out.println(Arrays.toString(ints));}void batchUpdate(List<Object[]> lists);@Overridepublic void batchUpdate(List<Object[]> lists) {studentDao.batchUpdate(lists);}
  @Testpublic void Test6(){//1.读取配置文件ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");//2.创建服务层接口对象StudentService studentServiceImpl = context.getBean("studentServiceImpl", StudentService.class);List<Object[]> args = new ArrayList<>();Object[] o1 = {"你好","安康"};Object[] o2 = {"世界","安康"};Object[] o3 = {"中国","安康"};Object[] o4 = {"万岁","安康"};args.add(o1);args.add(o2);args.add(o3);args.add(o4);studentServiceImpl.batchUpdate(args);}

8.整合MyBatis

8.1 方式一

步骤:

1.导入相关jar包

  • junit
  • mybatis
  • mysql数据库
  • spring相关的
  • aop织入
  • mybatis-spring【new】
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.wdzl</groupId><artifactId>04_spring_mybatis</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.1.9.RELEASE</version></dependency><!--        Spring操作数据库的话,还需要一个spring-jdbc--><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.2.7.RELEASE</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.6</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.4</version></dependency></dependencies></project>

2.dao层及实现类

public interface UserDao {List<Account> findAll();
}
public class UserDaoImpl implements UserDao {我们的所有操作,都使sqlSession来执行,在原来,现在都使用SqlSessionTemplate;private SqlSessionTemplate sqlSession;public SqlSessionTemplate getSqlSession() {return sqlSession;}public void setSqlSession(SqlSessionTemplate sqlSession) {this.sqlSession = sqlSession;}@Overridepublic List<Account> findAll() {UserDao userDao = sqlSession.getMapper(UserDao.class);return userDao.findAll();}
}

3.编写配置文件

​ 1.编写数据源配置

​ 2.sqlSessionFactory

3. sqlSessionTemplate

4.将自己写的实现类,注入到Spring中

Beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
"><!--    DataSources:使用Spring的数据源替换MyBatis的配置 c3p0 dbcp druid我们使用Spring提供的JDBC
--><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"></property><property name="url" value="jdbc:mysql:///test"></property><property name="username" value="root"></property><property name="password" value="13992794421"></property></bean><!--    SqlSessionFactory--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/>
<!--        绑定MyBatis配置文件 --><property name="configLocation" value="classpath:SqlMapConfig.xml"></property><property name="mapperLocations" value="classpath:com/wdzl/dao/UserDao.xml"></property></bean><!-- SqlSessionTemplate:这就是我们使用的sqlSession--><bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"><!-- 只能使用构造器注入SqlSessionFactory,因为它没有set方法--><constructor-arg index="0" ref="sqlSessionFactory"></constructor-arg></bean><bean id="userDaoImpl" class="com.wdzl.dao.impl.UserDaoImpl"><property name="sqlSession" ref="sqlSession"></property></bean></beans>

SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 设置-->
<!--    <settings>-->
<!--        <setting name="" value=""/>-->
<!--    </settings>--><!-- 别名-->
<!--    <typeAliases>-->
<!--        <package name="com.wdzl"/>-->
<!--    </typeAliases>--></configuration

UserDao.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wdzl.dao.UserDao"><!-- 对应dao层的全限定类名--><select id="findAll" resultType="com.wdzl.pojo.Account">select*from account;</select>
</mapper>

4.测试

8.2方式二

1.dao层及其实现类

public class UserDaoImpl2 extends SqlSessionDaoSupport implements UserDao {@Overridepublic List<Account> findAll() {return getSqlSession().getMapper(UserDao.class).findAll();}
}

2.编写配置文件

Beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
"><!--    DataSources:使用Spring的数据源替换MyBatis的配置 c3p0 dbcp druid我们使用Spring提供的JDBC
--><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"></property><property name="url" value="jdbc:mysql:///test"></property><property name="username" value="root"></property><property name="password" value="13992794421"></property></bean><!--    SqlSessionFactory--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/>
<!--        绑定MyBatis配置文件 --><property name="configLocation" value="classpath:SqlMapConfig.xml"></property><property name="mapperLocations" value="classpath:com/wdzl/dao/UserDao.xml"></property></bean><bean id="userDaoImpl" class="com.wdzl.dao.impl.UserDaoImpl"><property name="sqlSession" ref="sqlSession"></property></bean></beans>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
"><import resource="classpath:Beans.xml"></import><bean id="userDaoImpl2" class="com.wdzl.dao.impl.UserDaoImpl2"><property name="sqlSessionFactory" ref="sqlSessionFactory"></property></bean></beans>

3.测试

8.事务

  • 把一组业务当成一个业务来做;要么都成功,要么都失败
  • 事务在项目开发中,十分重要,涉及到数据的一致性问题,不能马虎
  • 确保完整性和一致性

事务ACID原则:

  • 原子性
  • 一致性
  • 隔离性
    • 多个业务可能操作同一个资源,防止数据损坏
  • 持久性
    • 事务一旦提交,无论系统发生什么问题,结果都不会被影响,被持久化的写到储存器中

8.1Spring中的事务管理

  • 声明式事务:AOP
  • 编程式事务:需要在代码中,进行事务的管理

8.2 事务的环境搭建

1.新建一个Module,添加相关依赖

2.编写配置文件

  • 配置数据源
  • 配置jdbcTemplate
  • 开启组件扫描

3.编写dao层接口,Service层接口,及相应的实现类

4.测试

8.3事务操作

1.事务应该添加到三层架构中的service层

  • 因为Service负责组装业务

2.在Spring中进行事务管理

  • 编程是事务
  • 声明式事务

3.声明式事务管理

  • 基于注解方式
  • 基于XML方式

4.在Spring中进行声明式事务管理,实用了AOP原理

5.Spring针对不同的框架使用了不同的API

  • Jdbc,MyBatis: DataSourceTransactionManager
  • Hibernate: HibernateTransactionManager

8.3基于XML方式的事务管理

1.编写dao层接口,Service层接口,及相应的实现类

dao层接口

public interface UserDao {List<Account> findAll();///添加一个用户int addUser(Account account);//删除一个用户int deleteUser(int id);
}

实现类

public class UserDaoImpl2 extends SqlSessionDaoSupport implements UserDao {@Overridepublic List<Account> findAll() {SqlSession sqlSession = getSqlSession();UserDao userDao = sqlSession.getMapper(UserDao.class);return userDao.findAll();}@Overridepublic int addUser(Account account) {return getSqlSession().getMapper(UserDao.class).addUser(account);}@Overridepublic int deleteUser(int id) {return getSqlSession().getMapper(UserDao.class).deleteUser(id);}
}

service层接口

public interface UserService {List<Account> findAll();///添加一个用户int addUser(Account account);//删除一个用户int deleteUser(int id);
}

实现类

public class UserServiceImpl extends SqlSessionDaoSupport implements UserService {private UserDao userDao;public void setUserDao(UserDao userDao){this.userDao = userDao;}@Overridepublic List<Account> findAll() {Account account = new Account(0, "yy", 666);userDao.addUser(account);userDao.deleteUser(9);return userDao.findAll();}@Overridepublic int addUser(Account account) {return userDao.addUser(account);}@Overridepublic int deleteUser(int id) {return userDao.deleteUser(id);}
}

编写配置文件

UserDao.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wdzl.dao.UserDao"><!-- 对应dao层的全限定类名--><select id="findAll" resultType="com.wdzl.pojo.Account">select*from account;</select><insert id="addUser" parameterType="com.wdzl.pojo.Account">insert into account (id,name,money) values (#{id},#{name},#{money})</insert><delete id="deleteUser" parameterType="int">delete from account where id = #{id}</delete>
</mapper>

Beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!--    DataSources:使用Spring的数据源替换MyBatis的配置 c3p0 dbcp druid我们使用Spring提供的JDBC
--><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"></property><property name="url" value="jdbc:mysql:///test"></property><property name="username" value="root"></property><property name="password" value="13992794421"></property></bean><!--    SqlSessionFactory--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/>
<!--        绑定MyBatis配置文件 --><property name="configLocation" value="classpath:SqlMapConfig.xml"></property><property name="mapperLocations" value="classpath:com/wdzl/dao/UserDao.xml"></property></bean><!-- SqlSessionTemplate:这就是我们使用的sqlSession--><bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"><!-- 只能使用构造器注入SqlSessionFactory,因为它没有set方法--><constructor-arg index="0" ref="sqlSessionFactory"></constructor-arg></bean><!--  配置声明式事务--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><constructor-arg ref="dataSource"></constructor-arg></bean><!--    结合AOP实现事务的织入-->
<!--    配置事务通知--><tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--        给那些方法配置事务-->
<!--        配置事务的转播特性:--><tx:attributes><tx:method name="add" propagation="REQUIRED"/><tx:method name="delete" propagation="REQUIRED"/><tx:method name="update" propagation="REQUIRED"/></tx:attributes></tx:advice><!--    配置事务切入--><aop:config><aop:pointcut id="txPoint" expression="execution(* com.wdzl.dao.*.*(..))"/><aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"></aop:advisor></aop:config></beans>

SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 设置-->
<!--    <settings>-->
<!--        <setting name="" value=""/>-->
<!--    </settings>--><!-- 别名-->
<!--    <typeAliases>-->
<!--        <package name="com.wdzl"/>-->
<!--    </typeAliases>--></configuration>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
"><import resource="classpath:Beans.xml"></import><bean id="userDaoImpl" class="com.wdzl.dao.impl.UserDaoImpl"><property name="sqlSession" ref="sqlSession"></property></bean><bean id="userDaoImpl2" class="com.wdzl.dao.impl.UserDaoImpl2"><property name="sqlSessionFactory" ref="sqlSessionFactory"></property></bean><bean id="userServiceImpl" class="com.wdzl.service.impl.UserServiceImpl"><property name="sqlSessionFactory" ref="sqlSessionFactory"></property><property name="userDao" ref="userDaoImpl2"></property></bean></beans>

测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8aipIwyj-1617199855710)(D:\图片\Aop.png)]

8.4基于注解方式的事务管理

- propagation :事务传播行为
- isolation: 事务隔离级别
- timeout:超时时间
- readOnly:是否只读
- rollbackFor:回滚
- noRollbackFor:不回滚

1.创建实体类

/*** 账户类*/
public class Account {private int id;private String name;private double money;@Overridepublic String toString() {return "Account{" +"id=" + id +", name='" + name + '\'' +", money='" + money + '\'' +'}';}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getMoney() {return money;}public void setMoney(double money) {this.money = money;}
}

2.数据库连接配置类

/*** 数据库连接配置类*/public class JdbcConfig {@Bean//将DataSource注入Spring容器中public DataSource getDataSource(){DriverManagerDataSource dataSource = new DriverManagerDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql:///test?useUnicode=true&characterEncoding=utf-8");dataSource.setUsername("root");dataSource.setPassword("13992794421");return dataSource;}@Bean//将SqlSessionFactory注入到Spring容器中public SqlSessionFactoryBean create(DataSource dataSource){SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();sqlSessionFactory.setDataSource(dataSource);Resource resource = new ClassPathResource("SqlMapConfig.xml");sqlSessionFactory.setConfigLocation(resource);return sqlSessionFactory;}
}

3.配置类

@Configuration//配置类
@ComponentScan(basePackages = "com.wdzl")//组件扫描
@Import(value = {JdbcConfig.class,TransactionConfig.class})//引入其他配置类
@EnableTransactionManagement//开启事务
public class SpringConfig {}

4.事务管理类

/*** 事务管理类*/
public class TransactionConfig {//将我们的事务管理对象注入容器@Beanpublic PlatformTransactionManager createTransactionManager(DataSource dataSource){return new DataSourceTransactionManager(dataSource);}
}

5.dao层及其实现类

public interface AccountDao {/*** 根据用户名查询账户信息* @param name* @return*/@Select("select*from account where name = #{name}")Account findAccountByName(String name);/*** 更新账户信息* @param account*/@Update("update account set name = #{name},money=#{money} where id = #{id}")void updateAccount(Account account);
}
@Repository
public class AccountDaoImpl implements AccountDao {//注入sqlSession工厂@Autowiredprivate SqlSessionFactory sqlSessionFactory;@Overridepublic Account findAccountByName(String name) {SqlSession sqlSession = sqlSessionFactory.openSession();AccountDao accountDao = sqlSession.getMapper(AccountDao.class);return accountDao.findAccountByName(name);}@Overridepublic void updateAccount(Account account) {SqlSession sqlSession = sqlSessionFactory.openSession();AccountDao accountDao = sqlSession.getMapper(AccountDao.class);accountDao.updateAccount(account);}
}

6.service层及其实现类

/*** 账户业务逻辑层接口*/
public interface AccountService {/*** 转账业务* @param sourceName 转出账户姓名* @param targetName 转入账户姓名* @param money 转动金钱*/void transfer(String sourceName,String targetName,double money);
}
@Service
@Transactional//开启事务
public class AccountServiceImpl implements AccountService {//注入数据访问层@Autowiredprivate AccountDao accountDao;@Overridepublic void transfer(String sourceName, String targetName, double money) {//查询转出账户对象Account source = accountDao.findAccountByName(sourceName);//查询注入账户是否存在Account target = accountDao.findAccountByName(targetName);//判断账户是否存在if (source != null && target != null ){//设置转入转出金额source.setMoney(source.getMoney() - money);target.setMoney(target.getMoney() + money);//更新账户信息accountDao.updateAccount(source);
//            System.out.println(3/0);accountDao.updateAccount(target);}}
}

7.账户控制层

/*** 账户控制层*/
@Controller
public class AccountController {@Autowiredprivate AccountService accountService;public void transfer(String sourceName,String targetName,double money){try {accountService.transfer(sourceName,targetName,money);System.out.println("转账成功");} catch (Exception e) {System.out.println("转账失败");}}
}

8.编写配置类

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><mappers><mapper class="com.wdzl.dao.AccountDao"></mapper></mappers>
</configuration>

9.测试

public class MyTest {@Testpublic void Test(){ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);AccountController accountController = context.getBean("accountController", AccountController.class);accountController.transfer("李明","张三",500);}
}

Spring框架的详细学习相关推荐

  1. 如何搭建一个Spring框架超详细

    如何搭建一个Spring框架,首先我们要先了解Spring的核心构成部分 1.Spring 的构成 IOC 控制反转 spring 框架最核心的部分 DAO spring 对 访问数据库的支持 MVC ...

  2. spring框架文档学习(包会)

    文章目录 spring简介 IOC控制反转 ioc概念 ioc使用 (1)导入依赖 (2)编写实体类 (3)编写配置文件 (3)创建容器从容器中获取对象并测试 ioc三种创建对象方式 (1)下标赋值 ...

  3. Spring框架零基础学习(一):IOC|DI、AOP

    文章目录 一.IDEA创建Spring项目 二.Spring: IOC和DI 三.Spring: AOP 参考链接: HOW2J.CN:Spring idea创建一个spring项目 一.IDEA创建 ...

  4. Spring框架【超详细学习笔记】

    文章目录 一.Spring学习目标 1.1 为什么要学习Spring框架? 1.2 主要学什么? 1.3 怎么学? 二.初识Spring 2.1Spring家族 2.2 Spring发展史 2.3 S ...

  5. 【Spring】(1)Spring概述:什么是Spring框架?为什么要用Spring框架?

    两个月前跟着b站动力节点王鹤老师的Spring框架教程视频学习完了Spring框架,在学习过程中我将视频中涉及的代码都一行一行手敲了一遍,并且把Spring入门相关的资料整理了一下,在这里记录一下我在 ...

  6. Spring框架学习笔记,超详细!!(4)

    Java小白开始学习Spring框架,一方面,跟着视频学习,并记录下学习笔记,方便以后复习回顾.另一方面,发布学习笔记来约束自己,学习路程还很遥远,继续加油坚持!!!希望能帮助到大家! 另外还有我的牛 ...

  7. spring框架mvc框架_5篇Spring框架书籍,通过MVC学习Spring

    spring框架mvc框架 Spring Framework is one of the most widely used Java EE Frameworks. It's an open sourc ...

  8. spring 框架学习(一)

    1.spring简介 Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成 ...

  9. spring学习12 -Spring 框架模块以及面试常见问题注解等

    以下为spring常见面试问题: 1.Spring 框架中都用到了哪些设计模式? Spring框架中使用到了大量的设计模式,下面列举了比较有代表性的: 代理模式-在AOP和remoting中被用的比较 ...

  10. Spring框架学习day_01: 框架配置方式/ 管理对象的作用域/ 生命周期/ 组件扫描/ 单例模式:“懒汉式“,“饿汉式“

    1. Spring框架的作用 Spring框架的主要作用是创建对象和管理对象. 创建对象:类似于User user = new User(); 管理对象:随时可以通过Spring框架获取对象,甚至Sp ...

最新文章

  1. XML与DataSet的相互转换类
  2. php获取svn文件,然后ftp上传服务器代码
  3. JQuery Basic Features Quick Walkthrough
  4. WxMac BadgeLabels
  5. 关于停断电后电脑自动开机重启的问题
  6. 2011股市大方向随想
  7. 云OS:Linux在桌面打翻身仗的机会?
  8. PHP 基本语法,变量
  9. chrome浏览器功能介绍
  10. 【Elasticsearch】Elasticsearch bouncing result 问题
  11. mysql登录跳转不了_Session过期后实现自动跳转登录页面
  12. 用CMarkup类创建xml文件的方法
  13. Dune Analytics 发布 v2 版本,新增自动实时查询刷新
  14. VC ODBC使用总结
  15. Cisco PIX 简单配置-4
  16. 打开计算机文件反应慢怎么解决方法,电脑反应慢怎么解决
  17. mysql常用语句梳理
  18. android字体颜色渐变色,实现TextView文本颜色渐变的骚操作
  19. 使用cmd命令清空windows中C盘的所有临时文件
  20. android 怎么看架构,怎么查看手机设备架构

热门文章

  1. 五款免费pdf转换成word转换器软件下载
  2. 备份VMWare ESXi虚拟机
  3. Oracle统一访问代理层方案
  4. API LayoutInflater
  5. 图像识别(五)| 春天花开却不识?打开百度识图,残差和卷积带你识遍路边野花
  6. Debug显示不支持opengl4,是双显卡未设置独立显卡模式
  7. oracle使用max提升效率,小小小的问题------关于count(*) 和 max(rownum) 效率问题
  8. win10任务栏全透明
  9. java 命令行工具_分享java自带命令行工具jmap、jhat与jinfo的方法详解
  10. SwiftUI HealthKit 基础教程