栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring框架笔记整理(Spring5+maven+IntelliJ IDEA+JDK 1.8 version16)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring框架笔记整理(Spring5+maven+IntelliJ IDEA+JDK 1.8 version16)

1.Spring框架 1.1概述

1.Spring 是轻量级的来源的JavaEE框架

2.Spring 可以解决企业开发的复杂性

3.Spring 有两个核心部分:IOC和AOP

(1)IOC:控制反转,把创建对象的过程交给Spring进行管理

(2)Aop:面向切面,不修改源代码的情况下进行功能增强

4.Spring 特点

(1)方便解耦,简化开发

(2)Aop 编程支持

(3)方便程序测试

(4)方便和其他框架整合

(5)降低api开发难度

(6)方便进行事务操作

5.

官方文档 Spring framework Overview

下载 JFrog


    org.springframework
    spring-webmvc
    5.2.17.RELEASE


    org.springframework
    spring-jdbc
    5.2.17.RELEASE
1.2 组成

 

## 1.3扩展

 

 

  • Spring Boot

    • 一个快速开发的脚手架

    • 基于SpringBoot可以快速的开发单个微服务

    • 约定大于配置

  • Spring Cloud

    • 基于SpringBoot实现的

弊端,Spring发展太久之后,违背了原来的理念,配置十分繁琐

2.IOC 2.1 理解导入

 

首先来看一组代码对比

   private UserDao userDao=new UserDaoOracleImpl();
​
​
    @Override
    public void getUser() {
        userDao.getUser();
    }
    
    test
     UserService userService=new UserServiceImpl();
        
        userService.getUser();
   private UserDao userDao;
​
    //利用set进行动态实现值得注入
    public void setUserDao(UserDao userDao){
        this.userDao=userDao;
    }
    @Override
    public void getUser() {
        userDao.getUser();
    }
    
    test
     UserService userService=new UserServiceImpl();
     ((UserServiceImpl)userService).setUserDao(new UserDaoImpl());
     //((UserServiceImpl)userService).setUserDao(new UserDaoOracleImpl());
     //((UserServiceImpl)userService).setUserDao(new UerDaoMysqlImpl());

之前,程序是主动创建对象

使用set注入后,程序不再具有主动性,而变成了被动的接受对象

系统的耦合性大大降低,是程序员更加专注于业务的实现上

以上是IOC的原型

2.2 IOC 本质

控制反转IOC,是一种设计思想,DI(依赖注入)是实现IOC的一种方法。没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制控制反转后将对象的创建转移给第三方。

控制反转就是一种通过描述(Xml或注解)并通过第三方生产或获取待定对象的方式,在Spring中实现控制反转的是IOC容器,其实现方法是依赖注入。

 

2.3 例子 HelloSpring

1.pojo

package com.yw.pojo;
public class Hello {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void show(){
        System.out.println("Hello,"+ name );
    }
}

2.配置元数据

创建beans.xml



    
    
        
    

其中 id 属性,用于标识单个bean定义

class 属性定义bean的类型并使用完全限定的类名

3.实例化一个容器

提供给ApplicationContext构造函数的一个或多个位置路径是资源字符串,允许容器从各种外部资源(例如本地文件系统、Java 等)加载配置元数据CLASSPATH。

  //获取Spring的上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //我们的对象现在都在Spring中管理了,我们要使用直接去里面取出来就可以
        Hello hello=(Hello) context.getBean("hello");
        hello.show();

输出

Hello,Spring

2.4 IOC创建对象的方式
  1. 使用无参构造方法创建对象,默认

  2. 如果要使用有参构造方法创建对象

    方式一:下标赋值

 
   
 

方式二:通过类型


   
 

方式三:直接通过参数名


   
 

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

3.Spring配置说明 3.1 别名

即重命名,如果添加了别名,我们可以通过别名获取对象

 
3.2 bean配置


    
    
        
    

id :bean的唯一标识符,相当于对象名

class:bean 对象所对应的全限类名:包名+类型

name:也是别名 name="h1 h2,h3;h4 可以命名多个

