Spring

1.Spring框架

1.spring优点

(1)轻量

  • Spring框架使用的jar都比较小,一般在1M以下或者几百kb。Spring核心功能的所需的jar总共在3M左右。
  • Spring框架运行占用的资源少,运行效率高。不依赖其他jar

(2)针对接口编程,解耦合

  • Spring 提供了loc控制反转,由容器管理对象,对象的依赖关系。原来在程序代码中的对象创建方式,现在由容器完成。对象之间的依赖解耦合。

(3)AOP编程的支持

  • 通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付
  • 在Spring 中,开发人员可以从繁杂的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。

(4)方便集成各种优秀框架

  • spring不排斥各种优秀的开源框架,相反 Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如Struts,Hibernate、MyBatis)等的直接支持。简化框架的使用。Spring像插线板一样,其他框架是插头,可以容易的组合到一起。需要使用哪个框架,就把这个插头放入插线板。不需要可以轻易的移除。

2.IOC理论推导

  • UserDao接口
  • UserDaoImpl实现类
  • UserService业务接口
  • UserServiceImpl业务实现类

3.Spring快速入门

  1. Spring的开发步骤导入坐标

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.16</version>
        </dependency>
    </dependencies>
    
  2. 创建Bean 接口和实体类

    public interface UserDao {
         void save();
    }
    
    import com.kaiyu.dao.UserDao;
    
    public class UserDaoImpl implements UserDao {
        @Override
        public void save() {
            System.out.println("save running........");
        }
    }
    
  3. 创建applicationContext.xml

  4. 在配置文件中进行配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id="userDao" class="com.kaiyu.dao.impl.UserDaoImpl"></bean>
    </beans>
    
  5. 创建ApplicationContext对象getBean

    public static void main(String[] args) {
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) app.getBean("userDao");
        userDao.save();
    }
    

4.Spring配置文件

4.1别名

  • 添加了别名也可以使用别名使用

  • ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
    Student student = (Student) app.getBean("st");
    student.show();
    
<alias name="student" alias="st"></alias>

4.2 Bean标签基本配置

  • 用于配置对象交由Spring来创建。
    默认情况下它调用的是类中的无参构造函数,如果没有无参构造函数则不能创建成功。
  • 基本属性:
    • id: Bean实例在Spring容器中的唯一标识
    • class: Bean的全限定名称
    • name :别名 而且name可以取多个别名

4.3 Bean标签范围配置

scope:指对象的作用范围,取值如下:

