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

Spring5 框架

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

Spring5 框架

Spring5 框架 一、Spring概述
  1. Spring是轻量级的开源的JavaEE框架。
  2. Spring可以解决企业应用开发的复杂性。
  3. Spring有两个核心部分:IOC和AOP。
    • IOC:控制反转,把创建对象过程交给Spring进行管理。
    • AOP:面向切面编程,不修改源代码的情况下进行功能增强。
  4. Spring特点
    • 方面解耦,简化开发
    • AOP编程支持
    • 方便程序的测试
    • 可以方便和其他框架进行整合
    • 方便进行事务操作
    • 降低API开发难度
二、IOC容器 1、IOC的概述
  • 什么是IOC:控制反转,把对象创建和对象之间的调用过程交给Spring进行管理。
  • 使用IOC的目的:为了降低耦合度。
2、IOC底层原理
  • xml解析、工厂模式、反射


3、IOC接口(BeanFactory)
  • IOC思想基于IOC容器完成,IOC容器底层就是对象工厂。
  • Spring提供IOC容器实现的两种方式(两个接口)
    • BeanFactory:IOC容器基本实现,是Spring内部的使用接口,不提供开发人员进行使用
    • ApplicationContext:接口的子接口,提供更多更强大的功能,一般由开发人员进行使用
    • 区别:BeanFactory在加载配置文件时不会创建对象,在获取对象(使用)才去创建对象;ApplicationContext在加载配置文件时就会把配置文件中的对象进行创建。
  • BeanFactory接口主要实现类
    • FileSystemXmlApplicationContext:配置文件需要用系统路径(绝对路径)
    • ClassPathXmlApplicationContext:配置文件使用相对路径