3.3 import

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

  
4.DI依赖注入 4.1 构造器注入

4.2 Set方式注入【重要】
  • 依赖注入:set注入

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

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

【环境搭配】

  1. 复杂类型

private String address;

    public Address(String address) {
        this.address = address;
    }

    public String getAddress() {
        return address;
    }

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

getseter 省略

public class Student {
    private  String name;
    private Address address;
    private String[] books;
    private List hobbies;
    private Map card;
    private Set games;
    private String wife;
    private Properties info;
  1. beanxml



    
    
    
         
        
        
        

        
        
            
                红楼梦
                西游记
                水浒传
                三国演义
            
        
        
        
            
                听歌
                跑步
                看电影
            
        
        
        
            
                
            
        
        
        
            
                LoL
                COC
                BOB
            
        
        
        
            
        

        
        
            
                2015001
                小米
                rose
            
        
    

  1. 测试类

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
        Student student=(Student) context.getBean("student");
        System.out.println(student.toString());
        
    }
4.3扩展方式注入 带有 p 命名空间的 XML 快捷方式

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

  

带有 c 命名空间的 XML 快捷方式

前提:适用于有参构造器

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

public class User {
    private String name;

    public User() {

    }

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

 

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

4.4.bean Scops 作用域

官网

 

4.4.1 单例 singleton

 

 

配置默认的是单例模式

4.4.2 原型模式 prototype

 

每次从容器get的时候,都会产生一起新的对象

4.4.3 其他

其中 request session application 这些只能在web开发使用到

5.Bean 的自动装配
  • 自动装配是Spring满足bean依赖一种方式

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

在Spring中三种装配方式

  1. 在xml中显示的配置

  2. 在Java中显示配置

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

5.1 测试

实体类

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

xml



    
    
    
    
        


    
5.2 byName自动装配

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

5.3 byType自动装配

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

小结:

  • byName的时候,需要保证所有的bean的i唯一,并且这个备案需要和自动注入的属性的set方法的值一致

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

5.4 使用注解实现自动装配 @Autowired

jdk1.5支持注解,Spring从2.5支持的注解

要使用注解须知

  1. 导入约束 context

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




    

3.代码变化

public class People {
    private String name;
    @Autowired
    private Cat cat;
    @Autowired
    private Dog dog;

xml



    
    
    
    
    

总结:

@Autowired

  • 直接在属性上使用即可,也可以在set方式上使用

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

  • @Qualifier : 如果配置的定义的对象实例有多个,可以使用@Qualifier(value="...")去匹配beanid

  • java 注解 @Resource 会去配置文件中自动匹配,先根据name 再根据类型

@Autowired 和 @Resource 区别

  • 都是用来自动装配的,都可以放在属性字段上

  • @Autowired 通过byType的方式实现,而且必须要求这个对象存在【常用】

  • @Resource 默认通过byname 的方式实现,如果找不到名字,则通过byType实现【常用】

  • 执行顺序不同:

6.使用注解开发 6.1 bean

在Spring4之后开发,必须保证aop的包导入了

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

注解 @Component

例子

xml




    
    
    

bean

//等价于 
@Component  //组件
public class User {
    public String name="tutu";

}

测试

public class MyTest {
    @Test
    public void test1(){
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        User user=(User) context.getBean("user");
        System.out.println(user.name);
    }
}

小结

@Component 组件,放在类上,说明这个类被Spring管理了。

6.2 属性如何注入

使用注解 @Value("")

//等价于 
@Component  //组件
public class User {
    //相当于 
    @Value("tutu")
    public String name;

}

或者

//等价于 
@Component  //组件
public class User {

    public String name;

    //相当于 
    @Value("tutu")
    public void setName(String name) {
        this.name = name;
    }
}

6.3 衍生的注解

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

  • dao [@Repository]

  • service [@Service]

  • controller [@Controller]

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

6.4 自动装配置

@Autowried

6.5 作用域

@Scop("singleton")

@Scop("prototype")

6.6 小结

xml 与 注解 :

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

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

xml 与 注解最佳实践 :

  • xml用来管理bean

  • 注解只负责属性的注入

