Spring

Spring

1.简介
1.1、优点
  • 轻量级、非入侵式的框架

  • 免费开源框架(容器)

  • 控制反转,,面向切面

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

1.2、拓展
  • Spring Boot

    快速开发脚手架

    约定大于配置

  • Spring Cloud

    SpringCloud基于Springboot实现

2.IOC
2.1、IOC理论推导
  1. UserDao接口

  2. UserDaoImpl实现类

  3. UserService业务接口

  4. UserService业务实现类

  • 用户的需求会导致我们修改源代码,破坏程序的完整性;

  • 使用set注入后,程序不再具有主动性

        public void setUserdao(UserDao userdao) {
            this.userdao = userdao;
        }
    
  • 降低耦合性

2.2、IOC初体验
package com.ming.pojo;

/**
 * @Author:weiming
 * @Date:2020/7/12 11:39
 */
public class Hello {
    private String Name;

    public void setName(String name) {
        Name = name;
    }

    public String getName() {
        return Name;
    }

    @Override
    public String toString() {
        return "Hello{" +
                "Name='" + Name + '\'' +
                '}';
    }
}

<?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
    bean相当于new对象
    类型 变量名  = new 类型();
    Hello hello = new Hello;

    id = 变量名
    class = 类型
    property 设置属性值
    -->
    <bean id="hello" class="com.ming.pojo.Hello">
        <property name="Name" value="spring"/>
    </bean>
</beans>
public class mytest {
    public static void main(String[] args) {
        //获取spring上下文
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        Hello hello = (Hello) context.getBean("hello");
        System.out.println(hello);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HvOzorv3-1595255353978)(C:\Users\zwm\AppData\Roaming\Typora\typora-user-images\image-20200712115913999.png)]

  • 控制:Spring帮我们管理和创建的对象

  • 反转:程序本身不创建对象,而被动的变成接收对象

  • 依赖注入:利用set方法注入(体会ioc推导中的set作用),如果删掉set方法会报错

    控制反转

    采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。

2.3、IOC创建对象
  1. 默认使用无参构造
package com.ming.pojo;

/**
 * @Author:weiming
 * @Date:2020/7/13 10:30
 */
public class User {
    private String name;

    public User (){
        System.out.println("User的无参构造");
    }

//    public User(String s) {
//    }

    public String getName() {
        return name;
    }

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

    public void show (){
        System.out.println("name"+name);
    }
}

<?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
    bean相当于new对象
    类型 变量名  = new 类型();
    Hello hello = new Hello;

    id = 变量名
    class = 类型
    property 设置属性值
    -->
    <!--下标赋值-->
    <bean id="user" class="com.ming.pojo.User">
        <property name="Name" value="ming"/>
    </bean>
</beans>
public class MyTest {
    public static void main(String[] args) {
        //new User();
        ApplicationContext applicationContext =  new ClassPathXmlApplicationContext("bean.xml");
        User user = (User) applicationContext.getBean("user");
        user.show();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EsXVrYae-1595255353981)(C:\Users\zwm\AppData\Roaming\Typora\typora-user-images\image-20200713105340198.png)]

2.使用有参构造,下标赋值

<!--下标赋值-->
<bean id="user" class="com.ming.pojo.User">
   <constructor-arg index="0" value="ming"/>
    <constructor-arg index="1" value="20"/>
</bean>

3.类型赋值,局限性大,不推荐


        <bean id="user" class="com.ming.pojo.User">
           <constructor-arg type="java.lang.String" value="ming"/>
            <constructor-arg type="int" value="20"/>
        </bean> 

4.对应名称赋值,最常用

<!--对应名称赋值,最常用-->
<bean id="user" class="com.ming.pojo.User">
    <constructor-arg name="name" value="weiming"/>
    <constructor-arg name="Age" value=" 20"/>
</bean>

总结,在配置文件加载的时候,容器(ApplicationContext)就初始化了管理的对象

3、Spring配置
3.1 、 别名
<alias name="user" alias="userName"/>

​ 可以用别名取bean

3.2、Bean配置
<!--id是bean的唯一标识,也就是相当于对象名
    class :包名+类型
    name:也是别名,可以取多个别名