4、IOC操作:Bean管理(基于xml方式 和 基于注解方式)
  • 什么是Bean管理?

    • Spring创建对象
    • Spring注入属性
  • Bean管理操作有两种方式

    • 基于xml配置文件方式实现
    • 基于注解方式实现
  • 基于xml方式

    • 创建对象

      在spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建

      
      
      

      在bean标签中有很多属性,常用的属性有:id(唯一标识);class(类全路径或包类路径);

      创建对象时,默认也是执行无参构造方法

    • 注入属性

      • DI:依赖注入,就是注入属性。DI是IOC的一种具体实现;注入属性必须在创建完对象的基础上。
    • 两种注入方式:set方法和有参构造方法。

      • 第一种:set方法注入

        • 创建类,定义属性和对应的set方法
        public class Book{
        	private String bname;
        	private String bauthor;
        	
        	public void setBname(String bname){
        		this.bname = bname;
        	}
        	
        	public void setBauthor(String bauthor){
        		this.bauthor = bauthor;
        	}
        }
        
        • 在Spring配置文件中配置对象创建,配置属性注入
        
        
        
        
        
        	
            
            
        
        
      • 第二种:基于有参构造方法注入

        • 创建类,定义属性,创建属性对应有参构造方法

        • public class Orders{
              private String oname;
              private String address;
              
              public Orders(String oname, String address){
                  this.oname = oname;
                  this.address = address;
              }
              
              public void orderTest(){
                  System.out.println(oname+"::"+address)
              }
          }
          
        • 在Spring配置文件中进行配置

        
        
            
            
        
        
        • 测试
        @Test
        public void testOrders(){
            //1、加载spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
            //2、获取配置创建的对象
            Orders orders = context.getBean("orders",Orders.class);
            
            System.out.println(orders);
            orders.orderest();
        }
        
    • xml注入其他类型属性

      • 字面量:是用于源代码中一个固定值的表示法

        • null值
        
        	
        
        
        • 属性值包含特殊符号
        
        
        
        
        	      
        
        
      • 注入属性-外部Bean

        • 创建两个类service类和dao类
        
            
                
                
            
            
        
        • 在service中调用dao里面的方法
        public class UserService {
        
            //创建UserDao类型属性,生成set方法
            private UserDao userDao;
        
            public void setUserDao(UserDao userDao) {
                this.userDao = userDao;
            }
        
            public void add(){
                System.out.println("service add.....");
                userDao.update();
            }
        }
        
        public class UserDaoImpl implements UserDao{
            @Override
            public void update() {
                System.out.println("dao update....");
            }
        }
        
        public class Test_02 {
           @Test
            public void test(){
               //使用ApplicationContext加载配置文件
               ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
               //创建service对象
               UserService userService = context.getBean("userService", UserService.class);
               //调用User中的方法
               userService.add();
           }
        }
        
      • 注入属性-内部Bean和级联赋值

        • 内部Bean
        //部门类
        public class Dept {
            private String dname;
        
            public void setDname(String dname) {
                this.dname = dname;
            }
            
            @Override
            public String toString() {
                return "Dept{" +
                        "dname='" + dname + ''' +
                        '}';
            }
        }
        
        //员工类
        public class Emp {
            private String ename;
            private String gender;
            private Dept dept;          //员工所属部门
        
            public void setEname(String ename) {
                this.ename = ename;
            }
        
            public void setGender(String gender) {
                this.gender = gender;
            }
        
            public void setDept(Dept dept) {
                this.dept = dept;
            }
        }
        
        
        
        
            
            
            
            
                
                    
                
            
        
        
        //测试
        @Test
           public void test2(){
              //使用ApplicationContext加载配置文件
              ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
              //创建service对象
              Emp emp = context.getBean("emp", Emp.class);
              //调用User中的方法
              emp.print();
           }
        
        //输出结果
        //张曼玉 女 Dept{dname='演艺部'}
        
        • 级联赋值
        
        
            
            
            
        
        
            
        
        
        
        
            
            
            
            
            
        	
            
        
        
            
        
        
    • xml注入集合属性

      
          
              
              
                  
                      java面向对象程序设计
                      数据库设计
                      Spring5
                  
              
      
              
              
                  
                      张三
                      李四
                      王麻子
                  
              
      
              
              
                  
                      
                      
                  
              
      
              
              
                  
                      嘿嘿
                      哈哈
                      呵呵
                  
              
          
      
      //学生类
      public class Stu {
          private String[] courses;
      
          private List list;
      
          private Map maps;
      
          private Set sets;
      
          public void setCourses(String[] courses) {
              this.courses = courses;
          }
      
          public void setList(List list) {
              this.list = list;
          }
      
          public void setMaps(Map maps) {
              this.maps = maps;
          }
      
          public void setSets(Set sets) {
              this.sets = sets;
          }
      
          @Override
          public String toString() {
              return "Stu{" +
                      "courses=" + Arrays.toString(courses) +
                      ", list=" + list +
                      ", maps=" + maps +
                      ", sets=" + sets +
                      '}';
          }
      }
      
      //测试
      public class Test {
          public static void main(String[] args) {
              ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
              Stu stu = context.getBean("stu", Stu.class);
              System.out.println(stu);
          }
      }
      //输出结果
      //Stu{courses=[java面向对象程序设计, 数据库设计, Spring5], list=[张三, 李四, 王麻子], maps={JAVA=java, PHP=php}, sets=[嘿嘿, 哈哈, 呵呵]}
      
    • 在集合里面设置对象类型值

    • 把集合注入部分提取出来

  • Bean管理(FactoryBean)

    • Spring有两种Bean,一种普通Bean,另一种工厂bean(FactoryBean)
    • 普通Bean:配置文件中定义什么类型就返回什么类型
    • 工厂Bean:配置文件中定义类型和返回类型可以不一致
    public class MyBean implements FactoryBean {
    
        @Override
        public Stu getObject() throws Exception {
            Stu stu = new Stu();
            stu.setCourses(new String[]{"java","spring5"});
            return stu;
        }
    
        @Override
        public Class getObjectType() {
            return null;
        }
    
        @Override
        public boolean isSingleton() {
            return false;
        }
    }
    
    
    
    • Bean的作用域

      • 在spring里面,可以设置bean实例是单实例还是多实例(使用scope:singleton、prototype、request、session)。singleton和prototype的区别:1、singleton为单实例,加载配置文件时就会创建对象。2、prototype为多实例,加载的时候并不创建对象,而是在调用getBean()方法时创建多实例对象。
      • 在spring里面,默认情况下,bean是单实例对象
      //地址相同,说明stu1和stu2是同一个实例化对象
      ApplicationContext context = new ClassPathXmlApplicationContext("spring-config2.xml");
              Stu stu1 = context.getBean("stu", Stu.class);
              Stu stu2 = context.getBean("stu", Stu.class);
              System.out.println(stu1);
              System.out.println(stu2);
      
      //输出结果
      //com.atguigu.spring5.collectiontype.Stu@1e66f1f5
      //com.atguigu.spring5.collectiontype.Stu@1e66f1f5
      
    • Bean管理的生命周期:bean从创建到销毁的过程

      • 创建bean实例——>为bean的属性设置值和对其他bean引用(set方法)——>调用bean的初始化的方法(需要进行配置)——>使用——>当容器关闭时,调用bean的销毁方法(需要进行配置)
      • 添加后置处理器后变为7步:创建bean实例——>为bean的属性设置值和对其他bean引用(set方法)——>初始化前执行的方法——>调用bean的初始化的方法(需要进行配置)——>初始化后执行的方法——>使用——>当容器关闭时,调用bean的销毁方法(需要进行配置)
    • xml自动装配(很少使用)

      • 根据指定装配规则(属性名或者属性类型),Spring自动将匹配的属性值注入
      
                                                                        
      
  • 基于注解方式

    • 什么是注解?注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值…);注解可以作用在类、方法、属性上面。使用注解的目的:简化xml配置。

    • spring针对Bean管理中创建对象提供注解

      • @Component
      • @Service
      • @controller
      • @Repository

      以上四个注解功能都是一样的,都可以用来创建bean实例。

      
      
      
      
      
          
          
      
      
      //UserService类
      //在注解里面value属性值可以不写,默认值是类名称,首字母小写
      @Component(value="userService")     //相当于public class UserService {
          public void add(){
              System.out.println("service add...");
          }
      }
      
      //测试类
      public class TestDemo {
      
          @Test
          public void testService(){
              //加载配置文件
              ApplicationContext context =
                      new ClassPathXmlApplicationContext("spring-config2.xml");
              UserService userService = context.getBean("userService", UserService.class);
              userService.add();
              System.out.println(userService);
          }
      }
      
    • 基于注解方式实现属性注入

      • @AutoWired:根据属性类型自动装配
      • @Qualifier:根据属性名称进行注入,和@AutoWired一起使用
      • @Resource:可以根据类型注入,也可以根据名称注入
      • @Value:注入普通类型属性
    • 完全注解开发

      • 创建配置类,替代xml配置文件
      @Configuration        //将当前类作为配置类,替代xml文件
      @ComponentScan(basePackages = "com.atguigu")     //开启组件扫描
      public class SpringConfig {
      
      }
      
      • 测试类(与之前有所不同)
      public void Test02(){
              //加载配置类  AnnotationConfigApplicationContext
              ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
      
              //创建对象
              UserService userService = context.getBean("userService", UserService.class);
      
              //调用方法
              System.out.println(userService);
              userService.add();
          }
      
三、AOP 1、概述
  • 什么是AOP?面向切面编程,是OOP的一种延续,是软件开发的一个热点。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间耦合度降低,提高程序的可重用性,同时提高开发效率。

2、底层原理
  • 动态代理

    • 有两种情况动态代理:(1)有接口情况,使用JDK动态代理(2)没有接口情况,使用CGLIB动态代理

      //JDK动态代理
      
      

      首先定义一个People接口

      package reflect;
      
      public interface People {
      
          public String work();
      }
      

      定义一个Teacher类,该类实现People接口

      package reflect;
      
      public class Teacher implements People{
      
          @Override
          public String work() {
              System.out.println("老师教书育人...");
              return "教书";
          }
      
      }
      

      现在我们要定义一个代理类的调用处理程序,每个代理类的调用处理程序都必须实现InvocationHandler接口,代理类如下:

      package reflect;
      
      import java.lang.reflect.InvocationHandler;
      import java.lang.reflect.Method;
      
      public class WorkHandler implements InvocationHandler{
      
          //代理类中的真实对象  
          private Object obj;
      
          public WorkHandler() {
              // TODO Auto-generated constructor stub
          }
          //构造函数,给我们的真实对象赋值
          public WorkHandler(Object obj) {
              this.obj = obj;
          }
      
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              //在真实的对象执行之前我们可以添加自己的操作
              System.out.println("before invoke。。。");
              Object invoke = method.invoke(obj, args);
              //在真实的对象执行之后我们可以添加自己的操作
              System.out.println("after invoke。。。");
              return invoke;
          }
      
      }
      

      接下来我们看下客户端类

      package reflect;
      
      import java.lang.reflect.InvocationHandler;
      import java.lang.reflect.Proxy;
      
      public class Test {
      
          public static void main(String[] args) {
              //要代理的真实对象
              People people = new Teacher();
              //代理对象的调用处理程序,我们将要代理的真实对象传入代理对象的调用处理的构造函数中,最终代理对象的调用处理程序会调用真实对象的方法
              InvocationHandler handler = new WorkHandler(people);
              
              People proxy = (People)Proxy.newProxyInstance(handler.getClass().getClassLoader(), people.getClass().getInterfaces(), handler);
              //System.out.println(proxy.toString());
              System.out.println(proxy.work());
          }
      }
      

      看下输出结果:

      before invoke。。。
      老师教书育人...
      after invoke。。。
      教书
      
3、AOP术语
  • Advice (增强/通知)实际增强的逻辑部分成为通知(增强);通知分为(前置通知@Before、后置通知@AfterReturning、环绕通知@Around、异常通知@AferThrowing、最终通知@After)。如果有异常,AfterReturning就不执行;AfterReturning在返回值之后执行。
  • JoinPoint (连接点) 表示允许使用增强的地方。基本每个方法的前、后或异常等都是连接点。
  • Pointcut (切入点) 表示实际增强的方法。
  • Aspect (切面) 表示扩展功能的过程。
  • Introduction( 引入) 表示向现有的类中添加新方法、新属性。
  • Target (目标对象) 表示被增强的对象。
  • Proxy (代理) 表示实现AOP的机制。
  • Weaving (织入) 表示把增强应用到目标对象的过程。
4、AOP操作
  • 切入点表达式

    语法结构:execution([权限修饰符] [返回类型] [类全路径] [方法名称] ([参数列表]))

    举例1:对com.atguigu.dao.BookDao类里面的add进行增强
    execution(* int com.atguigu.dao.BookDao.add(..))
    
    举例2:对com.atguigu.dao.BookDao类里面的所有方法进行增强
    execution(* com.atguiug.dao.BookDao.*(..))
    
    举例3:对com.atguigu.dao包里面所有类,类里面所有方法进行增强
    execution(* com.atguigu.dao.*.*(..))
    
  • AspectJ注解

    //1.创建类,在类里面定义方法
    public class User {
        public void add(){
            System.out.println("add ....");
        }
    }
    //2、编写增强逻辑
    @Component
    @Aspect
    public class UserProxy {
        //前置通知
        @Before(value = "execution(* com.atguigu.spring5.aop.User.add(..))")   //增强add()方法
        public void before(){
            System.out.println("before ...");
        }
    
        //后置通知
        @AfterReturning(value = "execution(* com.atguigu.spring5.aop.User.add(..))")
        public void afterReturning(){
            System.out.println("afterReturning...");
        }
    
        //环绕通知--------需要ProceedingJoinPoint类型参数
        @Around(value = "execution(* com.atguigu.spring5.aop.User.add(..))")
        public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            //环绕之前
            System.out.println("环绕之前...");
    
            //被增强的方法
            proceedingJoinPoint.proceed();
    
            //环绕之后
            System.out.println("环绕之后...");
        }
    
        //最终通知
        @After(value = "execution(* com.atguigu.spring5.aop.User.add(..))")
        public void after(){
            System.out.println("after...");
        }
    
        //异常通知
        @AfterThrowing(value = "execution(* com.atguigu.spring5.aop.User.add(..))")
        public void afterThrowing(){
            System.out.println("afterThrowing...");
        }
    }
    
    //3、进行通知的配置
    
    
    
    
        
        
        
        
    
    
    

    测试类

    public class TestAop {
        public static void main(String[] args) {
            ApplicationContext context =
                    new ClassPathXmlApplicationContext("spring-config.xml");
            User user = context.getBean("user", User.class);
            user.add();
        }
    }
    

    输出结果

    环绕之前...
    before ...
    add ....
    环绕之后...
    after...
    afterReturning...
    
  • AspectJ配置文件(使用较少)

四、JDBCTemplate 1、概念

​ spring对JDBC进行了封装,JDBCTemplate方便实现对数据库的操作。

2、准备工作
  • 引入相关jar包

    mysql-connector-java-5.1.37-bin.jar (需要与数据库版本相匹配,否则会报错)

    spring-jdbc-5.2.3.RELEASE.jar

    spring-orm-5.2.3.RELEASE.jar

    spring-tx-5.2.3.RELEASE.jar

    druid-1.2.8.jar(德鲁伊数据库连接池)

  • 在spring配置文件中配置数据库连接池

    
        
        
        
        
    
    
  • 配置jdbcTemplate对象,注入DataSource

    
    
        
        
    
    
  • 创建service类,创建dao类,在service中注入到,dao中注入jdbcTemplate

    service类

    @Service
    public class BookService {
        //注入bookdao
        @Autowired
        private BookDao bookDao;
    }
    

    BookDao接口

    public interface BookDao {
    }
    

    BookDaoImple类实现BookDao

    @Repository
    public class BookDaoImpl implements BookDao{
        //注入jdbcTemplate
        @Autowired
        private JdbcTemplate jdbcTemplate;
    }
    

    spring相关配置

        
            
            
            
            
        
    
        
        
            
            
        
    
  • jdbcTemplate操作数据库

    • 创建数据库中实体类

      public class Book {
          private int id;
          private String bookname;
          private String author;
          private String publish;
          private String isbn;
          private float price;
          private String bookresume;
          private String publishdate;
      
          public Book(){
              super();
          }
          public Book(int id, String bookname, String author, String publish, String isbn, float price, String bookresume, String publishdate) {
              this.id = id;
              this.bookname = bookname;
              this.author = author;
              this.publish = publish;
              this.isbn = isbn;
              this.price = price;
              this.bookresume = bookresume;
              this.publishdate = publishdate;
          }
      
          public int getId() {
              return id;
          }
      
          public void setId(int id) {
              this.id = id;
          }
      
          public String getBookname() {
              return bookname;
          }
      
          public void setBookname(String bookname) {
              this.bookname = bookname;
          }
      
          public String getAuthor() {
              return author;
          }
      
          public void setAuthor(String author) {
              this.author = author;
          }
      
          public String getPublish() {
              return publish;
          }
      
          public void setPublish(String publish) {
              this.publish = publish;
          }
      
          public String getIsbn() {
              return isbn;
          }
      
          public void setIsbn(String isbn) {
              this.isbn = isbn;
          }
      
          public float getPrice() {
              return price;
          }
      
          public void setPrice(float price) {
              this.price = price;
          }
      
          public String getBookresume() {
              return bookresume;
          }
      
          public void setBookresume(String bookresume) {
              this.bookresume = bookresume;
          }
      
          public String getPublishdate() {
              return publishdate;
          }
      
          public void setPublishdate(String publishdate) {
              this.publishdate = publishdate;
          }
      
          @Override
          public String toString() {
              return "Book{" +
                      "id=" + id +
                      ", bookname='" + bookname + ''' +
                      ", author='" + author + ''' +
                      ", publish='" + publish + ''' +
                      ", isbn='" + isbn + ''' +
                      ", price=" + price +
                      ", bookresume='" + bookresume + ''' +
                      ", publishdate='" + publishdate + ''' +
                      '}';
          }
      }
      
      
    • 编写service和dao

      BookService最终实现

      @Service
      public class BookService {
          //注入bookdao
          @Autowired
          private BookDao bookDao;
      
          //添加
          public void addBook(Book books){
              bookDao.add(books);
          }
      
          //修改
          public void updateBook(){
              bookDao.updateBook();
          }
      
          //删除
          public void deleteBook(int id){
              bookDao.deleteBook(id);
          }
      
          //查询单个值
          public void findCount(){
              bookDao.findCount();
          }
      
          //查询返回一个对象类型
          public Book findBookDetail(int id){
              return bookDao.findBookDetail(id);
          }
      
          //查询返回一个集合
          public List findAllBook(){
              return bookDao.findAllBook();
          }
      }
      
      

      BookDao接口

      public interface BookDao {
          //添加
          void add(Book book);
      
          //查找
          void query(Book book);
      
          //修改
          void updateBook();
      
          //删除
          void deleteBook(int id);
      
          //查询表记录数
          void findCount();
      
          //查询某本书详情,返回该书本对象
          Book findBookDetail(int id);
      
          List findAllBook();
      }
      
      

      BookDaoImpl实现类

      @Repository
      public class BookDaoImpl implements BookDao{
          //注入jdbcTemplate
          @Autowired
          private JdbcTemplate jdbcTemplate;
      
          //添加
          @Override
          public void add(Book book) {
              int id = book.getId();
              String bookname = book.getBookname();
              String author = book.getAuthor();
              String isbn = book.getIsbn();
              String publish = book.getPublish();
              float price = book.getPrice();
              String bookresume = book.getBookresume();
              String publishdate = book.getPublishdate();
              //创建sql语句
              String sql = "insert into books values (?,?,?,?,?,?,?,?)";
              int update = jdbcTemplate.update(sql, id, bookname, author, publish,
                      isbn, price, bookresume, publishdate);
              System.out.println(update);
          }
      
          @Override
          public void query(Book book) {
              int id = book.getId();
              String bookname = book.getBookname();
              String author = book.getAuthor();
              String isbn = book.getIsbn();
              String publish = book.getPublish();
              float price = book.getPrice();
              String bookresume = book.getBookresume();
              String publishdate = book.getPublishdate();
      
              //创建sql语句
              String sql = "selct * from books";
      
      
          }
      
          //修改
          @Override
          public void updateBook() {
              String sql = "update books set bookname = ? where id = ?";
              int update = jdbcTemplate.update(sql, "神雕侠侣", 9);
              System.out.println("总共"+update+"受影响");
          }
      
          //删除
          @Override
          public void deleteBook(int id) {
              String sql = "delete from books where id = ?";
              int update = jdbcTemplate.update(sql, 9);
              System.out.println("共删除"+update+"行记录");
          }
      
          //查询表记录数
      
          @Override
          public void findCount() {
              String sql = "select count(*) from books";
              Integer count = jdbcTemplate.queryForObject(sql, Integer.class);
              System.out.println("books表中共有"+count+"条记录");
          }
      
          //查询书本详情
          @Override
          public Book findBookDetail(int id) {
              String sql = "select * from books where id = ?";
              Book book = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper(Book.class), id);
              return book;
          }
      
          //查询Book集合
      
          @Override
          public List findAllBook() {
              String sql = "select * from books";
              List books = jdbcTemplate.query(sql, new BeanPropertyRowMapper(Book.class));
              return books;
          }
      }
      
      

      测试类

      import java.util.Iterator;
      import java.util.List;
      
      public class Testjdbc {
          public static void main(String[] args) {
              ApplicationContext context = 
                      new ClassPathXmlApplicationContext("spring-config.xml");
              BookService bookService = context.getBean("bookService", BookService.class);
      
              //添加元素
              Book book1 = new Book(9, "九阴真经", "无名氏", "机械工业出版社",
                      "12345678", 23.6f, "作者很懒,没有简介", "1998-07");
      //        bookService.addBook(book);    //增
      //        bookService.updateBook();     //改
      //        bookService.deleteBook(9);    //删
      //        bookService.findCount();        //查    返回单个值
      
              //返回一个book对象      --Book类需要有无参构造方法,否则报错
      //        Book book2 = bookService.findBookDetail(8);
      //        System.out.println(book2);
      
              //返回List
              List allBook = bookService.findAllBook();
              Iterator iterator = allBook.iterator();
              while(iterator.hasNext())
                  System.out.println(iterator.next());
      
          }
      }
      
      

      测试结果

      添加:

      修改:

      删除:

      查找:单个返回值

      查找:返回book对象

    查找:返回集合

五、事务管理 1、概念

​ 什么是事务?事务是数据库操作的最基本单元,逻辑上的一组操作,该操作要么都执行,要么不执行。

2、事务的四个特性(ACID)
  • 原子性:操作要么全部执行,要么都不执行
  • 一致性:操作前和操作后的状态保持一致(例如银行转账前和转账后的总钱数是相同的)
  • 隔离性:不同事务的操作互不影响
  • 持久性:事务提交之后的改变是永久的
3、事务操作
  • 事务通常添加到Service层

  • spring中有两种方式进行事务管理:编程式事务管理(了解)和声明式事务管理(使用)

    • 声明事务管理:基于注解方式(常用)和基于xml配置文件方式
    • 声明事务管理底层使用了AOP原理
  • 事务操作

    • 1、在spring配置文件中配置事务管理器

      
      
          
          
      
      
    • 配置开启事务注解

      先引入命名空间tx

      
      

      开启事务注解

      
      
      

      在service类上面(或者里面的方法上面)添加事务注解**@Transactional**

      如果注解添加在类上面,那么类里面的所有方法都添加事务;如果注解添加到方法上面,那么只有该方法添加事务。

      事务注解中的参数设置

      1、**propagation:**事务传播行为。多事务方法间直接进行调用,这个过程中事务是如何进行管理的。

      ​ spring定义了7种传播行为:

      传播属性描述
      REQUIRED支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
      SUPPORTS支持当前事务,如果当前没有事务,就以非事务方式执行。
      MANDATORY支持当前事务,如果当前没有事务,就抛出异常。
      REQUIRES_NEW新建事务,如果当前存在事务,把当前事务挂起。
      NOT_SUPPORTED以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
      NEVER以非事务方式执行,如果当前存在事务,则抛出异常。
      NESTED支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。

      2、**isolation:**事务隔离级别

      ​ 事务有特性成为隔离性,多事务操作之间不会产生影响。不考虑隔离性产生很多问题
      ​ 有三个读问题:脏读、不可重复读、虚(幻)读

      ​ **脏读(致命问题):**一个未提交事务读取到另一个未提交事务的数据

      ​ **不可重复读:**一个未提交事务读取到另一个已提交事务的数据

      ​ **虚(幻)读:**一个未提交事务读取到另一个已提交事务添加的数据

      ​ 解决:通过设置事务隔离级别,解决读问题

      脏读不可重复读幻读
      READ UNCOMMITTED(读未提交)
      READ COMMITTED(读已提交)
      REPEATABLE READ(可重复读)
      SERIALIZABLE(串行化)

      3、**timeout:**超时时间

      ​ 事务需要在一定时间内进行提交,如果不提交进行回滚
      ​ 默认值是-1 ,设置时间以秒单位进行计算

      4、**readOnly:**是否只读

      ​ 读:查询操作,写:添加修改删除操作
      ​ readOnly 默认值false,表示可以查询,可以添加修改删除操作
      ​ 设置readOnly 值是true,设置成true 之后,只能查询

      5、**rollbackFor:**回滚

      ​ 设置出现哪些异常进行事务回滚

      6、**noRollbackFor:**不回滚

      ​ 设置出现哪些异常不进行事务回滚

    • xml声明式事务管理

      第一步 配置事务管理器

      第二步 配置通知

      第三步 配置切入点和切面

      
          
              
              
          
      
          
          
              
              
                  
                  
              
          
      
          
          
              
              
              
              
          
      
    • 完全注解实现声明式事务管理

      第一步 创建配置类,替代xml文件

      package com.atguigu.spring5.config;
      
      import com.alibaba.druid.pool.DruidDataSource;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.ComponentScan;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.jdbc.core.JdbcTemplate;
      import org.springframework.jdbc.datasource.DataSourceTransactionManager;
      import org.springframework.transaction.annotation.EnableTransactionManagement;
      
      import javax.sql.DataSource;
      
      @Configuration    //配置类
      @ComponentScan(basePackages = "com.atguigu")    //组件扫描
      @EnableTransactionManagement        //开启事务
      public class TxConfig {
          //创建数据库连接池
          @Bean
          public DruidDataSource getDruidDataSource(){
              DruidDataSource dataSource = new DruidDataSource();  //德鲁伊连接池
              dataSource.setDriverClassName("com.mysql.jdbc.Driver"); //加载驱动
              dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/account?characterEncoding=UTF-8");  //url
              dataSource.setUsername("root");  //用户名
              dataSource.setPassword("root");  //密码
      
              return dataSource;
          }
      
          //创建jdbcTemplate对象
          @Bean
          public JdbcTemplate getJdbcTemplate(DataSource dataSource){
              //到ioc容器中根据类型找到dataSource
              JdbcTemplate jdbcTemplate = new JdbcTemplate();
              //注入dataSource
              jdbcTemplate.setDataSource(dataSource);
              return jdbcTemplate;
          }
      
          //创建事务管理器
          @Bean
          public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){
              DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
              //注入数据源
              transactionManager.setDataSource(dataSource);
              return transactionManager;
          }
      }
      

      service类

      import com.atguigu.spring5.config.TxConfig;
      import com.atguigu.spring5.service.UserService;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.annotation.AnnotationConfigApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class TestDemo {
          @Test
          public void TestAccount(){
              ApplicationContext context =
                      new ClassPathXmlApplicationContext("spring-config.xml");
              UserService userService = context.getBean("userService", UserService.class);
              userService.BankTransfer1("1","2",500);
          }
      
          @Test
          public void TestAccount2(){
              ApplicationContext context =
                      new AnnotationConfigApplicationContext(TxConfig.class);
              UserService userService = context.getBean("userService", UserService.class);
              userService.BankTransfer1("1","2",500);
          }
      }
      
      

      dao接口

      package com.atguigu.spring5.dao;
      
      public interface UserDao {
          void reduceMoney(String id1, int money);
      
          void addMoney(String id2, int money);
      }
      
      

      dao实现类

      package com.atguigu.spring5.dao;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.jdbc.core.JdbcTemplate;
      import org.springframework.stereotype.Repository;
      
      @Repository
      public class UserDaoImpl implements UserDao {
          @Autowired
          private JdbcTemplate jdbcTemplate;
      
          @Override
          public void reduceMoney(String id1, int money) {
              String sql = "update account set money = money - ? where id = ?";
              jdbcTemplate.update(sql,money,id1);
          }
      
          @Override
          public void addMoney(String id2, int money) {
              String sql = "update account set money = money + ? where id = ?";
              jdbcTemplate.update(sql,money,id2);
          }
      }
      
      

      测试类

      import com.atguigu.spring5.config.TxConfig;
      import com.atguigu.spring5.service.UserService;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.annotation.AnnotationConfigApplicationContext;
      
      public class TestDemo {
        
          @Test
          public void TestAccount2(){
              ApplicationContext context =
                      new AnnotationConfigApplicationContext(TxConfig.class);
              UserService userService = context.getBean("userService", UserService.class);
              userService.BankTransfer1("1","2",500);
          }
      }
      
      

      运行结果:

六、Spring5 新特性
  • 整个Spring5框架基于Java8,运行时兼容JDK9,许多不建议使用的类和方法在代码库中删除

  • Spring5框架核心容器支持@Nullable注解

    • 可以使用在方法上面,属性上面,参数上面,表示可以为空
  • 支持函数式风格GenericApplicationContext

  • Spring5支持整合JUnit5

  • SpringWebFlux

tereotype.Repository;

@Repository
public class UserDaoImpl implements UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void reduceMoney(String id1, int money) {
        String sql = "update account set money = money - ? where id = ?";
        jdbcTemplate.update(sql,money,id1);
    }

    @Override
    public void addMoney(String id2, int money) {
        String sql = "update account set money = money + ? where id = ?";
        jdbcTemplate.update(sql,money,id2);
    }
}

```

测试类

```java
import com.atguigu.spring5.config.TxConfig;
import com.atguigu.spring5.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestDemo {
  
    @Test
    public void TestAccount2(){
        ApplicationContext context =
                new AnnotationConfigApplicationContext(TxConfig.class);
        UserService userService = context.getBean("userService", UserService.class);
        userService.BankTransfer1("1","2",500);
    }
}

```

运行结果:

[外链图片转存中...(img-SxdR1Tsj-1651586731623)]
六、Spring5 新特性
  • 整个Spring5框架基于Java8,运行时兼容JDK9,许多不建议使用的类和方法在代码库中删除

  • Spring5框架核心容器支持@Nullable注解

    • 可以使用在方法上面,属性上面,参数上面,表示可以为空
  • 支持函数式风格GenericApplicationContext

  • Spring5支持整合JUnit5

  • SpringWebFlux

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

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

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