  • 我们在使用注解,需要开启注解的支持

 
    

7.实现 javaconfig 实现配置

我们现在完全不使用Spring 的 xml 配置了,全权交给java 来做

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

代码说明

实体类

package com.yw.pojo;

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

@Component
public class User {
    @Value("tutu1")
    private String name;

    public String getName() {
        return name;
    }

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

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

配置类

package com.yw.config;

import com.yw.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.import;

//这个也会被Spring托管,注册到容器中,因为它本身就是一个@Component
//@Configuration代表这是一个配置类,就和我们之前看的bean.xml
@Configuration
@ComponentScan("com.yw.pojo")
@import(AppConfig2.class)
public class AppConfig {

    //注册一个bean 就相当于我们之前写的一个bean标签
    //这个方法的名字 就相当于bean标签的id 属性
    //这个方法的返回值 就相当于bean标签的class属性
    @Bean
    public User getUser(){
        return new User();
    }
}

测试

import com.yw.config.AppConfig;
import com.yw.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        //如果完全使用了配置类去做,我们就只能通过AnnotationConfig 上下文获取容器
        ApplicationContext context=new AnnotationConfigApplicationContext(AppConfig.class);
        User user=(User) context.getBean("getUser");
        System.out.println(user.getName());
    }
}

这种纯java的配置方式,在Spring Boot中 随处可见

8.代理模式

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

代理模式的分类:

  • 静态代理

  • 动态代理

8.1 静态代理

角色分析:

  • 抽象角色:一般会使用接口或者抽象类来解决

  • 真实角色:被代理的角色

  • 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作

代码步骤

  1. 接口

//租房
public interface Rent {
    void rent();
}
  1. 真实角色

//房东
public class Host implements Rent{
    @Override
    public void rent() {
        System.out.println("房东要出租");
    }
}
  1. 代理角色

package com.yw.demo1;

//代理
public class Proxy implements Rent{
    private Host host;

    public Proxy(){

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

    @Override
    public void rent() {
        seeHouse();
        host.rent();
        hetong();
        fare();
    }

    //看房
    public void seeHouse() {
        System.out.println("中介带你看房");
    }

    //瘦中介费
    public void fare() {
        System.out.println("中介收费");
    }
    //签租赁合同
    public void hetong() {
        System.out.println("签租赁合同");
    }
}
  1. 客户端访问代理角色

package com.yw.demo1;

public class Client {
    public static void main(String[] args) {
        Host host=new Host();
        //host.rent();
        //代理 中介帮房东租房 但是代理角色一般会有一些附属操作
        Proxy proxy=new Proxy(host);

        //你不用面对房东,直接找中介租房即可
        proxy.rent();
    }
}

代理模式的好处:

  • 可以说使真实角色的操作更加纯粹,不用去关注一些公共的业务

  • 公共业务交给代理角色,实现业务的分工

  • 公共业务发生扩展的时候,方便集中管理

缺点:一个真实角色会产生一个代理角色,代码量会翻倍 开发效率变低

再举一个例子进一步理解

给一个业务新增一个日志记录功能

  1. 接口

public interface UserService {
    void add();
    void delete();
    void update();
    void query();
}
  1. 真实角色

package com.yw.demo2;

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("查询了一个用户");
    }
}
  1. 代理角色

package com.yw.demo2;

public class UserServiceProxy implements UserService{
    USerServiceImpl uSerService;

    public void setuSerService(USerServiceImpl uSerService) {
        this.uSerService = uSerService;
    }

    @Override
    public void add() {
        uSerService.add();
        log("add");
    }

    @Override
    public void delete() {
        uSerService.delete();
        log("delete");
    }

    @Override
    public void update() {
        uSerService.update();
        log("update");
    }

    @Override
    public void query() {
        uSerService.query();
        log("query");
    }

    //日志方法
    public void log(String msg){
        System.out.println("[loging]使用了"+msg+"方法");
    }
}
  1. 客户端访问代理角色

package com.yw.demo2;