取值范围 说明
singleton 默认值,单例的
prototype 多例的
request WEB 项目中,Spring创建一个Bean的对象,将对象存入到request域中
session WEB项目中,Spring创建一个 Bean的对象,将对象存入到session域中
global session
  • 当scope的取值为singleton
    • Bean的实例化个数:1个
    • Bean的实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例
    • Bean的生命周期:
      • 对象创建:当应用加载,创建容器时,对象就被创建了
      • 对象运行:只要容器在,对象一直活着
      • 对象销毁:当应用卸载,销毁容器时,对象就被销毁了
  • 当scope的取值为prototype时
    • Bean的实例化个数:多个
    • Bean的实例化时机:当调用getBean(方法时实例化Bean
      • 对象创建:当使用对象时,创建新的对象实例
      • 对象运行:只要对象在使用中,就一直活着
      • 对象销毁:当对象长时间不用时,被Java的垃圾回收器回收了

4.4、improt

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

4.5 Bean生命周期配置

  • init-method:指定类中的初始化方法名称
  • destroy-method:指定类中销毁方法名称

4.6 Bean的依赖注入概念

依赖注入(DependencyInjection):它是Spring框架核心IOC的具体实现。

在编写程序时,通过控制反转,把对象的创建交给了Spring,但是代码中不可能出现没有依赖的情况。IOC解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。

那这种业务层和持久层的依赖关系,在使用Spring之后,就让Spring来维护了。简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取

3.依赖注入

3.1Set方式注入【重点】

  • ·依赖注入:Set注入!
    。依赖: bean对象的创建依赖于容器!I
    。注入: bean对象中的所有属性,由容器来注入!

    • 复杂对象

      • private String address;
        
        @Override
        public String toString() {
            return "Address{" +
                    "address='" + address + '\'' +
                    '}';
        }
        
        public String getAddress() {
            return address;
        }
        
        public void setAddress(String address) {
            this.address = address;
        }
        
  • 配置注入

    • <bean id="address" class="com.kaiyu.pojo.Address">
              <property name="address" value="长沙"></property>
          </bean>
          <bean id="student" class="com.kaiyu.pojo.Student">
              <!--普通注入-->
              <property name="name" value="张三"></property>
              <!--ref注入-->
              <property name="address" ref="address" ></property>
              <!--数组注入-->
              <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="1564564654654"></entry>
                      <entry key="银行卡" value="797879798"></entry>
                  </map>
              </property>
              <!--set注入-->
              <property name="games">
                  <set>
                      <value>LOL</value>
                      <value>CF</value>
                      <value>CDF</value>
                  </set>
              </property>
              <property name="info">
                  <props>
                      <prop key="学号">2020</prop>
                      <prop key="性别">男</prop>
                      <prop key="姓名">姚开钰</prop>
                  </props>
              </property>
          </bean>
      
  • 真实测试对象

    • ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
      Student student = (Student) app.getBean("student");
      System.out.println(student.getName());
      System.out.println(student.toString());
      

3.2 p标签和c标签

  • p标签和c标签不能直接使用 需要导入xml约束

    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:c="http://www.springframework.org/schema/c"
    
package com.pojo;

public class User {

    private String name;
    private int age;

    public User() {
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       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">

<!--p命名空间注入/set注入-->
<bean id="use" class="com.pojo.User" p:name="丽梅" p:age="10">
</bean>

<!--c命名空间/构造器-->
<bean id="use2" class="com.pojo.User" c:name="开钰" c:age="19"></bean>

</beans>

4.Bean的自动装配

4.1autowire

1.byName自动装配

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

    • <bean id="people" class="com.kaiyu.pojo.People" autowire="byName">
          <property name="name" value="开钰"></property>
      
      </bean>
      
      

2.byType自动装配

  • byType:会自动在容器上下文中查找,和自己属性类型后面的值对应 bean

    • <bean id="people" class="com.kaiyu.pojo.People" autowire="byType">
          <property name="name" value="开钰"></property>
      
      </bean>
      

3.小结

  • byName的时候,需保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致
  • byType的时候,需保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致

4.2使用注解实现自动装配

1.使用须知

1.1导入约束 :context约束

1.2配置注解的支持 context:annotation-config/

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

2.@Autowired

  • @Autowire

    • 在属性上个使用,也可以在set上使用

      我们可以不用编写set方法了前提是这个自动装配的属性在啊IOC(Spring)容器中存在,切符合名字byname!

@Autowired
private Cat cat;
@Autowired
private Dog dog;

private String name;

public Cat getCat() {
    return cat;
}

public Dog getDog() {
    return dog;
}

public String getName() {
    return name;
}

3.@Data

  • 自动生成get set方法

4.@NoArgsConstructor

  • 生成无参构造

5.@AllArgsConstructor

  • 生成有参构造
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Phone {
    private String name;
    private double money;
}
public void phone(){
    ApplicationContext app = new ClassPathXmlApplicationContext("phone.xml");
    Phone phone = app.getBean("phone", Phone.class);
    Phone xm = new Phone("小米", 222);
    System.out.println(xm);
}

5.读取配置文件

5.1.读取properties文件

我们可以让Spring读取properties文件中的key/value,然后使用其中的值。

①设置读取properties

在Spring配置文什中加入如下标签:指定要读取的文件的路径。

<!--读取properties配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

其中的classpath表示类加载路径下。
我们也会用到如下写法: classpath:.properties其中的表示文件名任意。注意: context命名空间的引入是否正确

②使用配置文件中的值

在我们需要使用的时候可以使用${key)来表示具体的值。注意要再value属性中使用才可以。例如:

<bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.Driver}"></property>
    <property name="url" value="${jdbc.url}"></property>
    <property name="username" value="${jdbc.username}"></property>
    <property name="password" value="${jdbc.password}"></property>
</bean>

6.Spring注解开发

6.1Spring原始注解

Spring原始注解主要是替代的配置

注解 说明
@Component 使用在类上用于实例化Bean
@Controller 使用在web层类上用于实例化Bean
@Service 使用在service层类上用于实例化Bean
@Repository 使用在dao层类上用于实例化Bean
@Autowired 使用在字段上用于根据类型依赖注入
@Qualifier 结合@Autowired一起使用用于根据名称进行依赖注入
@Resource 相当于@Autowired+@Qualifier,按照名称进行注入
@Value 注入普通属性
@Scope 标注Bean的作用范围
@PostConstruct 使用在方法上标注该方法是Bean的初始化方法
@PreDestroy 使用在方法上标注该方法是Bean的销毁方法

6.2注意:

使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,作用是指定哪个包及其子包下的Bean需要进行扫描以便识别使用解配置的类、字段和方法。

  • 配置组件扫描
<context:component-scan base-package="com.kaiyu"/>

6.3区别(@Autowired @Qualifier @ Resource)

@Autowired 按照数据类型从Spring容器中进行匹配的
@Qualifier("userDao") 是按照id值从容器中进行匹配的但是主要此处@Qualifier结合@Autowired一起使用

@Resource(name="userDao")// CResource相当于@Qualifier+@Autowired

6.4Spring新注解

注解 说明
@Configuration 用于指定当前类是一个Spring 配置类,当创建容器时会从该类上加载注解
ComponentScan 用于指定Spring在初始化容器时要扫描的包。 作用和在Spring的xml配置文件中的 <context:component-scan base-package="com.itheima"/>一样
Bean 使用在方法上,标注将该方法的返回伯存储到Spring容器中
@PropertySource 用于加载.properties文件中的配置
@lmport 用于导入其他配置类

6.5.小结

xml 与注解:

o xml更加万能,适用于任何场合!维护简单方便。注解不是自己类使用不了,维护相对复杂!xml与注解最佳实践:
o xml用来管理bean;
。 注解只负责完成属性的注入;
。我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持

<!--指定扫描的包,注解才会生效-->
<context:component-scan base-package="com.heima"></context:component-scan>
<context:annotation-config/>

7.代理模式

7.1静态代理

  • 模拟一个简单的代理模式 ---租房

1.代理步骤

1.1接口

//租房
public interface Rent {
    //租房方法
    void rent();
}

1.2真实角色

//房东
public class Host implements Rent{
    @Override
    public void rent() {
        System.out.println("房东出租房子........");
    }
}

1.3.代理角色

public class Proxy implements Rent{
    //房东
    private Host host;

    public Proxy() {
    }

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

    @Override
    public void rent() {
        seeHouse();
        host.rent();
        fee();
        contract();
    }
    //看房子方法
    void seeHouse(){
        System.out.println("中介带你看房子");
    }
    //中介费用
    void fee(){
        System.out.println("支付中介费用");
    }
    //签合同
    void contract(){
        System.out.println("和中介签合同");
    }
}

1.4客户端访问代理角色

public class People {
    public static void main(String[] args) {
        //房东要租房
        Host host = new Host();
        //代理,中介帮房东租房
        Proxy proxy = new Proxy(host);
        //不需要见房东,直接找中介就可
        proxy.rent();
    }
}

2. 代理模式优缺点

2.1代理模式的好处:

  • ·可以使真实角色的操作更加纯粹!不用去关注一些公共的业务·
  • 公共也就就交给代理角色!实现了业务的分工!
  • ·公共业务发生扩展的时候,方便集中管理!

2.2缺点:

  • 一个真实角色就会产生一个代理角色;代码量会翻倍开发效率会变低

7.2加深静态代理

image-20220402103916060

7.2.1.一个增删改查的小案例

  • 接口

    • package com.kaiyu.demo02;
      
      public interface UserService {
          public void add();
          public void delete();
          public void update();
          public void query();
      }
      
  • 真实角色

    • package com.kaiyu.demo02;
      
      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 query() {
              System.out.println("查询了一个用户");
          }
      }
      
  • 代理角色

    • package com.kaiyu.demo02;
      
      public class UserServiceProxy implements UserService{
          private UserService userService;
      
          public UserServiceProxy() {
          }
      
          public UserServiceProxy(UserService userService) {
              this.userService = userService;
          }
      
          @Override
          public void add() {
              log("add");
              userService.add();
          }
      
          @Override
          public void delete() {
              log("delete");
              userService.delete();
          }
      
          @Override
          public void update() {
              log("update");
              userService.update();
          }
      
          @Override
          public void query() {
              log("query");
              userService.query();
          }
          //日志方法
          public void log(String msg ){
              System.out.println("[bug]:使用了"+msg+"方法");
          }
      }
      
  • 客户端调用代理角色

    • package com.kaiyu.demo02;
      
      public class Client {
          public static void main(String[] args) {
              UserServiceImpl userService = new UserServiceImpl();
              UserServiceProxy userServiceProxy = new UserServiceProxy(userService);
              userServiceProxy.add();
              userServiceProxy.delete();
          }
      }
      

7.3动态代理

万能模板

  • public class ProxyInvocationHandler implements InvocationHandler {
        //被代理的接口
        private Object target;
    
        public void setTarget(Object target) {
            this.target = target;
        }
        //生成得到代理类
        public Object getProxy(){
            return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
        }
    	//处理代理实例,并返回结果
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object result = method.invoke(target, args);
            return result;
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            //真实角色
            UserServiceImpl userService = new UserServiceImpl();
            //代理对象  不存在
            ProxyInvocationHandler pih = new ProxyInvocationHandler();
            pih.setTarget(userService);//设置要代理的对象
            //动态生成代理类
            UserService proxy = (UserService) pih.getProxy();
            proxy.add();
            proxy.query();
        }
    }
    