-->
<bean id="userT" class="com.ming.pojo.UserT" name="userT2 userT3,userT4;userT5">
</bean>
3.3、 import

这个import,一般用于团队开发,可以将多个配置文件合并为一个。可以用import所有的bean.xml,使用的时候直接用总的配置即可

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ywqzPHsD-1595255353983)(C:\Users\zwm\AppData\Roaming\Typora\typora-user-images\image-20200713132608891.png)]

4.Di依赖注入

三种构造方式之一

构造器注入,Set方式注入(重点),拓展方式注入

4.1、构造注入
4.2、set注入

依赖注入:set注入

​ 依赖:bean对象依赖于容器

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

【环境搭建】

package com.ming.pojo;

/**
 * @Author:weiming
 * @Date:2020/7/13 14:28
 */
public class Address {
    private  String address;

}
package com.ming.pojo;

import java.util.*;

/**
 * @Author:weiming
 * @Date:2020/7/13 14:28
 */
public class Student {
    private  String name;
    private  Address address;
    private  String[] books;
    private List<String> hobbbys;
    private Map<String,String> card;
    private Set<String> games;
    private String wife;
    private Properties 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> getHobbbys() {
        return hobbbys;
    }

    public void setHobbbys(List<String> hobbbys) {
        this.hobbbys = hobbbys;
    }

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

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

    public Set<String> getGames() {
        return games;
    }

    public void setGames(Set<String> games) {
        this.games = games;
    }

    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;
    }

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

4.3、拓展方式注入

p-命名空间注入 对应set注入

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


		<bean id="user" class="com.ming.pojo" p:name="ming" p:age="18"/>
    
    </beans>

c-命名空间 对应构造器注入(有参)

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:c="http://www.springframework.org/schema/c"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<bean id="user" class="com.ming.pojo" c:name="ming" c:age="18"/>
</beans>
4.4、Bean作用域
ScopeDescription
singleton(单例)(Default) Scopes a single bean definition to a single object instance for each Spring IoC container.
prototype(原型模式Scopes a single bean definition to any number of object instances.
requestScopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
sessionScopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
applicationScopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.
websocketScopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring ApplicationContext.
  • 单例模式(默认)

        <bean id="address" class="com.ming.pojo.Address" scope="singleton"/>
    

    ​ 每次取得都是同一个对象

  • 原型模式

    <bean id="address" class="com.ming.pojo.Address" scope="prototype"/>
    

    ​ 每次都创建一个对象

5、Bean自动装配

Spring自动在上下文寻找,并且自动给Bean配置属性

  1. 在xml中配置(已学)
  2. 在java代码中显式配置
  3. 隐式的自动装配(重要)
5.1、ByName自动装配
    <bean id="cat" class="com.ming.pojo.Cat"/>
    <bean id="dog" class="com.ming.pojo.Dog"/>

    <bean id="person" class="com.ming.pojo.Person">
        <property name="name" value="ming"/>
	    <property name="cat" ref="cat"/>
		<property name="dog" ref="dog"/>	
    </bean>


<!--autoWire自动装配-->
<bean id="cat" class="com.ming.pojo.Cat"/>
    <bean id="dog" class="com.ming.pojo.Dog"/>

    <bean id="person" class="com.ming.pojo.Person" autowire="byName">
        <property name="name" value="ming"/>
    </bean>
5.2、ByType自动装配
<!--根据类型自动装配,局限性:类型必须全局唯一-->
<bean id="cat" class="com.ming.pojo.Cat"/>
    <bean id="dog" class="com.ming.pojo.Dog"/>

    <bean id="person" class="com.ming.pojo.Person" autowire="byName">
        <property name="name" value="ming"/>
    </bean>
5.3、@AutoWired注解自动装配

jdk1.5支持注解,spring2.5支持注解

注解需知

  • 导入约束

  • 配置注解支持

    <?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(required = false)允许为空

实际是byType的模式,如果type相同再按照byName寻找

  • @Qualifier(“dog123”) 当类型不唯一时

        @Qualifier("dog123")
        private  Dog dog;
    
<bean id="dog123" class="com.ming.pojo.Dog"/>
<bean id="dog222" class="com.ming.pojo.Dog"/>

当类型重复时,为他指定一个默认的id进行装配

6、注解开发

注解开发需要aop包,需要context约束

6.1、@Component注解
    <context:component-scan base-package="com.ming.pojo"/>

在类上使用@Component 说明这个类被Spring管理了

//等价于<bean id= "user" class="com.ming.pojo.User">
@Component
public class User {

    private String Name;

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }
}
6.2、@value 注解
package com.ming.pojo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * @Author:weiming
 * @Date:2020/7/15 15:30
 */