public class Client {
    public static void main(String[] args) {
        USerServiceImpl userService=new USerServiceImpl();
        UserServiceProxy proxy=new UserServiceProxy();
        proxy.setuSerService(userService);
        proxy.add();
    }
}
增加了一个用户
[loging]使用了add方法
8.2 动态代理
  • 动态代理和静态代理角色一样

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

  • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理

    • 基于接口---JDK动态代理

    • 基于类:cglib

    • java字节码实现:javassist

需要了解两个类

  • Proxy

  • InvocationHandler 代理实例处理程序

代码理解 举例1:

  1. 接口

//租房
public interface Rent {
    void rent();
}
  1. 真实角色

//房东
public class Host implements Rent{
    @Override
    public void rent() {
        System.out.println("房东要出租");
    }
}
  1. 代理处理程序 实现了接口InvocationHandler

package com.yw.demo3;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//自动生成代理类
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 );
    }

    //处理代理实例,并返回结果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //动态代理的本质,就是反射机制体现
        Object result=method.invoke(rent,args);
        return result;
    }
}
  1. 客户端访问代理角色

package com.yw.demo3;

public class Client {
    public static void main(String[] args) {
        //真实角色
        Host host=new Host();

        //代理角色 :现在没有
        ProxyInvocationHandler pih=new ProxyInvocationHandler();
        //通过调用程序处理来处理我们要调用的接口对象
        pih.setRent(host);

        Rent proxy=(Rent) pih.getProxy();
        proxy.rent();
    }
}

举例2:

  1. 接口

package com.yw.demo4;

public interface UserService {
    void add();
    void delete();
    void update();
    void query();
}
  1. 真实角色

package com.yw.demo4;

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("查询了一个用户");
    }
}
  1. 动态代理处理程序

package com.yw.demo4;

import com.yw.demo3.Rent;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//自动生成代理类
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 {
        //动态代理的本质,就是反射机制体现
        log(method.getName());
        Object result=method.invoke(target,args);
        return result;
    }

    //日志方法
    public void log(String msg){
        System.out.println("[loging]使用了"+msg+"方法");
    }
}
  1. 客户端访问代理角色

package com.yw.demo4;

public class Clent {
    public static void main(String[] args) {
        UserService userService=new USerServiceImpl();

        //代理角色
        ProxyInvocationHandler pih=new ProxyInvocationHandler();

        pih.setTarget(userService);
        UserService proxy=(UserService) pih.getProxy();
        proxy.add();
    }
}
结果:
[loging]使用了add方法
增加了一个用户

总结

动态代理的好处:

  • 一个动态代理类代理的是一个接口,一般就是对应的一类业务

  • 一个动态代理类可以代理多个类,只要实现同一个接口即可

9.AOP 9.1 什么是AOP

面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术

 

9.2 AOP在Spring中的作用

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

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

  • 切面(ASPECT):切面关注点被模块化的特殊时期。即,他是一个类

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

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

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

  • 切入点(PointCut):切面通知执行的地点定义

  • 连接点(Joint Point):与切入点匹配的执行点

  •  

Spring中支持的5种类型的Advice

 

即AOP在不改变原有的 代码下,去增加新的功能

9.3 使用Spring实现AOP 9.3.1 方法一:使用Spring 的API 接口

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

     xmlns:aop="http://www.springframework.org/schema/aop"
         
     http://www.springframework.org/schema/aop
     https://www.springframework.org/schema/aop/spring-aop.xsd">  

实现增加日志功能

接口

package com.yw.service;

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

实现类

package com.yw.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 query() {
        System.out.println("查询了一个用户");
    }
}

log 类

package com.yw.log;

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class Log implements MethodBeforeAdvice {
    
    @Override
    public void before(Method method, Object[] objects, Object target) throws Throwable {
        System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了");
    }
}

配置文件

package com.yw.log;

import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;

public class AfterLog implements AfterReturningAdvice {
    
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("执行了"+method.getName()+"方法。返回结果为:"+returnValue);
    }
}

测试

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService uSerService=(UserService)context.getBean("userService");
        uSerService.add();
    }
}

结果
com.yw.service.USerServiceImpl的add被执行了
增加了一个用户
执行了add方法。返回结果为:null

