Spring

1. Spring

1.1 简介

  • spring理念,使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架

官网:Spring Framework Overview

GitHub:GitHub - spring-projects/spring-framework: Spring Framework

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>5.3.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-jdbc</artifactId>
   <version>5.3.8</version>
</dependency>

1.2 优点

  • Spring是一个开源的免费的容器

  • Spring是一个轻量级的,非入侵式的框架!

  • 控制反转(IOC),面向切面编程(AOP)

  • 支持事务的处理,对框架整合的支持

总结:Spring就是一个轻量级的控制反转(IOC)和切面编程的框架!

 

2.IOC理论推导

百度

3 HelloSpring

bean.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/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd">

   <!--使用spring来创建对象,在Spring中,这些都成为bean

       类型 变量名 = new 类型();
       Hello hello = new Hello();

       id = 变量名
       class = new 的对象;
       property 相当于给对象中的属性设置一个值!
   -->
   <bean id="hello" class="com.sr.pojo.Hello">
       <property name="str" value="Spring"/>
       <!--
           ref:是引用Spring容器创建好的对象(其他bean的id值
           value:具体的值,基本数据类型!
       -->
   </bean>
</beans>

测试文件

public class MyTest {
   public static void main(String[] args) {
       //获取获取ApplicationContext:拿到Spring的容器
       ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
       //我们的对象都在Spring中的管理了,我们要使用,直接去里面取出来就可以!
       //需要什么,就直接get什么
       Hello hello = (Hello) context.getBean("hello");
       System.out.println(hello.toString());
  }
}

4. IOC创建对象的方式

  1. 使用无参构造创建对象,默认!

  2. 假设我们要使用有参构造创建对象。

    1. 下标赋值

      <bean id="user" class="com.sr.pojo.User">
         <constructor-arg index="0" value="下标赋值"/>
      </bean>
    2. 类型(不推荐)

    3. 第三种,直接通过参数名设置

      <bean id="user" class="com.sr.pojo.User">
         <constructor-arg name="name" value="sr"/>
      </bean>

       

总结:在配置文件加载的时候,容器中管理的对象就已经初始化了!

 

5.Spring配置

5.1 别名

<!--如果添加了别名,我们也可以使用别名获取到这个对象-->
<alias name="user" alias="user2"/>

5.2 Bean的配置

<!--
   id:bean的唯一标识符,也就是相当于我们的对象名
   class:bean 对象所对应的全限定名:包名+类型
   name:也是别名,而且name 可以同时取多个别名
-->
<bean id="user" class="com.sr.pojo.User" name="user2,user3">
   <property name="name" value="sr"/>
</bean>

5.3 import

这个import,一般用于团队开发使用,它可以将多个配置文件,导入合并为一个

假设:项目中有多个人开发,可以创建多个bean.xml 文件,最后导入到applicationContext.xml中,合并为一个

<import resource="beans.xml"/>

使用的时候,直接使用总的配置就可以了

 

6.依赖注入

6.1 构造器注入

6.2 Set方式注入(重点)

  • 依赖注入: Set注入!

    • 依赖:bean对象的创建依赖于容器

    • 注入:bean对象中的所有属性,由容器来注入!

 

【环境搭建】

  1. 复杂类型

    实体类

    public class Address {
    private String address;

    public String getAddress() {
    return address;
    }

    public void setAddress(String address) {
    this.address = address;
    }
    }
  2. 真实测试对象

    public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List<String> hobbys;
    private Map<String,String> card;
    private Set<String> game;
    private String wife;
    private Properties info;

    @Override
    public String toString() {
    return "Student{" +
    "name='" + name + '\'' +
    ", address=" + address +
    ", books=" + Arrays.toString(books) +
    ", hobbys=" + hobbys +
    ", card=" + card +
    ", game=" + game +
    ", wife='" + wife + '\'' +
    ", info=" + info +
    '}';
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public Address getAddress() {
    return address;
    }

    public void setAddress(Address address) {
    this.address = address;
    }

    public String[] getBooks() {
    return books;
    }

    public void setBooks(String[] books) {
    this.books = books;
    }

    public List<String> getHobbys() {
    return hobbys;
    }

    public void setHobbys(List<String> hobbys) {
    this.hobbys = hobbys;
    }

    public Map<String, String> getCard() {
    return card;
    }

    public void setCard(Map<String, String> card) {
    this.card = card;
    }

    public Set<String> getGame() {
    return game;
    }

    public void setGame(Set<String> game) {
    this.game = game;
    }

    public String getWife() {
    return wife;
    }

    public void setWife(String wife) {
    this.wife = wife;
    }

    public Properties getInfo() {
    return info;
    }

    public void setInfo(Properties info) {
    this.info = info;
    }
    }
  3. bean.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/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="student" class="com.sr.pojo.Student">
    <!--第一种,普通值注入,value-->
    <property name="name" value="宋瑞"/>
    </bean>
    </beans>
  4. 测试类

    public class MyTest {

    public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
    Student student = (Student) context.getBean("student");
    System.out.println(student.getName());
    }
    }