//等价于<bean id= "user" class="com.ming.pojo.User">
@Component
public class User {
	//等价于<property name="name" value="weiming"/>
    @Value("weiming")
    private String Name;

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }
}

如果赋值复杂的类型,建议还是使配置文件

6.3、衍生注解

在springMVC里面有三层架构

controller【@Controller】

service【@Service】

dao【@Repository】

注解的功能都是一样的,将类注册到容器中,装配Bean

6.4、使用Java方式配置spring java
@Configuration
public class myConfig {
	  
    @Bean
    public User getUser(){
        return new User();
    }
}
public class Mytest {
    @Test
    public void test1(){
       ApplicationContext context = new AnnotationConfigApplicationContext(myConfig.class);
       User user = context.getBean("getUser",User.class);
        System.out.println(user.getName());
    }
}

在配置类中的方法名相当于xml中配置的name。

7、Aop
7.1、代理模式

分类

  • 静态代理
  • 动态代理
7.1.2静态代理

举例,房东把房子钥匙给中介,租房的人找中介看房,中介实现租房的接口方法

接口:租房

//租房的接口
public interface Rent {
    public void rent();
}

真实角色:房东

//房东
public class Host implements Rent{


    public void rent() {
        System.out.println("出租房屋");
    }
}

代理角色:中介

public class Proxy implements Rent{
    private Host host;

    public Proxy(Host host) {
        this.host = host;
    }

    public  Proxy(){

    }

    public void rent() {
        host.rent();
    }
}

客户端访问代理角色

//客户租房
public class Client {
    public static void main(String[] args) {

        Host host = new Host();
        Proxy proxy = new Proxy(host);
        proxy.rent();
    }

}

代理模式的好处

  • 让真实角色的操作更加纯粹,简单。不用去关心公共的业务
  • 公共的业务交个代理,实现业务的分工
  • 公共的业务发生拓展,方便集中管理

缺点

  • 一个真实的对象需要一个代理对象,当真实对象多的时候,开发效率低

==开闭原则:==当业务功能发生变更的时候,可以不去直接修改软件实体的源代码情况下,可以拓展模块的功能,使其满足新需求

理解:感觉就是,不是直接调用业务代码,而是在原来业务代码的基础上面,多封装了一层调用层,然后在调用层拓展公共的功能。是和开闭原则的实现

AOP

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-80ohJLZS-1595255353986)(C:\Users\zwm\AppData\Roaming\Typora\typora-user-images\image-20200716183444376.png)]

7.1.3动态代理

动态代理是动态实现的,不是直接写好的

动态代理的分类:基于接口的,基于类的

  • 基于接口的—jdk实现

  • 基于类的–cglib

  • 基于java字节码的:javasist

    //自动生成动态代理
    public class ProxyInvocationHandler implements InvocationHandler {
    
        //被代理的接口
        private Rent rent;
    
        public void setRent(Rent rent) {
            this.rent = rent;
        }
    
        //生成得到代理类
        public Object getProxy(){
            //参数:获取类的位置,代理的接口
            return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);
        }
    
        //处理代理的实例,并且返回结果
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
            //动态代理的本质是通过反射实现的
            Object result = method.invoke(rent, args);
            return result;
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            Host host = new Host();
            ProxyInvocationHandler pih = new ProxyInvocationHandler();
            pih.setRent(host);
            Rent rent = (Rent) pih.getProxy();
            rent.rent();
        }
    }
    
    