9.3.2 方法二 : 使用自定义类实现

自定义类

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

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

配置文件

    

    

        

            

            
            
        
    

测试结果

=========方法执行前=======
增加了一个用户
=========方法执行后=======
9.2.3 方法三:使用注解方式

切面类

package com.yw.anno;

//使用注解方式实现AOP

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect //标注这个类是切面
public class AnnotationPointCut {

    @Before("execution(* com.yw.service.USerServiceImpl.*(..))")
    public void before(){
        System.out.println("=========方法执行前=======");
    }

    @After("execution(* com.yw.service.USerServiceImpl.*(..))")
    public void after(){
        System.out.println("=========方法执行后=======");
    }

    //在环绕增强中,我们可以给定一个参数,代表我们需要获取处理切入的点
    @Around("execution(* com.yw.service.USerServiceImpl.*(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕前");
        //执行方法
        System.out.println(proceedingJoinPoint.getSignature());
        Object proceed=proceedingJoinPoint.proceed();
        System.out.println("环绕后");
    }
}

配置文件

    

    

结果

环绕前
void com.yw.service.UserService.delete()
=========方法执行前=======
删除了一个用户
=========方法执行后=======
环绕后
10 整合 Mybatis

步骤:

  1. 导入相关jar包

    • junit

    • mybatis

    • mysql

    • spring

    • aop

    • mybatis-spring[new] mybatis-spring –

    
    
        
            spring-study
            org.example
            1.0-SNAPSHOT
        
        4.0.0
    
        spring-09-mybatis
    
        
            1.8
            1.8
        
    
        
            
                junit
                junit
                4.12
                test
            
            
                mysql
                mysql-connector-java
                5.1.47
            
            
                org.mybatis
                mybatis
                3.5.2
            
            
                org.springframework
                spring-webmvc
                5.1.9.RELEASE
            
            
                org.springframework
                spring-jdbc
                5.1.9.RELEASE
            
            
                org.aspectj
                aspectjweaver
                1.8.13
            
            
                org.mybatis
                mybatis-spring
                2.0.2
            
            
                org.projectlombok
                lombok
                1.18.22
            
        
    
        
            
                
                    src/main/java
                    
                        **/*.xml
                    
                
            
        
    
    

  2. 编写配置文件

    1. mybatis-config.xml

    
    
    
        
            
        
        
            
                
                
                    
                    
                    
                    
                
            
        
        
            
        
    
  3.  

    实体类

    import lombok.Data;
    
    @Data
    public class User {
        private int id;
        private String name;
        private String pwd;

    mapper

    public interface UserMapper {
        List userList();
    }

    UserMapper.xml

    
    
    
        
            select * from mybatis.user;
        
    ​
        
            insert into mybatis.user (id,name,pwd) values (#{id},#{name},#{pwd});
        
    ​
        
            delete from mybatis.user where id=#{id}
        
    

    加入故意将其中删除用户的sql 写错,测试运行结果会报错

    数据库原有数据:

     

     

    再次查询数据库查看列表如下:

     

    会发现即使程序报错,仍然将数据插入到表中了

    所以这时候我们可以使用到事务解决该问题了

    11.2 mybatis-spring 中 Transactions
    • 声明式事务:AOP

    • 编程式事务 在源代码上改动

    要启用 Spring 事务处理,只需DataSourceTransactionManager在 Spring 配置文件中创建一个:

       
            
        
        

    了解

     

    根据11.2 代码 需要 在 spring 中加入事务的管理

    spring-dao.xml

    
    
    ​
    ​
    
        
            
            
            
            
        
        
        
            
    
            
            
        
    ​
    
    
    
    
    ​
    
        
            
        
    ​
        
    
    
            
                
                
                
                
                
            
        
    ​
    
        
            
            
        
    
    ​
    ​
    ​
    ​说明:该笔记通过该网址【狂神说Java】Spring5最新完整教程IDEA版通俗易懂_哔哩哔哩_bilibili

    视频课程,所总结的学习笔记,有兴趣的可以去看视频学习!!!!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/322349.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号