动态代理的好

  • ·可以使真实角色的操作更加纯粹!
  • 不用去关注一些公共的业务·公共也就就交给代理角色!实现了业务的分工!
  • ·公共业务发生扩展的时候,方便集中管理!
  • 。一个动态代理类代理的是一个接口,一般就是对应的一类业务

8.Spring实现Aop

8.1概念

AOP为Aspect oriented Programming的缩写,意为:面向切面编程。他是一种可以在不修改原来的核心代码的情况下给程序动态统—进行增强的一种技术。
SpringAOP:批量对Spring容器中bean的方法做增强,并且这种增强不会与原来方法中的代码耦合。

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

<dependencies>
     <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.16</version>
        </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.9</version>
    </dependency>
</dependencies>

2.相关bean要注入容器中

  • 开启组件扫描

    • <context:component-scan base-package="com.kaiyu"></context:component-scan>
      
  • 加入@Service

    • @Service
      public class UserService {
          public void deleteAll(){
              System.out.println("UserService中deleteAll的核心代码");
          }
      }
      
    • @Service
      public class PhoneService {
          public void deleteAll(){
              System.out.println("PhoneService中的deleteAll的核心代码");
          }
      }
      

3.实现AOP

  • 开启AOP注解

    • xmlns:aop="http://www.springframework.org/schema/aop"
      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
          <!--开启注解支持-->
      <aop:aspectj-autoproxy/>
      
  • 创建切面类

    • 创建一个类,在类上加上@component和@Aspect使用@Pointcut注解来指定要被增强的方法
      使用@Before注解来给我们的增强代码所在的方法进行标识,并且指定了增强代码是在被增强方法执行之前执行的。