注入方式

<bean id="address" class="com.sr.pojo.Address"/>
<bean id="student" class="com.sr.pojo.Student">
<!--普通值注入:value-->
<property name="name" value="宋瑞"/>
<!--Bean注入:使用ref注入-->
<property name="address" ref="address"/>
<!--数组注入:-->
<property name="books">
<array>
<value>红楼梦</value>
<value>西游记</value>
<value>水浒传</value>
<value>三国演义</value>
</array>
</property>
<!--List-->
<property name="hobbys">
<list>
<value>听歌</value>
<value>敲代码</value>
<value>看电影</value>
</list>
</property>
<!--map-->
<property name="card">
<map>
<entry key="身份证" value="123456" />
<entry key="银行卡" value="123456" />
</map>
</property>
<!--set-->
<property name="game">
<set>
<value>LOL</value>
<value>CS</value>
</set>
</property>
<!--null-->
<property name="wife">
<null/>
</property>
<!--Properties-->
<property name="info">
<props>
<prop key="学号">123456</prop>
<prop key="性别">男</prop>
</props>
</property>
</bean>

6.3 拓展方式注入

p命名空间注入,可以直接注入属性的值:property 无参

c命名空间注入,通过构造器注入:construc-args 有参

注意:p命名和c命名空间不能直接使用,需要导入xml约束

官网找

6.4 Bean的作用域

1.单例模式(Spring的默认机制)

scope="singleton"

创建的都是同一个对象;默认就是单例

<bean id="user" class="com.sr.pojo.User" scope="singleton">
<property name="name" value="sr"/>
</bean>
2.原型模式:每次从容器中get的时候,都会产生一个新对象

scope:"prototype"

3.其余的 request,session,application,这些个只能在web开发中使用到!

 

7. Bean的自动装配

  • 自动装配是Spring满足bean依赖一种方式!

  • Spring会在上下文中自动寻找,并自动给bean装配属性

 

在Spring中有三种装配的方式:

  1. 在xml中显示的配置

  2. 在java中显示的配置

  3. 隐式的自动装配bean【重要】

7.1 测试

  1. 环境搭建

    • 一个人有两个宠物

    public class Cat {
    public void shout(){
    System.out.println("喵");
    }
    }
    public class Dog {
    public void shout(){
    System.out.println("汪汪");
    }
    }
    public class People {
    private Cat cat;
    private Dog dog;
    private String name;

    @Override
    public String toString() {
    return "People{" +
    "cat=" + cat +
    ", dog=" + dog +
    ", name='" + name + '\'' +
    '}';
    }

    public Cat getCat() {
    return cat;
    }

    public void setCat(Cat cat) {
    this.cat = cat;
    }

    public Dog getDog() {
    return dog;
    }

    public void setDog(Dog dog) {
    this.dog = dog;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }
    }

    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/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="cat" class="com.sr.pojo.Cat"/>
    <bean id="dog" class="com.sr.pojo.Dog"/>
    <bean id="people" class="com.sr.pojo.People">
    <property name="name" value="宋瑞"/>
    <property name="dog" ref="dog"/>
    <property name="cat" ref="cat"/>
    </bean>
    </beans>

    test

    public class MyTest {
    @Test
    public void test1(){
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    People people = (People) context.getBean("people");
    people.getDog().shout();
    people.getCat().shout();
    }
    }
自动装配

autowire="byName"

<bean id="people" class="com.sr.pojo.People" autowire="byName">
</bean>

byName: 会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id

byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean

 

小结:

  • byName的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法后的名字一致

  • bytype的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致

 

7.2 注解实现装配

使用注解条件:

  1. 导入约束: context约束

  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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    https://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

    </beans>
