• spring


    Spring 简介

    Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由 EJB 框架完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。

    历史 :

    • 2002 年首次推出了 Spring 的雏形 – interface21框架!
    • Spring 框架以 interface21 框架为基础,经过重新设计,并不断丰富其内涵,在2004年3月24日,发布了1.0正式版

    Spring框架的创始人 – Rod Johnson

    Rod在悉尼大学不仅获得了计算机学位,同时还获得了音乐学位。

    Spring 框架使现有的技术更加容易使用,整合了现有的技术框架

    优点

    • Spring是一个开源免费的框架
    • Spring 是一个轻量级的框架
    • 控制反转(IOC)和 面向切面编程(AOP)
    • 支持事务的处理,spring提供了统一的事务管理接口,无需手动编程。
    • 支持集成其他类型的框架 (如:Struts、Hibernate、MyBatis)。
    • 异常处理:Spring提供统一处理异常的机制。

    Spring 的组成

    在这里插入图片描述

    需要用到的maven依赖

    
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-webmvcartifactId>
        <version>5.3.9version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    IOC 的本质

    之前的 实例化 dao 接口

    private UserDao userDao = new UserDaoImpl();
    
    • 1

    现在的实例化 dao 接口

    private UserDao userDao ;
    
    //使用 set 注入的方式实例化dao接口
    public void setUserDao(UserDao userDao) {
      this.userDao = userDao;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    之前是程序主动创建对象,控制权在程序员手上;现在使用了 set 注入的方式后,程序不在具有主动性,而是变成了被动的接受对象!

    这种思想,从本质上解决了问题,程序员不在需要去管理对象的创建了。系统的耦合度大大降低了,可以更专注在业务代码的实现上!这就是 IOC 的原型。

    编写第一个 Spring 程序

    1、导入 maven 依赖

    
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-webmvcartifactId>
        <version>5.3.9version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、创建实体类

    package com.hkp.entity;
    
    public class User {
        private Integer id;
        private String name;
        private Integer age;
        
        //生成对应的 get、set、toString 方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3、在 resources 文件夹中创建 applicationContext.xml 文件

    
    <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="user" class="com.hkp.entity.User">
            <property name="id" value="1"/>
            <property name="name" value="admin"/>
            <property name="age" value="21"/>
        bean>
    
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    4、创建测试类

    public static void main(String[] args) {
      //家在配置文件,实例化一个容器,获取Spring的上下文对象,参数可以有多个(可以加载多个配置文件)
      ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
      //我们的对象现在都在 Spring 容器中管理,如果要使用,只需要从里面取出来就行
      //从 Spring 容器中取对象 ,参数为 对象名 -- 就是 applicationContext.xml 文件中 bean 标签中的 name 属性
      User user = (User) context.getBean("user");
      System.out.println(user.toString());
      //输出结果 :User{id=1, name='admin', age=21}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    思考问题 :

    1、谁创建的对象? --Spring 创建的

    2、对象的属性是怎么设置的? --属性是有 Spring 容器设置的

    这个过程就叫控制反转。

    控制 :谁来控制对象的创建?传统的应用程序的对象是由程序本身控制创建的(new出一个对象),使用 Spring 后,对象是由 Spring 来创建的。

    反转 :程序本身不创建对象,而是被动的接收对象。

    依赖注入 :就是利用 set 方法进行注入。

    IOC 是一种编程思想,由主动的编程变成被动的接收。

    现在,要实现的操作,我们彻底不用去程序中做改动。只需要在 xml 配置文件中进行修改。

    所谓的 IOC 就是一句话 :对象由 Spring 来创建、管理、装配。

    IOC 创建对象的方式

    1、默认使用 无参构造器 创建对象,默认的方式

    <bean id="user" class="com.hkp.entity.User">
      <property name="id" value="1"/>
      <property name="name" value="admin"/>
      <property name="age" value="21"/>
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、使用有参构造器创建对象,

    • 通过下标赋值,下标的顺序就是参数的顺序,不能颠倒顺序

    • <bean id="user" class="com.hkp.entity.User">
        <constructor-arg index="0" value="1"/>
        <constructor-arg index="1" value="admin"/>
        <constructor-arg index="2" value="21"/>
      bean>
      
      • 1
      • 2
      • 3
      • 4
      • 5
    • 通过参数名赋值(与无参构造器类似)

    • <bean id="user" class="com.hkp.entity.User">
        <constructor-arg name="id" value="1"/>
        <constructor-arg name="name" value="admin"/>
        <constructor-arg name="age" value="21"/>
      bean>
      
      • 1
      • 2
      • 3
      • 4
      • 5

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

    Spring 配置

    别名

    方式一 :使用 alias 标签定义

    
    <alias name="user" alias="newUser"/>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    //实例化一个容器,获取Spring的上下文对象
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    User user = (User) context.getBean("user");
    User user2 = (User) context.getBean("newUser");
    System.out.println(user.getName().equals(user2.getName()));//true
    
    • 1
    • 2
    • 3
    • 4
    • 5

    方式二 :使用 bean 标签定义

    
    <bean id="user" class="com.hkp.entity.User" name="user2,user3 user4;user5">
      <property name="id" value="1"/>
      <property name="name" value="admin"/>
      <property name="age" value="21"/>
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    import

    这个标签用于团队开发使用,他可以将多个配置文件,导入合并为一个。

    多个配置文件中的配置有相同的配置的话,在调用的时候会随机选择一个进行使用

    案例

    1、在 resources 文件夹中创建 beans.xml 、beans2.xml 文件,内容相同

    
    <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="user" class="com.hkp.entity.User" name="user2,user3 user4;user5">
            <property name="id" value="1"/>
            <property name="name" value="admin"/>
            <property name="age" value="21"/>
        bean>
    
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    2、applicationContext.xml

    
    <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="beans.xml"/>
        <import resource="beans2.xml"/>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3、测试

    public static void main(String[] args) {
      //实例化一个容器,获取Spring的上下文对象
      ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
      //我们的对象现在都在 Spring 容器中管理,如果要使用,只需要从里面取出来就行
      //从 Spring 容器中取对象 ,参数为 对象名 -- 就是 applicationContext.xml 文件中 bean 标签中的 name 属性
      User user = (User) context.getBean("user");
      System.out.println(user.toString());
      //输出结果 :User{id=1, name='admin', age=21}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    DI 依赖注入

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

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

    DI 存在两种主要变体:基于构造函数的依赖注入和基于 Setter 的依赖注入。

    通过 构造函数 注入

    在 IOC 创建对象的方式中已经讲过了。

    • 通过下标赋值,下标的顺序就是参数的顺序,不能颠倒顺序

    • <bean id="user" class="com.hkp.entity.User">
        <constructor-arg index="0" value="1"/>
        <constructor-arg index="1" value="admin"/>
        <constructor-arg index="2" value="21"/>
      bean>
      
      • 1
      • 2
      • 3
      • 4
      • 5
    • 通过参数名赋值(与无参构造器类似)

    • <bean id="user" class="com.hkp.entity.User">
        <constructor-arg name="id" value="1"/>
        <constructor-arg name="name" value="admin"/>
        <constructor-arg name="age" value="21"/>
      bean>
      
      • 1
      • 2
      • 3
      • 4
      • 5

    通过 set 方法 注入

    案例 :

    1、创建实体类

    真实测试的实体类

    public class User {
    
        private String name;
        private Address address;
        private String[] books;
        private List<String> hobbies;
        private Map<String,String> score;
        private Set<String> games;
        private String testNull;
        private String testKong;
        private Properties pro;
    		
      	//对应的 get、set和 toString 方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    引用类型的实体类

    package com.hkp.entity;
    public class Address {
        private String address;
        //对应的 get、set和 toString 方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    配置 applicationContext.xml

    
    <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="address" class="com.hkp.entity.Address">
            <property name="address" value="北京市"/>
        bean>
    
        
        <bean id="user" class="com.hkp.entity.User">
            
            <property name="name" value="admin"/>
    
            
            <property name="address" ref="address"/>
    
            
            <property name="books">
                <array>
                    <value>水浒传value>
                    <value>西游记value>
                    <value>红楼梦value>
                    <value>三国演义value>
                array>
            property>
    
            
            <property name="hobbies">
                <list>
                    <value>听歌value>
                    <value>读书value>
                    <value>敲代码value>
                list>
            property>
    
            
            <property name="score">
                <map>
                    <entry key="语文" value="96"/>
                    <entry key="数学" value="99"/>
                    <entry key="英语" value="90"/>
                map>
            property>
    
            
            <property name="games">
                <set>
                    <value>LOLvalue>
                    <value>BOBvalue>
                    <value>吃鸡value>
                set>
            property>
    
            
            <property name="testNull">
                <null/>
            property>
    
            
            <property name="testKong" value=""/>
    
            
            <property name="pro">
                <props>
                    <prop key="学号">20210210prop>
                    <prop key="姓名">adminprop>
                    <prop key="性别">prop>
                props>
            property>
        bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    测试

    public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
      User user = (User) context.getBean("user");
      System.out.println(user.toString());
      /*
            * User{
            *   name='admin',
            *   address=Address{address='北京市'},
            *   books=[水浒传, 西游记, 红楼梦, 三国演义],
            *   hobbies=[听歌, 读书, 敲代码],
            *   score={语文=96, 数学=99, 英语=90},
            *   games=[LOL, BOB, 吃鸡],
            *   testNull='null',
            *   testKong='',
            *   pro={学号=20210210, 性别=男, 姓名=admin}
            *	}
            * */
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    拓展注入方式

    p 命名空间

    在 applicationContext.xml 文件中添加

    xmlns:p="http://www.springframework.org/schema/p"
    
    • 1

    applicationContext.xml

    
    <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.hkp.entity.User" p:id="1" p:age="21" p:name="admin" p:address-ref="address"/>
        
        <bean id="address" class="com.hkp.entity.Address">
            <property name="address" value="北京市"/>
        bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    c 命名空间

    在 applicationContext.xml 文件中添加

    xmlns:c="http://www.springframework.org/schema/c"
    
    • 1

    applicationContext.xml

    
    <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="user2" class="com.hkp.entity.User" c:id="1" c:age="21" c:name="admin" c:address-ref="address"/>
    
        <bean id="address" class="com.hkp.entity.Address">
            <property name="address" value="北京市"/>
        bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    bean 的作用域

    单例模式

    是 Spring 的默认机制

    
    <bean id="user" class="com.hkp.entity.User" scope="singleton"/>
    
    • 1
    • 2

    在 调用的时候,同时调用两次返回的结果是相同的,就说明两次调用的bean 是同一个 bean

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    User user = (User) context.getBean("user");
    User user2 = (User) context.getBean("user");
    System.out.println(user==user2);//true
    System.out.println(user.hashCode());//827966648
    System.out.println(user2.hashCode());//827966648
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    原型模式

    每次从容器中 getBean 的时候都会产生一个新对象

    
    <bean id="user" class="com.hkp.entity.User" scope="prototype"/>
    
    • 1
    • 2

    在 调用的时候,同时调用两次返回的结果不是相同的,就说明两次调用的bean 不是同一个 bean

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    User user = (User) context.getBean("user");
    User user2 = (User) context.getBean("user");
    System.out.println(user==user2);//false
    System.out.println(user.hashCode());//1164371389
    System.out.println(user2.hashCode());//517210187
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    其余的作用域 request、session、application 等都是 web 的时候才能用到

    bean 的自动装配

    自动装配是 Spring 满足 bean 依赖的一种方式,Spring 会在上下文中自动寻找,并自动给 bean 装配属性!

    Spring 中有三种装配方式 :

    1. 在 xml 中显示装配
    2. 在 Java 中显示装配
    3. 隐式的自动转配 bean 【重点】

    环境搭建

    • 实体类

      //cat
      public class Cat {
          public void shout(){
              System.out.println("miao~");
          }
      }
      
      //dog
      public class Dog {
          public void shout(){
              System.out.println("wang~");
          }
      }
      
      //People
      public class People {
          private Cat cat;
          private Dog dog;
          private String name;
      		
        	//对应的 get、set 方法
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
    • xml

      
      <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="dog" class="com.hkp.entity.Dog"/>
          <bean id="cat" class="com.hkp.entity.Cat"/>
          <bean id="people" class="com.hkp.entity.People">
              <property name="name" value="test"/>
              <property name="dog" ref="dog"/>
              <property name="cat" ref="cat"/>
          bean>
      
      beans>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
    • 测试类

      public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        People people = context.getBean("people", People.class);
        people.getDog().shout();
        people.getCat().shout();
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

    自动装配-- byName

    
    <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="dog" class="com.hkp.entity.Dog"/>
        <bean id="cat" class="com.hkp.entity.Cat"/>
        
        <bean id="people" class="com.hkp.entity.People" autowire="byName">
            <property name="name" value="test"/>
        bean>
    
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    自动装配-- byType

    
    <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="dog" class="com.hkp.entity.Dog"/>
        <bean id="cat" class="com.hkp.entity.Cat"/>
        
        <bean id="people" class="com.hkp.entity.People" autowire="byType">
            <property name="name" value="test"/>
        bean>
    
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    小结 :

    • byName : 需要保证所有 bean 中 id 的唯一性,并且这个bean要和实体中的 set 方法的值一致
    • byType : 需要保证所有 bean 中 class 的唯一性,并且这个bean要和实体中的 属性的类型一致

    使用注解实现自动装配

    jdk 从1.5开始支持注解,Spring 从 2.5 开始支持注解

    1、导入约束

    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/context
            https://www.springframework.org/schema/context/spring-context.xsd"
    
    • 1
    • 2
    • 3

    2、在 applicationContext.xml 中配置 注解的支持

    
    <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/>
    		<bean id="dog" class="com.hkp.entity.Dog"/>
        <bean id="cat" class="com.hkp.entity.Cat"/>
        <bean id="people" class="com.hkp.entity.People">
            <property name="name" value="test"/>
        bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    People 实体中的改动

    public class People {
        @Autowired
      	@Qualifier(value = "cat1")
        private Cat cat;
        @Autowired
        private Dog dog;
        private String name;
    		//对应的 get 的方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    @Autowired

    import org.springframework.beans.factory.annotation.Autowired;
    
    • 1

    该注解可以直接加在属性或者 set 方法上;使用该注解时,实体类中可以不加 set 方法

    @Qualifier(value = “cat1”)

    import org.springframework.beans.factory.annotation.Qualifier;
    
    • 1

    该注解用于一个对象在 applicationContext.xml 配置文件中配置了多个bean,此时自动注入不知该选择哪一个,这时用该注解来指定一个 bean 即可。value 的参数值为 bean 标签中的 id 值

    @Resource

    import javax.annotation.Resource;
    
    • 1
    public class People {
        @Resource
        private Cat cat;
        @Resource
        private Dog dog;
        private String name;
      	//对应的 get 方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    该注解的作用可以替代@Autowired@Qualifier(value = “cat1”) 他们两个,如果不加参数就和@Autowired 类似。 如果一个对象在 application.xml 配置文件中配置了多个bean,此时直接使用 @Resource 自动注入不知该选择哪一个,这时在该注解后面加一个参数 @Resource(name = “”) 指定一个 bean 即可。name 的值为 bean 标签中的 id 值

    @Autowired 和 @Resource 的区别 :

    • 都是自动装配,都可以放在属性和方法上
    • @Autowired 是通过 byType 的方式实现的,而且必须要求这个对象存在
    • @Resource 是通过 byName 的方式实现的,如果找不到对应的名字则会通过 byType 的方式实现

    使用注解开发

    在 Spring4 之后 要使用注解开发,需要导入 aop 包

    在这里插入图片描述

    在 applicationContext.xml 配置文件中配置注解的支持

    
    <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.hkp"/>
    
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    @Component

    import org.springframework.stereotype.Component;
    
    • 1

    组件,用在实体类上,等价于在xml文件中 ,id属性默认为全小写

    1、创建实体类

    @Component //组件,等价于在xml文件中,id属性默认为全小写
    public class User {
        public String name="Hello World!!!";
    }
    
    • 1
    • 2
    • 3
    • 4

    2、编写测试

    public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
      User user = context.getBean("user", User.class);
      System.out.println(user.name);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    @Value

    import org.springframework.beans.factory.annotation.Value;
    
    • 1

    给属性设置默认值,相等于

    1、编写实体类

    @Component //组件,等价于在xml文件中
    public class User {
        //给属性默认值,相等于
        @Value("Hello World!!!")
        public String name;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、编写测试

    public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
      User user = context.getBean("user", User.class);
      System.out.println(user.name);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    衍生的注解

    @Component 中有几个衍生的注解,这几个注解的作用都是一样的,都是用来将类注解成bean 的,只不过用的层级不一样

    • dao

      import org.springframework.stereotype.Repository;
      @Repository
      
      • 1
      • 2
    • service

      import org.springframework.stereotype.Service;
      @Service
      
      • 1
      • 2
    • controller

      import org.springframework.stereotype.Controller;
      @Controller
      
      • 1
      • 2

    小结 :

    @Component 实体类

    @Repository 持久层

    @Service 业务层

    @Controller 控制层

    自动装配

    @Autowired

    import org.springframework.beans.factory.annotation.Autowired;
    
    • 1

    该注解可以直接加在属性或者 set 方法上;使用该注解时,实体类中可以不加 set 方法

    @Qualifier(value = “cat1”)

    import org.springframework.beans.factory.annotation.Qualifier;
    
    • 1

    该注解用于一个对象在 applicationContext.xml 配置文件中配置了多个bean,此时自动注入不知该选择哪一个,这时用该注解来指定一个 bean 即可。value 的参数值为 bean 标签中的 id 值

    @Resource

    import javax.annotation.Resource;
    
    • 1
    public class People {
        @Resource
        private Cat cat;
        @Resource
        private Dog dog;
        private String name;
      	//对应的 get 方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    该注解的作用可以替代@Autowired@Qualifier(value = “cat1”) 他们两个,如果不加参数就和@Autowired 类似。 如果一个对象在 application.xml 配置文件中配置了多个bean,此时直接使用 @Resource 自动注入不知该选择哪一个,这时在该注解后面加一个参数 @Resource(name = “”) 指定一个 bean 即可。name 的值为 bean 标签中的 id 值

    @Autowired 和 @Resource 的区别 :

    • 都是自动装配,都可以放在属性和方法上
    • @Autowired 是通过 byType 的方式实现的,而且必须要求这个对象存在
    • @Resource 是通过 byName 的方式实现的,如果找不到对应的名字则会通过 byType 的方式实现

    bean的作用域

    import org.springframework.context.annotation.Scope;
    
    • 1
    @Component //组件,等价于在xml文件中
    @Scope("singleton")
    //@Scope("singleton") 表示将该实体设置生了单例模式,Spring的默认模式
    //@Scope("prototype") 表示将该实体设置生了原型模式,每次从容器中 getBean 的时候都会产生一个新对象
    public class User {
        //给属性默认值,相等于
        @Value("Hello World!!!")
        public String name;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    使用 Java 的方式 配置 spring

    可以不使用 xml 来配置 Spring 了,

    1、创建实体

    package com.hkp.entity;
    import org.springframework.beans.factory.annotation.Value;
    
    public class User {
        @Value("hello")
        private String name;
    
       //get、set方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2、创建配置文件

    package com.hkp.config;
    import com.hkp.entity.User;
    import org.springframework.beans.factory.annotation.Configurable;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Import;
    
    @Configurable //等同于 applicationContext.xml 文件中的 标签
    @Import(MyConfig2.class)//引入外部配置文件,等价于
    public class MyConfig {
        /**
         * 注册一个bean,等价于在xml文件中
         * 方法中的方法名相当于 bean 标签中的id属性
         * 方法中的返回值相当于 bean 标签中的 class 属性
         * @return
         */
        @Bean
        public User getUser(){
            return new User();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3、创建测试

    import com.hkp.config.MyConfig;
    import com.hkp.entity.User;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class TestDemo {
        public static void main(String[] args) {
            //如果使用了配置类方式去做,我们就只能通过AnnotationConfigApplicationContext 来获取容器
            ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
            User user = (User) context.getBean("getUser");
            System.out.println(user.getName());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    代理模式

    代理模式是SpringAOP的底层

    代理模式的分类 :

    • 静态代理
    • 动态代理

    静态代理

    代理模式的好处 :

    • 可是真实角色操作更加纯粹,不用去关注其他业务
    • 公共业务发生拓展的时候,方便集中管理

    缺点 :

    • 一个真实角色有一个代理 – 代码臃肿

    以一个 租房的案例 :

    1、编写接口

    public interface Rent {
        void rent();
    }
    
    • 1
    • 2
    • 3

    2、真实角色(房东)

    public class Host implements Rent{
        public void rent(){
            System.out.println("房主要出租房子");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3、代理

    public class Proxy implements Rent{
        //出租房间
        @Override
        public void rent() {
            look();
            System.out.println("授权给代理发布房间出租");
            free();
        }
        
        //收中介费
        public void free(){
            System.out.println("收中介费");
        }
        
        //看房子
        public void look(){
            System.out.println("看房子");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    4、客户端访问代理角色

    public class Client {
        public static void main(String[] args) {
            Proxy proxy = new Proxy();
            proxy.rent();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    动态代理

    动态代理的代理类是动态生成的,不是我们直接写好的

    动态代理分为两类 :

    • 基于接口的动态代理 :JDK 动态代理(常用)
    • 基于类的动态代理 :cglib
    • Java 字节码 :javasist

    JDK 动态代理需要用到的类 :Proxy :代理、InvocationHandler :调用处理程序(里面只有一个方法 invoke )

    案例

    1、编写接口

    public interface Rent {
        void rent();
    }
    
    • 1
    • 2
    • 3

    2、真实角色(房东)

    public class Host implements Rent{
        public void rent(){
            System.out.println("房主要出租房子");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3、动态生成代理类

    package com.hkp.demo1;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    //用这个类,自动生成代理类
    public class ProxyIn 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);
        }
    
        //处理代理实例,并返回结果
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            seeHouse();
            //执行方法
            Object result = method.invoke(rent, args);
            free();
            return result;
        }
    
        public void seeHouse(){
            System.out.println("看房子");
        }
    
        public void free(){
            System.out.println("收中介费");
        }
    
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    4、客户端访问代理角色

    public class Client {
        public static void main(String[] args) {
            //真实角色
            Host host = new Host();
            //获得代理类
            ProxyIn proxyIn = new ProxyIn();
            proxyIn.setRent(host);
            //动态生成的代理类
            Rent proxy = (Rent) proxyIn.getProxy();
            proxy.rent();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    aop

    在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

    aop在Sprin的作用

    提供声明式事务,允许用户自定义切面

    横切关注点 :跨越应用程序多个模块的方法或功能。即与我们的业务逻辑无关,但需要我们关注的部分,就是横切关注点。如日志、事务、缓存等等。

    切面(ASPECT):横切关注点被模块化的特殊对象。即他是一个类

    通知(Advice):切面必须要完成的工作。即他是类中的一个方法

    目标(Target):被通知的对象

    代理(Proxy):向目标对象应用通知之后创建的对象

    切入点(PointCut):切面通知执行的“地点”

    连接点(JoinPoint):与切入点匹配的执行点

    在这里插入图片描述

    Spring AOP 中,通过Advice 定义横切逻辑,Spring 中支持类型的 Advice

    在这里插入图片描述

    使用 Spring 实现 AOP

    需要的依赖

    
    <dependency>
        <groupId>org.aspectjgroupId>
        <artifactId>aspectjweaverartifactId>
        <version>1.9.7version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    方式一 :使用 Spring API 接口

    1、创建接口

    package com.hkp.service;
    
    public interface UserService {
        void add();
        void delete();
        void update();
        void select();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2、创建接口实现

    package com.hkp.service;
    
    public class UserServiceImpl implements UserService{
        @Override
        public void add() {
            System.out.println("进入了增加方法");
        }
    
        @Override
        public void delete() {
            System.out.println("进入了删除方法");
        }
    
        @Override
        public void update() {
            System.out.println("进入了修改方法");
        }
    
        @Override
        public void select() {
            System.out.println("进入了查询方法");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    3、创建日志类

    //前置通知
    package com.hkp.log;
    import org.springframework.aop.MethodBeforeAdvice;
    import java.lang.reflect.Method;
    
    public class BeforeLog implements MethodBeforeAdvice {
        /**
         * 参数详解
         * @param method 执行的方法
         * @param objects 参数
         * @param o 目标对象
         * @throws Throwable
         */
        @Override
        public void before(Method method, Object[] objects, Object o) throws Throwable {
            System.out.println(o.getClass().getName()+"类中的 "+method.getName()+" 方法即将被执行");
        }
    }
    
    
    
    //后置通知
    package com.hkp.log;
    import org.springframework.aop.AfterReturningAdvice;
    import java.lang.reflect.Method;
    
    public class AfterLog implements AfterReturningAdvice {
        /**
         *
         * @param o 返回值
         * @param method 执行的方法
         * @param objects 参数
         * @param o1 目标对象
         * @throws Throwable
         */
        @Override
        public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
            System.out.println(o1.getClass().getName()+"类中的 "+method.getName()+" 方法已经被执行");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    4、配置 applicationContext.xml 文件

    导入约束

    xmlns:aop="http://www.springframework.org/schema/aop"
    http://www.springframework.org/schema/aop
            https://www.springframework.org/schema/aop/spring-aop.xsd
    
    • 1
    • 2
    • 3
    
    <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 id="userServiceImpl" class="com.hkp.service.UserServiceImpl"/>
        <bean id="afterLog" class="com.hkp.log.AfterLog"/>
        <bean id="beforeLog" class="com.hkp.log.BeforeLog"/>
    
        
        <aop:config>
            
            
            <aop:pointcut id="pointcut" expression="execution(* com.hkp.service.UserServiceImpl.*(..))"/>
    				
            <aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>
            <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
        aop:config>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    5、测试

    public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
      //动态代理的是接口
      UserService userService = (UserService) context.getBean("userServiceImpl");
      userService.add();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    方式二 :自定义类

    接口与实现类与方式一中的相同

    1、编写 自定义日志类

    package com.hkp.diy;
    
    public class DiyPointCut {
    
        public void before(){
            System.out.println("执行方法前");
        }
    
        public void after(){
            System.out.println("执行方法后");
        }
    		
      	public void around(ProceedingJoinPoint jp) throws Throwable {
            System.out.println("环绕前");
            jp.proceed();//执行方法
            System.out.println("环绕后");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2、配置 applicationContext.xml 文件

    
    <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 id="userServiceImpl" class="com.hkp.service.UserServiceImpl"/>
        <bean id="diy" class="com.hkp.diy.DiyPointCut"/>
    
        <aop:config>
            
            <aop:aspect ref="diy">
                
                <aop:pointcut id="point" expression="execution(* com.hkp.service.UserServiceImpl.*(..))"/>
                
                <aop:before method="before" pointcut-ref="point"/>
                <aop:after method="after" pointcut-ref="point"/>
              	<aop:around method="around" pointcut-ref="point"/>
            aop:aspect>
        aop:config>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    3、测试

    public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
      //动态代理的是接口
      UserService userService = (UserService) context.getBean("userServiceImpl");
      userService.add();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    方式三 :使用注解实现 aop

    接口与实现类与方式一中的相同

    1、编写 自定义日志类

    package com.hkp.diy;
    
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    
    @Aspect //标注该类是一个切面类
    public class AnnoPointCut {
    
        //里面的参数为切入点
        @Before("execution(* com.hkp.service.UserServiceImpl.*(..))")
        public void before(){
            System.out.println("执行方法前");
        }
        @After("execution(* com.hkp.service.UserServiceImpl.*(..))")
        public void after(){
            System.out.println("执行方法后");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    2、配置 applicationContext.xml 文件

    
    <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 id="userServiceImpl" class="com.hkp.service.UserServiceImpl"/>
        <bean id="annoPointcut" class="com.hkp.diy.AnnoPointCut"/>
    		
        <aop:aspectj-autoproxy/>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3、测试

    public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
      //动态代理的是接口
      UserService userService = (UserService) context.getBean("userServiceImpl");
      userService.add();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    整合 mybatis

    文档 :mybatis-spring –

    在这里插入图片描述

    需要的 jar 依赖

    
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-webmvcartifactId>
        <version>5.3.9version>
    dependency>
    
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-jdbcartifactId>
        <version>5.3.9version>
    dependency>
    
    <dependency>
        <groupId>org.aspectjgroupId>
        <artifactId>aspectjweaverartifactId>
        <version>1.9.7version>
    dependency>
    
    <dependency>
        <groupId>org.projectlombokgroupId>
        <artifactId>lombokartifactId>
        <version>1.18.20version>
    dependency>
    
    <dependency>
        <groupId>org.mybatisgroupId>
        <artifactId>mybatisartifactId>
        <version>3.5.7version>
    dependency>
    
    <dependency>
        <groupId>junitgroupId>
        <artifactId>junitartifactId>
        <version>4.13version>
    dependency>
    
    <dependency>
        <groupId>mysqlgroupId>
        <artifactId>mysql-connector-javaartifactId>
        <version>8.0.25version>
    dependency>
    
    <dependency>
        <groupId>org.mybatisgroupId>
        <artifactId>mybatis-springartifactId>
        <version>2.0.6version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    入门–先将mybatis跑起来

    1、创建 mybatis 核心配置文件

    
    DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    
    <configuration>
        
        <properties resource="db.properties">properties>
    
    
    
    
    
        <typeAliases>
            <package name="com.hkp.entity"/>
        typeAliases>
        
        <environments default="development">
            <environment id="development">
                
                <transactionManager type="JDBC" />
                
                <dataSource type="POOLED">
                    
                    <property name="driver" value="${driver}" />
                    
                    <property name="url" value="${url}" />
                    
                    <property name="username" value="${user}" />
                    
                    <property name="password" value="${password}" />
                dataSource>
            environment>
        environments>
    
        
        <mappers>
            <mapper class="com.hkp.mapper.UserMapper"/>
        mappers>
    configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    2、创建实体类

    package com.hkp.entity;
    
    import java.util.Date;
    
    public class User {
        private Integer id;
        private String userCode;
        private String userName;
        private String userPassword;
        private Integer gender;
        private Date birthday;
        private String phone;
        private String address;
        private Integer userRole;
        private Integer createdBy;
        private Date creationDate;
        private Integer modifyBy;
        private Date modifyDate;
        
        ...对应的 get set 方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    3、创建 UserMapper 接口

    public interface UserMapper {
        List<User> selectUser();
    }
    
    • 1
    • 2
    • 3

    4、创建 UserMapper.xml 映射器

    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.hkp.mapper.UserMapper">
        <select id="selectUser" resultType="user">
    		SELECT * FROM smbms_user
    	select>
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    5、创建 测试类

    @Test
    public void testMybatis() throws Exception{
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = mapper.selectUser();
        sqlSession.close();
        for (User user: userList) {
            System.out.println(user);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    spring 整合 mybatis

    方式一 :实现类中需要注入 sqlSession

    1、修改 mybatis 核心配置文件的配置

    
    DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    
    <configuration>
    
    
    
    
    
        <typeAliases>
            <package name="com.hkp.entity"/>
        typeAliases>
    configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2、创建 UserMapper 实现

    package com.hkp.mapper;
    
    import com.hkp.entity.User;
    import org.mybatis.spring.SqlSessionTemplate;
    import java.util.List;
    
    public class UserMapperImpl implements UserMapper{
    
        //之前都是使用 sqlSession 来操作,现在是使用 sqlSessionTemplate 
        private SqlSessionTemplate sqlSession;
    
        public void setSqlSession(SqlSessionTemplate sqlSession) {
            this.sqlSession = sqlSession;
        }
    
        @Override
        public List<User> selectUser() {
            return sqlSession.getMapper(UserMapper.class).selectUser();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3、创建 spring 配置文件

    
    <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:property-placeholder
                location="classpath*:db.properties" />
    
        
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="${driver}">property>
            <property name="url" value="${url}">property>
            <property name="username" value="${user}">property>
            <property name="password" value="${password}">property>
        bean>
    
        
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            
            <property name="configLocation" value="classpath:mybatis-config.xml"/>
            
            <property name="mapperLocations" value="classpath:com/hkp/mapper/*.xml"/>
        bean>
    
        
        <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
            
            <constructor-arg index="0" ref="sqlSessionFactory"/>
        bean>
    
        <bean id="userMapper" class="com.hkp.mapper.UserMapperImpl">
            <property name="sqlSession" ref="sqlSession"/>
        bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    4、编写测试类

    @Test
    public void testSpring(){
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-dataSource.xml");
        UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
        List<User> userList = userMapper.selectUser();
        for (User user: userList) {
            System.out.println(user);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    方式二 :SqlSessionDaoSupport 不需要手动注入 sqlSession

    SqlSessionDaoSupport 是一个抽象的支持类,用来为你提供 SqlSession。调用 getSqlSession() 方法你会得到一个 SqlSessionTemplate,之后可以用于执行 SQL 方法

    1、重新创建 UserMapper 实现类

    public class UserMapper2 extends SqlSessionDaoSupport implements UserMapper {
        @Override
        public List<User> selectUser() {
            SqlSession sqlSession = getSqlSession();
            return sqlSession.getMapper(UserMapper.class).selectUser();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2、修改 spring 的配置文件

    
    <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:property-placeholder
                location="classpath:db.properties" />
    
        
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="${driver}">property>
            <property name="url" value="${url}">property>
            <property name="username" value="${user}">property>
            <property name="password" value="${password}">property>
        bean>
    
        
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            
            <property name="configLocation" value="classpath:mybatis-config.xml"/>
            
            <property name="mapperLocations" value="classpath:com/hkp/mapper/*.xml"/>
        bean>
    
        <bean id="userMapper2" class="com.hkp.mapper.UserMapper2">
            <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    3、编写测试

    @Test
    public void testSpring(){
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-dataSource.xml");
        UserMapper userMapper = context.getBean("userMapper2", UserMapper.class);
        List<User> userList = userMapper.selectUser();
        for (User user: userList) {
            System.out.println(user);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    声明式事务

    声明式事务 :可以在不改变原有的代码,添加事务。

    回顾事务 :

    • 一个业务中的代码,要么都成功,要么都失败!
    • 事务在项目中十分重要
    • 确保完整性和一致性

    事务的 ACID 原则 :

    • 原子性
    • 一致性
    • 隔离性
    • 持久性

    使用事务的步骤

    1、在 applicationContext.xml 中引入事务约束 (tx)

    xmlns:tx="http://www.springframework.org/schema/tx"
    
    
    http://www.springframework.org/schema/tx
    https://www.springframework.org/schema/tx/spring-tx.xsd
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、创建 bean

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

    3、结合AOP 实现事务

    
    
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        
        <tx:attributes>
            <tx:method name="add"/>
            <tx:method name="delete"/>
            <tx:method name="update"/>
            <tx:method name="query"/>
            <tx:method name="*"/>
        tx:attributes>
    tx:advice>
    
    <aop:config>
        <aop:pointcut id="txPoint" expression="execution(* com.hkp.mapper.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
    aop:config>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    4、测试插入和删除代码

    package com.hkp.mapper;
    
    import com.hkp.entity.User;
    import org.apache.ibatis.session.SqlSession;
    import org.mybatis.spring.support.SqlSessionDaoSupport;
    
    import java.util.List;
    
    public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper {
        @Override
        public List<User> selectUser() {
    
            User user = new User("admin","123",1);
            int i = this.addUser(user);
            int i1 = this.deleteUser(22);
    
            SqlSession sqlSession = getSqlSession();
            return sqlSession.getMapper(UserMapper.class).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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
  • 相关阅读:
    Python数据分析实战-实现模型K折交叉验证(附源码和实现效果)
    LCD液晶显示屏常见类型和接口
    Java 多线程
    Mysql 中遇到的坑
    《攻守道》笔记(1)
    程序员都是这样关机的
    常用设计模式
    C语言数据的输入
    Pytorch学习之路 - CNN
    Shader入门精要笔记-屏幕后处理(2)
  • 原文地址:https://blog.csdn.net/weixin_46047612/article/details/126134060