4.切点

1.4.1切点表达式

  • 可以使用切点表达式来表示要对哪些方法进行增强。
  • 写法: execution([修饰符]返回值类型包名.类名.方法名(参数))
    • ·访问修饰符可以省略,大部分情况下省略
    • ·返回值类型、包名、类名、方法名可以使用星号* 代表任意
    • ·包名与类名之间一个点.代表当前包下的类,两个点..表示当前包及其子包下的类·
    • 参数列表可以使用两个点..表示任意个数,任意类型的参数列表

1.4.2切点函数@annotation

我们也可以在要增强的方法上加上注解。然后使用@annotation来表示对加了什么注解的方法进行增强。
写法:@annotation(注解的全类名)

  • 定义注解如下 创建一个@annotation
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface InvokeLog {

}
  • 给需要增强的方法加入注解
@Repository
public class UserService {
    @InvokeLog
    public void deleteAll(){
        System.out.println("UserService中deleteAll的核心代码");
    }
}
  • 切面类中使用@annotation来确定要增强的方法
@Component
@Aspect
public class MyAspect{
	//用Pointcut注解中的属性来指定对哪些方法进行增强
    @Pointcut("@annotation(com.kaiyu.Aspect.InvokeLog)")
    public void pt(){

    }
    @Before("pt()")
    public void methodBefore(){
        System.out.println("方法呗调用了");
    }
    @After("pt()")
    public void methodAfter(){
        System.out.println("方法后被调用");
    }
}