7.2、Spring实现Aop

导入依赖

    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.4</version>
        </dependency>
    </dependencies>

方式一 :Spring方式,原生API

<?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
        http://www.springframework.org/schema/aop/spring-aop.xsd"

>

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

    <!--配置aop-->
    <aop:config>
        <!--切入点 expression表达式 execution(要执行的位置.*表示这个类下面所有的方法)-->
        <aop:pointcut id="pointcut" expression="execution(* com.ming.service.UserServiceImpl.*(..))"></aop:pointcut>

        <!--环绕增加-->
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
    </aop:config>
</beans>

方式二:

自定义切面类

package com.ming.diy;

/**
 * @Author:weiming
 * @Date:2020/7/17 11:58
 */
public class diyCutPoint {

    public void before(){
        System.out.println("=========在之前=========");
    }

    public void after(){
        System.out.println("=========在之后=========");
    }
}

<?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
        http://www.springframework.org/schema/aop/spring-aop.xsd"
>
    
    <!--注册bean-->
    <bean id="userService" class="com.ming.service.UserServiceImpl"/>
    <bean id="log" class="com.ming.Log.Log"/>
    <bean id="afterLog" class="com.ming.Log.AfterLog"/>

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


</beans>

方法三:注解

@Aspect
public class AnnotationPointCut {


    //切入点
    @Before("execution(* com.ming.service.UserServiceImpl.*(..))")
    public void before(){
        System.out.println("=========在之前=========");
    }

    @After("execution(* com.ming.service.UserServiceImpl.*(..))")
    public void after(){
        System.out.println("=========在之后=========");
    }

}
    <!--方式三:注解-->
    <bean id="annotationPointCut" class="com.ming.diy.AnnotationPointCut"/>
    <!--开启注解支持-->
    <aop:aspectj-autoproxy />
8、整合mybatis
  • junit

  • mysql

  • mybatis

  • aop植入

  • mybatis-spring

  • spring相关的

    相关依赖

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version> 4.12</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version> 8.0.21</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version> 3.5.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version> 5.1.5.RELEASE</version>
        </dependency>
        <!--spring操作数据库 还要spring-jdbc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version> 1.8.11</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.2</version>
        </dependency>
    
    </dependencies>
    
8.1、回顾mybatis
  1. 编写实体
  2. 编写配置文件
  3. 编写接口
  4. 编写mapper.xml
8.2、Spring-mybatis
  1. 配置数据源
  2. SqlsessionFactory
  3. SqlsessionTemplate
  4. 给接口增加实现类
  5. 将自己的实现类注入到spring-mybatis

spring-mybatis.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的数据源代替mybatis-->
    <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/jdbcdemo?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>


<!--sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
<!--绑定mybatis配置文件-->
        <property name="configLocation" value="classpath:mybatisConfig.xml"/>
        <property name="mapperLocations" value="classpath:com/ming/mapper/*.xml"/>
     </bean>

    <!--SqlsessionTemplate:就是我们使用的sqlSession-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!--只能用构造器注入,因为他没有set方法-->
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>

    <!--注入usermapper实现类-->
    <bean id="userMapper" class="com.ming.mapper.UserMapperImpl">
        <property name="sqlSession" ref="sqlSession"/>
     </bean>

</beans>

UserMapperImpl.java

import org.mybatis.spring.SqlSessionTemplate;

import java.util.List;

/**
 * @Author:weiming
 * @Date:2020/7/18 17:20
 */
public class UserMapperImpl implements UserMapper {

    //我们的所有的操作,都使用Sqlsession来执行在原来,现在使用SqlsessionTemplate

    public SqlSessionTemplate sqlSession;

    public void setSqlSession(SqlSessionTemplate sqlSession) {
        this.sqlSession = sqlSession;
    }

    public List<mybatis> selectUser() {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        return  userMapper.selectUser();
    }
}

原来mybatis.xml的配置最终精简为


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    
    <typeAliases>
        <package name="com.ming.pojo"/>
    </typeAliases>

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

精简,省略SqlsessionTemplate,继承了sqlsessionDaoSupport这样就不用去私有化sqlsessionfactory(参考UserMapperImpl的操作)