@Autowired
public class People {
@Autowired
private Cat cat;
@Autowired
private Dog dog;

private String name;

直接在属性上使用即可!也可以在set方法上使用!

使用Autowired我们可以不用编写Set方法了,前提是你这个自动装配的属性在IOC(Spring)容器中存在,且符合名字byType

科普
@Nullable  字段标记了这个注解,说明这个字段可以为null
public class People {
//如果显示定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空
@Autowired(required = false)
private Cat cat;
@Autowired
private Dog dog;

private String name;

 

如果@Autowired 自动装配的环境比较复杂,自动装配无法通过一个【@Autowired】注解完成的时候,我们可以使用 @Qualifier(value="xxx") 去配合 @Autowired的使用,指定一个唯一的bean对象注入!

public class People {
@Autowired
@Qualifier(value="cat2")
private Cat cat;
@Resource注解
public class People {
@Resource(name="cat2")
private Cat cat;
@Resource
private Dog dog;

private String name;

Resource是Autowired和Qualifier结合

小结:

@Resource和@Autowired的区别:百度

 

8.使用注解开发

在Spring4之后,要使用注解开发,必须要保证aop的包导入了

<!--会自动导入aop依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.8</version>
</dependency>

使用注解需要导入context约束,增加注解的支持

<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">

<!--指定要扫描的包,这个包下的注解就会生效-->
<context:component-scan base-package="com.sr.pojo"/>
<!--开启注解支持-->
<context:annotation-config/>

</beans>
  1. bean

    @Component:组件,放在类上,说明这个类被Spring管理了,就是bean!名字默认小写

  2. 属性如何注入

    @Value

    @Component
    public class User {
    //@Value("sr")
    //相当于<property name="name" value="sr"/>
    public String name;
    @Value("sr") //也可以写道set方法上
    public void setName(String name) {
    this.name = name;
    }
    }
  3. 衍生的注解

    @Component 有几个衍生注解,我们在web开发中,会按照mvc三层架构分层

    • dao【@Repository】

    • service【@Service】

    • controller【@Controller】

    这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配Bean

  4. 作用域

    @Scope(" ") 在类上写

  5. 小结

xml与注解:

  • xml更加万能,适用于任何场合!维护简单方便

  • 注解 不是自己的类使用不了,维护相对复杂!

xml与注解最佳实践:

  • xml用来管理bean

  • 注解只负责完成属性的注入

  • 我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持

    <!--指定要扫描的包,这个包下的注解就会生效-->
<context:component-scan base-package="com.sr.pojo"/>
<!--开启注解支持-->
<context:annotation-config/>

9. 使用Java的方式配置Spring

完全不使用Spring配置,全权交给java来做!

JavaConfig是Spring的一个子项目,在Spring4之后,成为了一个核心功能

 

10. 代理模式

为什么要学习代理模式?因为这就是SpringAOP的底层!

  • 静态代理

  • 动态代理

 

11 AOP

 

 

11.3 使用Spring实现Aop

【重点】使用AOP注入,需要导入一个依赖包!

    <dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
</dependency>

 

方式一:使用Spring的API接口【主要是SpringAPI接口实现】

UserService

public interface UserService {
public void add();
public void delete();
public void update();
public void select();
}

UserServiceImpl.xml

public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("add");
}

@Override
public void delete() {
System.out.println("delete");
}

@Override
public void update() {
System.out.println("update");
}

@Override
public void select() {
System.out.println("select");
}
}

Log

public class Log implements MethodBeforeAdvice {
@Override
//method:要执行的目标对象的方法
//object:参数
//target:目标对象
public void before(Method method, Object[] objects, Object target) throws Throwable {
System.out.println(target.getClass().getName()+"的"+method.getName()+"方法被执行了");
}
}

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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">

<!--注册bean-->
<bean id="userService" class="com.sr.service.UserServiceImpl"/>
<bean id="log" class="com.sr.log.Log"/>
<bean id="afterLog" class="com.sr.log.AfterLog"/>

<!--配置AOP:导入aop的约束-->
<aop:config>
<!--切入点:expression:表达式 execution(返回值类型 类名.方法名*(..))-->
<!-- *(..) 表示任何参数-->
<aop:pointcut id="pointcut" expression="execution(* com.sr.service.UserServiceImpl.*(..))"/>
<!--执行环绕增加!-->
<!--把log这个类,切入到pointcut方法上-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>

</aop:config>
</beans>

test

public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//注意点:动态代理,代理的是接口
UserService userService = (UserService) context.getBean("userService");
userService.add();
}
}

方式二:自定义实现AOP【主要是切面】

自定义方法

public class DiyPointCut {
public void before(){
System.out.println("=======方法执行前==========");
}
public void after(){
System.out.println("=======方法执行后==========");
}
}

applicationContext.xml

<!--方式二:自定义类-->
<bean id="diy" class="com.sr.diy.DiyPointCut"/>
<aop:config>
<!--自定义切面,ref 要引用的类-->
<aop:aspect ref="diy">
<!--切入点-->
<aop:pointcut id="point" expression="execution(* com.sr.service.UserServiceImpl.*(..))"/>
<!--通知-->
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>

方式三:使用注解实现!