1.5通知分类

  • ·@Before:前置通知,在方法执行前执行
  • .@AfterReturning:返回后通知,在目标方法执行后执行,如果出现异常不会执行
  • @After:后置通知,在目标方法返回结果之后执行,无论是否出现异常都会执行·
  • @AfterThrowing:异常通知,在目标方法抛出异常后执行
  • Around:环绕通知,围绕着方法执行

9.Spring整合Mybatis

9.1步骤:

1.导入相关jar包

  • junit
  • mybatis
  • mysql数据库
  • spring相关的
  • aop织入
  • mybatis-spring 【new]

⒉编写配置文件

3.测试

9.2回忆mybatis

1.编写实体类
2.编写核心配置文件

3.编写接口
4.编写Mapper.xml

5.测试

10.整合Mybatis-Spring

1.创建mybatis内容

1.1User实体类

@Data
public class User {
    private int id;
    private String username;
    private String password;
    private int age;
    private String sex;
    private String email;
}

1.2mybatis-config.xml

<configuration>
   <!-- &lt;!&ndash;引入properties-->
    <properties resource="jdbc.properties"/>
    <!--类型别名-->
    <typeAliases>
        <package name="com.kaiyu.mybatis.pojo"/>
    </typeAliases>
</configuration>

1.3 jdbc.properties

jdbc.Driver = com.mysql.cj.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/mybatis
jdbc.username = root
jdbc.password = root

1.4 UserMapper 接口

public interface UserMapper {

    List<User> selectAll();

}

1.5UserMapper.xml

<mapper namespace="com.kaiyu.mybatis.mapper.UserMapper">
<!--List<User> selectAll();-->
    <select id="selectAll" resultType="User">
        select *
        from mybatis.user;
    </select>
</mapper>

1.6 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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation=
               "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="com.kaiyu"></context:component-scan>
    <context:annotation-config></context:annotation-config>

    <!--引入jdbc配置文件-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    <!--DataSource 使用spring的数据源来替代mybatis配置-->
    <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
    <!--SqlSessionFactoryBean-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <!--绑定mybatis-->
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        <!--mapper-->
        <property name="mapperLocations" value="com/kaiyu/mybatis/mapper/UserMapper.xml"></property>
    </bean>
    <!--SqlSessionTemplate:就是我们使用的sqlSession-->
    <bean class="org.mybatis.spring.SqlSessionTemplate" id="sqlSession">
        <!--只能使用构造器注入 因为没有set方法-->
        <constructor-arg index="0" ref="sqlSessionFactoryBean"/>
    </bean>

    <bean class="com.kaiyu.mybatis.mapper.UserMapperImpl">
        <property name="sqlSession" ref="sqlSession"></property>
    </bean>
</beans>

1.7UserMapperImpl 实现接口类

@Repository("userMapper")
public class UserMapperImpl implements UserMapper {
    //我们的所有操作 都是用sqlSession来执行在原来   现在都是用sqlSessionTemplate
    private SqlSessionTemplate sqlSession;

    public UserMapperImpl(SqlSessionTemplate sqlSession) {
        this.sqlSession = sqlSession;
    }

    @Override
    public List<User> selectAll() {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        return mapper.selectAll();
    }


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

    public SqlSessionTemplate getSqlSession() {
        return sqlSession;
    }
}

1.8 测试类

@Test
public void test1(){
    ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
    UserMapper userMapper = app.getBean("userMapper", UserMapper.class);
    for (User user : userMapper.selectAll()) {
        System.out.println(user);
    }
}

11.声明事物

1、回顾事务

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

2.事务ACID原则:

  • 原子性。
  • 一致性·
  • 隔离性
    • 多个业务可能操作同一个资源,防止数据损坏
  • ·持久性
    • 事务一旦提交,无论系统发生什么问题,结果都不会再被影响,被持久化的写到存储器中!
posted @ 2022-04-07 20:07  堆起小码码  阅读(47)  评论(0)    收藏  举报