/**
 * @Author:weiming
 * @Date:2020/7/18 19:09
 *
 *
 * 继承了sqlsessionDaoSupport这样就不用去私有化sqlsessionfactory(参考UserMapperImpl的操作)
 */

public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper {


    public List<mybatis> selectUser() {
        return getSqlSession().getMapper(UserMapper.class).selectUser();
    }
}

在xml配置中注入SqlsessionTemplate


    <bean id="userMapper2" class="com.ming.mapper.UserMapperImpl2">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
9、声明式事务

要么都成功,要么都失败

事务ACID

  • 原子性
  • 一致性
  • 隔离性 :多个业务操作同一个资源,防止数据损坏
  • 持久性:结果不被影响

http://mybatis.org/spring/zh/transactions.html

9.1、spring事务管理
  • 申明式事务(aop)

    要开启 Spring 的事务处理功能,在 Spring 的配置文件中创建一个 DataSourceTransactionManager 对象:

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <constructor-arg ref="dataSource" />
</bean>

配置事务通知

 <!--配置事务通知-->
    <tx:advice id="advise" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="add" propagation="REQUIRED"/>
            <tx:method name="del"/>
            <tx:method name="update"/>
            <tx:method name="query"/>
            <tx:method name="*"/>
        </tx:attributes>

    </tx:advice>

propagation

一、在声明式的事务处理中,要配置一个切面,其中就用到了propagation,表示打算对这些方法怎么使用事务,是用还是不用,其中propagation有七种配置,REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED。默认是REQUIRED。

二、Spring中七种Propagation类的事务属性详解:

REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。

MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。

REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。

NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。

三、注意.
这个配置将影响数据存储,必须根据情况选择。
————————————————
版权声明:本文为CSDN博主「sayok_why」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sayoko06/article/details/79164858

将事务织入,通过aop切入

        <!--配置事务切入-->
        <aop:config>
            <!--将mapper下的所有方法织入-->
            <aop:pointcut id="pointcut" expression="execution(* com.ming.mapper.*.*(..))"/>
            <aop:advisor advice-ref="advise" pointcut-ref="pointcut"></aop:advisor>
        </aop:config>

完整配置

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <constructor-arg ref="dataSource" />
        </bean>
        <!--配置事务通知-->
        <tx:advice id="advise" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="add" propagation="REQUIRED"/>
                <tx:method name="del"/>
                <tx:method name="update"/>
                <tx:method name="query"/>
                <tx:method name="*"/>
            </tx:attributes>

        </tx:advice>

        <!--配置事务切入-->
        <aop:config>
            <!--将mapper下的所有方法织入-->
            <aop:pointcut id="pointcut" expression="execution(* com.ming.mapper.*.*(..))"/>
            <aop:advisor advice-ref="advise" pointcut-ref="pointcut"></aop:advisor>
        </aop:config>

事务可以解决数据一致性的问题

  • 编程式事务

请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/sayoko06/article/details/79164858

将事务织入,通过aop切入

        <!--配置事务切入-->
        <aop:config>
            <!--将mapper下的所有方法织入-->
            <aop:pointcut id="pointcut" expression="execution(* com.ming.mapper.*.*(..))"/>
            <aop:advisor advice-ref="advise" pointcut-ref="pointcut"></aop:advisor>
        </aop:config>

完整配置

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <constructor-arg ref="dataSource" />
        </bean>
        <!--配置事务通知-->
        <tx:advice id="advise" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="add" propagation="REQUIRED"/>
                <tx:method name="del"/>
                <tx:method name="update"/>
                <tx:method name="query"/>
                <tx:method name="*"/>
            </tx:attributes>

        </tx:advice>

        <!--配置事务切入-->
        <aop:config>
            <!--将mapper下的所有方法织入-->
            <aop:pointcut id="pointcut" expression="execution(* com.ming.mapper.*.*(..))"/>
            <aop:advisor advice-ref="advise" pointcut-ref="pointcut"></aop:advisor>
        </aop:config>

事务可以解决数据一致性的问题

  • 编程式事务
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值