//方式三:使用注解方式实现AOP
@Aspect //标注这个类是一个切面
public class AnnotationPointCut {
@Before("execution(* com.sr.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("============方法执行前==============");
}
@After("execution(* com.sr.service.UserServiceImpl.*(..))")
public void after(){
System.out.println("============方法执行后==============");
}
//在环绕增强中,我们可以给定一个参数,代表我们要获取处理切入的点(不推荐)
@Around("execution(* com.sr.service.UserServiceImpl.*(..)))")
public void around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("环绕前");
//执行方法
Object proceed = jp.proceed();
System.out.println("环绕后");
}
}
<!--方式三-->
<bean id="annotationPointCut" class="com.sr.diy.AnnotationPointCut"/>
<!--开启注解支持!-->
<aop:aspectj-autoproxy/>

 

12 Mybatis

步骤:

  1. 导入相关jar包

    • junit

    • mybatis

    • mysql数据库

    • spring相关的

    • aop织入

    • mybatis-spring【new】

    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    </dependency>
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.24</version>
    </dependency>
    <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.3.0</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.8</version>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.0.2.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.7</version>
    </dependency>
    <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.2.3</version>
    </dependency>
    <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version>
    </dependency>
  2. 编写配置文件

  3. 测试

12.1 回忆mybatis

  1. 编写实体类

  2. 编写核心配置文件

  3. 编写接口

  4. 编写Mapper.xml

  5. 测试

 

12.2 Mybatis-Spring

方式一:

UserMapper

public interface UserMapper {
public List<User> selectUser();
}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sr.mapper.UserMapper">

<select id="selectUser" resultType="User">
select * from mybatis.user;
</select>

</mapper>

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--核心配置文件-->
<configuration>
<typeAliases>
<package name="com.sr.pojo"/>
</typeAliases>

<!--设置-->
</configuration>

spring-dao.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">

<!--这个文件专门配置mybatis,不需要改动-->

<!--DataSource:使用Spring的数据源替换Mybatis的配置
我们这里使用Spring提供的JDBC:org.springframework.jdbc.datasource
-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!--sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--绑定Mybatis配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/sr/mapper/UserMapper.xml"/>
</bean>
<!--SqlSessionTemplate: 就是我们使用的sqlSession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--只能使用构造器注入sqlSessionFactory ,以为他没有set方法-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">

<import resource="spring-dao.xml"/>

<bean id="userMapper" class="com.sr.mapper.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
</beans>

UserMapperImpl

public class UserMapperImpl implements UserMapper{
private SqlSessionTemplate sqlSession;

public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public List<User> selectUser() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectUser();
}
}

方式二:(简化操作)

spring-dao.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">

<!--这个文件专门配置mybatis,不需要改动-->

<!--DataSource:使用Spring的数据源替换Mybatis的配置
我们这里使用Spring提供的JDBC:org.springframework.jdbc.datasource
-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!--sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--绑定Mybatis配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/sr/mapper/UserMapper.xml"/>
</bean>
</beans>

UserMapperImpl2

public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{
@Override
public List<User> selectUser() {
return getSqlSession().getMapper(UserMapper.class).selectUser();
}
}

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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">

<import resource="spring-dao.xml"/>
<bean id="userMapper2" class="com.sr.mapper.UserMapperImpl2">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
</beans>

test

public class MyTest {
@Test
public void test() throws IOException {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper userMapper = context.getBean("userMapper2", UserMapper.class);
for (User user : userMapper.selectUser()) {
System.out.println(user);
}
}
}

13. 声明式事务

1.回顾事务

  • 要么都成功,要么都失败

  • 事务在项目开发中,十分的重要,涉及到数据的一致性问题,不能马虎!

  • 确保完成性和一致性;

 

  • 声明式事务:AOP

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

UserMapperImpl

public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{
@Override
public List<User> selectUser() {

User user = new User(5, "小王", "45564");
UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
mapper.addUser(user);
mapper.deleteUser(5);
return mapper.selectUser();

}

@Override
public int addUser(User user) {
return getSqlSession().getMapper(UserMapper.class).addUser(user);
}

@Override
public int deleteUser(int id) {
return getSqlSession().getMapper(UserMapper.class).deleteUser(id);
}
}

spring-dao.xml

    <!--配置声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--结合AOP实现事务的织入-->
<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--给哪些方法配置事务-->
<!--配置事务的传播特性-->
<tx:attributes>
<tx:method name="add"/>
<tx:method name="update"/>
<tx:method name="delete"/>
</tx:attributes>
</tx:advice>

<!--配置事务切入-->
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.sr.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>

 

posted @ 2021-07-19 16:55  Sr淑女  阅读(57)  评论(0)    收藏  举报