sping5框架

一、spring概述

  • spring是轻量级的开源的javaEE框架。
  • spring可以解决企业应用开发的复杂性
  • spring有两个核心部分:IOC和AOP
  • 1)IOC:控制反转,把创建对象过程交过Spring进行管理
  • 2)AOP:面向切面,不修改源代码进行功能增强
  • Spring特点:
    1)方便解耦,简化开发
    2)AOP编程支持
    3)方便程序的测试
    4)可以方便和其他框架组合
    5)方便进行事物的操作
    6)降低了API
准备工作

1、进入官网下载spring包
2、打开idea,创建普通java工程
3、导入Spring5相关的jar包
在这里插入图片描述

二、 IOC容器

1)ioc底层原理

什么是IOC
1、也叫控制反转,把对象创建和对象之间的调用过程,交过Spring
2、使用IOC目的:为了耦合度降低

ioc底层原理
1)xml解析、工厂模式、反射
在这里插入图片描述

2)IOC接口

IOC接口
1、ioc思想基于ioc容器完成,ioc容器底层就是对象工厂
2、Spring提供了ioc容器实现的两种方式(两个接口)
------1)BeanFactory:IOC容器基本实现方式,是Spring内部使用接口,一般不使用. 加载配置文件不会创建对象,在获取对象是才创建对象
-------2)ApplicationContext:BeanFactory接口的子接口,提供更加强大的功能,加载配置文件时就会把配置文件给创建

ApplicationContext接口的实现类
在这里插入图片描述
区别:filesystem…它的参数是文件的全路径
classpath…通过它的xml文件名

3)IOC操作Bean管理(基于xml)

什么是Bean管理
1)Bean管理指的是俩个操作
1)Spring 创建对象(类似于new 对象名)
2)Spring注入属性(类似于给属性赋值)

Bea管理操作的两种方式
1)基于xml配置文件方式创建
2)基于注解方式实现

创建对象
1)在spring的配置文件中使用bean标签,标签里面添加对应的属性,就可以实现对象的创建
<bean id="user1" class="com.qsh.User"></bean>
/**
id属性:唯一标识
class属性:你要创建类的全路径
**/
用Sprin配置文件创建对象时,默认也是执行无参数构造器
xml方式注入属性:
1)第一种注入方式:使用set方式注入
------创建属性和对的set方法
public class Book {
    private String name;
    private  String bauthor;
    public void setName(String name) {
        this.name = name;
    }

    public void setBauthor(String bauthor) {
        this.bauthor = bauthor;
    }
}
-------用在配置文件中配置对象创建,配置属性注入
 <!--配置User对象-->
    <bean id="user2" class="com.bean1.Book">

        <!--使用property完成属性注入
        name:类的属性名称
        value:属性注入的值
        -->
        <property name="name" value="九阴真经"></property>
        <property name="bauthor" value="qinshenghang"></property>
    </bean>



2)第二种注入方式:使用有参数构造进行注入
----------创建类,定义属性,创建属性对应有参数构造方法
public class Order {
    private String name;
    private String address;

    public Order(String name, String address) {
        this.name = name;
        this.address = address;
    }
}
--------用在配置文件中配置对象创建,配置构造函数的注入
 <bean id="orders" class="com.bean1.Order">
        <!--使用constructor完成属性注入
       name:类的属性名称
       value:属性注入的值
       -->
        <constructor-arg name="name" value="电脑" ></constructor-arg>
        <constructor-arg name="address" value="China"></constructor-arg>
    </bean>

IOC操作Bean管理(xml注入其他类型属性)
1、字面量
--------1)null

   设置属性值为null
   <property name="number" >
     <null/>
</property>

--------2)属性值包含特殊符号

  属性值包含特殊的符号
  1.把<>进行转义
  2.把带特殊符号类容写道CDATA中
   <property name="address">
       <value>
         <![CDATA[<南京>>]]> 
         </value>
    </property>

注入对象类型的属性
1)外部bean
------创建Service类和dao类
------在Service中调用dao类里面的方法
-------在配置文件中进行配置
2)内部bean和级联赋值
--------一对多关系
---------在实体类之间表示一对多关系
---------在spring配置文件中进行配置

> 1)外部bean
   //Service类中调用UerDaoIpl方法(原始方法)
        UserDao user= new UerseDaoIpl();
        user.update();
    
 //Service实现类
   public class UserService {
    //创建UserDao类型的属性,生成set方法
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void add(){
        System.out.println("serverice adddd--");

    }
}


//接口
public interface UserDao {
    public void update();
}


//接口实现类
public class UerseDaoIpl implements UserDao {
    @Override
    public void update() {
        System.out.println("dao UODATE------");
    }
}


xml配置文件:
 <!--配置Service和dao对象-->
    <bean id="userdaopl"  class="dao.UerseDaoIpl"></bean>

    <bean id="userservice" class="service.UserService">
        <!--
        ref属性:UerDao对象bean标签的id值(把外部的bea注入进来)
        -->
        <property name="userDao" ref="userdaopl"></property>
    </bean>
2)内部bean和级联赋值

//部门类
public class Dept {
    private String dname;

    public void setDname(String dname) {
        this.dname = dname;
    }
}



//员工类
public class Emp {
    private  String ename;
    private  String gender;
    //员工属于某一个部门,使用对象形式表示
    private Dept dept;

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}

xml配置文件

    <bean id="emp" class="bean.Emp">
    <property name="ename" value="覃圣航"></property>
    <property name="gender" value="男"></property>
    
<!--设置对象类型属性-->
    <property name="dept">
    <!--内部bean-->
        <bean id="Dept" class="bean.Dept" >
            <property name="dname" value="保安部"></property>
        </bean>
    </property>
</bean>

IOC操作Bean管理(xml注入集合list,map.set属性)
-------创建类,定义数组、list、map、set类型的属性,生成对应的set方法
-------在Spring配置文件中进行配置

<bean id="Stu" class="com.Spring.Stu">
    <property name="courses">
        <!--数组的的注入-->
        <array>
            <value>sad</value>
            <value>123</value>
        </array>
    </property>
    <property name="list">
        <list>
            <value>sad</value>
        </list>
    </property>
    <property name="set">
        <set>
            <value>123</value>
        </set>
    </property>
    <property name="map">
        <map>
            <entry key="姓名" value="覃圣航"></entry>
            <entry key="年龄" value="19"></entry>
        </map>
    </property>
</bean>
</beans>
在集合里面设置对象类型的值
<!--注入list集合,但值是对象 -->
    <property name="courseList">
        <list>
            <ref bean="course1"></ref>
            <ref bean="course2"></ref>
        </list>
    </property>
</bean>
    <!--创建多个course对象-->
    <bean id="course1" class="com.Spring.Course">
        <property name="aname" value="Spring5框架"></property>
    </bean>
    <bean id="course2" class="com.Spring.Course">
        <property name="aname" value="mybatis框架"></property>
    </bean>
把集合注入部分提取出来
1)在spring配置文件中引入名称空间util
xmlns:util="http://www.springframework.org/schema/util"
在xsi:schemaLocation后面加上 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-beans.xsd
2)提取list集合类型属性注入
 <util:list id="books">
        <value>123456</value>
        <value>456789</value>
        <value>456789</value>
    </util:list>
3)提取list集合类型属性注入使用
  <bean id="Book" class="com.Spring.Book">
        <property name="name" ref="books"></property>
    </bean>
5)IOC操作Bean管理(FactorBean)

Spring有两种bean,一种是普通bean,另外一种是工厂bean(FactoryBean)。
-----普通bean:在配置文件中定义bean类型就是返回类型
-----工厂bean:在配置文件中定义bean类型可以和返回的类型不一样。
1)创建类,让这个类作为工厂bean,实现FacroyBean接口
2)实现接口里面的方法,在实现的方法中定义返回bean类型

public class MyBean implements FactoryBean<Book> {
    //定义bean返回的类型
    @Override
    public Book getObject() throws Exception {
        return null;
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }
   
    @Override
    public boolean isSingleton() {
        return false;
    }
}

bean管理的作用域
-----作用域:在Spring中,设置创建的bean是单实例,还是多实列。
-------在Spring里面,默认情况下,bea是一个单实例对象
-------在spring配置文件bean标签里面有属性(sope)用于设置单实例还是多实例.
--------scope属性值:
1 ) 默认值,singleton表示是单实例对象
2 )prototype表示是多实例对象

 //创建多实例对象
    <bean id="Book" class="com.Spring.Book" scope="prototype">
        <property name="name" ref="books"></property>
    </bean>

bean管理的生命周期
--------什么周期:从对象创建到对象销毁的过程;
--------bean的生命周期:
1)通过构造器创建bea实例(无参构造器,有参构造器)
2)为bean的属性设置值和对其他bea的引用(调用set方法)
3)把bean实例传递bean后置处理器的方法(创建类实现接口BeanPostProcessor)
4)调用bean的初始化方法(需要配置初始化的方法)
5)把bean实例传递bean后置处理器的方法
6)bean可以使用了(对象获取到了)
7)当容器关闭时候,调用bean的销毁的方法(需要配置销毁的方法)

public class bean {
    private String aname;

    public bean() {
        System.out.println("执行了第一步,通过构造器创建方法");

    }

    public void setAname(String aname) {
        this.aname = aname;
        System.out.println("执行了第二步,调用set属性");

    }
    public  void csh(){
        System.out.println("执行了第三步,初始化");
    }
    public void Destoy(){
        System.out.println("执行了第五步,销毁");
    }





@Test
    public void test(){
      ApplicationContext context=new ClassPathXmlApplicationContext("beanxml.xml");
      bean bean1=context.getBean("bean",bean.class);
      System.out.println("执行了第4步,对象获取到了");
      //手动销毁
      ((ClassPathXmlApplicationContext)context).close();  

    }
}



//后配处理器
public class last implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化之前执行的方法");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化之后执行的方法");
        return bean;
    }
}



   <!--init-method:代表初始化方法
        destroy-method:代表销毁方法-->
<bean id="bean" class="Bean.bean" init-method="csh" destroy-method="Destoy">
    <property name="aname" value="覃圣航"></property>
</bean>

<!--配置后配处理器-->
    <bean id="last" class="Bean.last"></bean>

自动装配
----自动装配:根据指定装配规则(属性名称或者属性类型),Spring自动将配置的属性值进行注入。

</bean>
    <!--实现自动装配
        bean标签属性autowire,配置自动装配
        autowire属性常用的两个值:
             byName根据属性名称注入,注入值bean的id值和类属性名称一致
             byType根据属性类型注入
     -->
    <bean id="emp" class="autowrie.Emp" autowire="byName">

    </bean>

    <bean id="dept" class="autowrie.Dept">
        <property name="aname" value="学习部"></property>
    </bean>

外部属性文件
1)配置连接池
-------引号人jar包
-------配置spring文件在这里插入图片描述
2)引入外部属性文件配置数据库连接池
--------创建外部属性文件,properties格式文件,写数据库信息
在这里插入图片描述
--------把properties属性文件引入到spring配置文件中
先引入名称空间:
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
xmlns:context="http://www.springframework.org/schema/context"
在这里插入图片描述

5)IOC操作Bean管理(基于注解)

1、什么是注解:
-------注解是代码的特殊标记,格式:@注解名称(属性名称=属性值)
-------注解可以用在类,方法、属性。
-------注解目的,简化xml配置。
2、Spring针对bean管理创建对象提供的注解
-------@Compoent:
-------@Service
-------@Controller
-------@Repository
--------上面的4个注解功能都是一样的,用来创建bean实例
3、基于注解方式实现对象创建
--------第一步、引入依赖
在这里插入图片描述
--------第二步、开启组件扫描(告诉spring类里面,要加上注解,去扫描那些类)
在这里插入图片描述
-------第三步、创建类,在类上面添加创建对象注解
在这里插入图片描述

开启组件扫描细节(告诉spring类里面,要加上注解,去扫描那些类)
<!--
use-default-filters="false" false表示自己配置规则
context:include-filter  设置扫描的内容
例子一:表示只扫描zhujie包中org.springframework.stereotype.Service的注解
-->
    <context:component-scan base-package="zhujie" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
    </context:component-scan>




  <!--
    use-default-filters="false" false表示自己配置规则
    context:include-filter  设置扫描那些内容不扫描
  
    -->
    <context:component-scan base-package="zhujie" use-default-filters="false">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
   
    </context:component-scan>
注解方式属性的注入

@AuroWired (根据属性类型进行自动装配)
---------第一步把Service和dao对象创建好,在service和dao类添加创建对象的注解
---------第二步在service注入dao对象,在service和dao类添加创建对象注解
--------第三步在serviece注入到对象,在属性上面使用注解
在这里插入图片描述
@Qualifier (根据属性名称进行注入)
Qualifier要和AuroWired一起使用
在这里插入图片描述
@Resourc (可以根据类型注入,也可以根据名称注入)
在这里插入图片描述
@value(更具普通类型属性)
在这里插入图片描述

三、AOP

1)AOP概念

---------面向切面编程(方面),利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,提高开发效率
--------通俗描述:不通过修改源代码方式,在主干功能里面添加新的功能

2)底层原理

-------Aop底层使用动态代理
1)两种情况的动态代理
第一种、有接口的情况,使用JDK动态代理
****创建接口实现类代理对象,增强类的方法在这里插入图片描述
第二种、无接口的情况,使用CGLIB动态代理
******创建子类的代理对象,增强类的方法
在这里插入图片描述

3)AOP(动态代理)

----------使用JDK动态代理,使用proxy类里面的方法创建代理对象
在这里插入图片描述
1)newproxyinstance方法第一个参数, 定义了由哪个ClassLoader对象来对生成的代理对象进行加载
2)第二个参数,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
3)第三个参数,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上

1)创建接口定义方法
public interface UserDao {
    public int add(int a,int b);
    public String update(String a);
}


2)创建接口实现类,实现方法
public class UsrDaoImpl implements UserDao{
    @Override
    public int add(int a, int b) {
        return a+b;
    }

    @Override
    public String update(String a) {
        return a;
    }
}

3)使用proxy类创建接口代理对象
public class JDKProxy {
    public static void main(String[] args) {
        //创建接口实现类代理对象
        Class[] interfase={UserDao.class};
        UsrDaoImpl usrDao = new UsrDaoImpl();
        UserDao o = (UserDao)Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfase, new UserDaoPosy(usrDao));
        int add = o.add(1, 2);
        System.out.println(add);
    }
}

//创建代理对象代码
class UserDaoPosy implements InvocationHandler{
    //把创建是谁的代理对象,把他给传递过来
    //通过有参构造传递
    private Object object;
    public  UserDaoPosy(Object object){
        this.object=object;
    }

    //incoke写增强的逻辑
    //proxy:你的代理对象   method:你的代理中的方法    args:你的参数
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //方法之前
        System.out.println("方法之前执行"+method.getName()+"传递的参数"+ Arrays.toString(args));

        //被增强后的方法执行
        Object res = method.invoke(object, args);
        //方法之后
        System.out.println("方法之后执行"+object);

        return res;
    }
}
4)AOP(术语)

------连接点
类里面那些方法可以增强,这些方法被叫做连接点
------切入点
实际被真正增强的方法,被叫做切入点
------通知(增强)
实际增强的逻辑部分
通知有多种类型,前置通知,后置通知,环绕通知,异常通知,最终通知。
------切面
是动作,把通知应用到切入点的过程。

4)AOP(准备工作)

--------1、Spring矿建一般基于Aspecj实现AOP操作
1)什么是Aspecj
他不是spring组成部分,是独立的Aop框架,一般Aspecj和Sping一起使用,进行Aop操作
--------2、基于Aspecj实现Aop操作
1)基于xml方式实现
2)基于注解方式实现(经常使用)
--------3、在项目工程里面引入AOP相关依赖
在这里插入图片描述
-------4、切入点表达式
1)切入点表达式作用,知道对哪个类里面的那个方法增强
2)语法结构
execution([权限修饰符] [返回类型][类全路径][方法名称][(参数名字)]),通常*表示所有的权限修饰符

5)AOP(Aspecj注解实现操作)

-------创建类,在类里面定义方法
-------创建一个增强类(里面写你要增强的逻辑)
1)在增强类里面,创建方法,让不同方法代表不同的通知
--------进行通知配置
1)在spring配置文件中,开启注解的扫描
2)使用注解来创建user和userproxy对象
3)增强类上面添加注解@Aspect
4)在spring配置文件中开启生成代理对象
在这里插入图片描述
在这里插入图片描述
---------配置不同类型的通知
1)在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置
@Before(vlaue=“切入点表达式”)前置通知
@After(vlaue=“切入点表达式”)后置通知
@AfterReturning(vlaue=“切入点表达式”)最终通知,返回值之后执行
@AfterThrowing(vlaue=“切入点表达式”)异常通知
@Around(vlaue=“切入点表达式”)环绕通知。 在方法之前和之后都会执行

    <context:component-scan base-package="User"></context:component-scan>
    <aopt:aspectj-autoproxy></aopt:aspectj-autoproxy>

//被增强类
@Service("user1")
public class User1 {
    public void Add(String name){
        System.out.println("被增强的类"+name);
    }
}

//增强的类
@Service(value = "user1proxy")
@Aspect//生成代理对象
public class User1proxy {
    @Before(  value = "execution(* User.User1.Add(..))")
    public void user1proxy_add(){
        System.out.println("这是前置增强的方法");
    }
    @Test
    public void qsh(){
        ApplicationContext context=new ClassPathXmlApplicationContext("qsh01.xml");
        User1 user1 = context.getBean("user1", User1.class);
        user1.Add("覃圣航");
    }
}
5)AOP(Aspecj注解实现操作优化)

相同的切入点抽取
1)定义一个方法
2)在方法上面加上切入点注解Poincur(value=“切入点表达式”)

public class User1proxy {
    @Pointcut(value ="execution(* User.User1.Add(..))" )
    public void Poinitt(){

    }
    @Before(  value = "Poinitt()")
    public void user1proxy_add(){
        System.out.println("这是前置增强的方法");
    }
    @Test

三、jdbcTemplate

1)jdbc准备工作

------------什么是jdbcTemplate
1)Spring框架对jabc进行封装,使用jdbcTemplae方便实现对数据库操作
-----------准备工作
1‘)引入相关jar包
在这里插入图片描述
在这里插入图片描述
2)在spring配置文件配置数据库连接池
在这里插入图片描述
3)配置jdbctemplate对象
在这里插入图片描述
4)创建service类,创建dao类,在dao类注入jdbctemplate对象

public interface Dao_interface {
}


@Service("dao")
public class dao implements Dao_interface{
    @Autowired
    private JdbcTemplate jdbcTemplate;
}


public class service {
    @Autowired
    private Dao_interface dao;
}
1)操作数据库准备工作

-------对应数据库表创建实体类
-------编写service和dao
1)在dao进行数据库添加操作
2)update(String sql ,Objec… args )
第一个参数:sql语句,第二个参数:可变参数,设置sql语句值

public interface Dao_interface {
    //添加的方法
    void add(Book book);
}

@Service("dao")
public class dao implements Dao_interface{
    @Autowired
    private JdbcTemplate jdbcTemplate;

    //添加的方法
    @Override
    public void add(Book book) {
        //用 jdbcTemplate.update来实现增加删除修改
        String sql="inert into book values(?,?,?)";
        int update = jdbcTemplate.update(sql, book.getUserId(), book.getUsername(), book.getUstatus());
        System.out.println(update);
    }
}

public class service {
    @Autowired
    private Dao_interface dao;
    public void addBook(Book book){
        dao.add(book);
    }
    }

----查询操作
返回一个值:
在这里插入图片描述
第一个参数是sql语句,第二个是返回值类型
返回对象:
在这里插入图片描述
----多条语句执行
在这里插入图片描述

四、 事物管理

1)什么是事务

1)事务是数据库操作最基本的单元,逻辑上一组操作,要么成功,要么失败,如果一个失败那所有的操作都失败
2)事务的特性:原子性(要么成功要么失败)、一致性(操作前和操作后总量不变)、隔离性(在多事务操作时,之间没有影响)、持久性()

2)事务操作(搭建事务操作环境)

在这里插入图片描述-----------创建数据库表,添加记录在这里插入图片描述
-------创建service,搭建dao,完成对象的创建和注入关系
1)在service注入dao,在dao注入jdbctemplate,在jdbctemplate注入DateSource
------在dao创建两个方法:多钱和少钱的方法,在service创建方法(转账的方法)

public interface UserDao {
    public void addMoney();
    public void reduceMoney();
}





@Repository("userdaoimpl")
public class UserDaoImpl implements UserDao{
    @Autowired
    private JdbcTemplate jdbcTemplate;

   //A转账100给B
    @Override
    public void reduceMoney() {
        String sql="update t_account set money=money-? where username";
        jdbcTemplate.update(sql,100,"lucy");
    }
    @Override
    public void addMoney() {
        String sql="update t_account set money=money+? where username";
        jdbcTemplate.update(sql,100,"mary");
    }


}




@Service("userservice")
public class UserService {
//注入dao
    @Autowired
    @Qualifier("UserDaoimpl")
    private UserDao userdao;
    public void accountMoney(){
        //A少100
        userdao.addMoney();
        //b多100
        userdao.reduceMoney();
    }

}


2)事务操作(事务场景出现)

上面代码,如果正常执行没有问题的,但是如果代码执行过程中出现异常。
1)下面问题如何解决
使用事务进行解决
2)操作过程。开启事务操作、进行业务操作、没有异常关闭异常提交事务,出现异常事务回滚

public void accountMoney(){
        //A少100
        userdao.addMoney();
        //模拟异常,如此a会少100但是b不会增加
        int a=10/0;
        //b多100
        userdao.reduceMoney();
    }
2)事务操作(Spring事务管理介绍)

-----------事务添加到javaee三层架构里面service层中(业务逻辑层)
-----------在Spring进行事务管理操作
1)有两种方式:编程式事务管理和声明式事务管理(常使用)
--------声明事务管理
1)基于注解方式
2)基于xml配置文件方式
--------在Spring进行声明式事务管理,底层使用Aop原理
---------Spring事务管理API
1)提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类
在这里插入图片描述

2)事务操作(注解声明式事务管理)

-----------在spring中配置文件配置事务管理器
在这里插入图片描述
-----------在Spring配置文件中,引入tx名称空间
xmlns:tx="http://www.springframework.org/schema/tx" http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
-----------开启事务注解
在这里插入图片描述
-----------在service的类上面(或者service类的方法上)添加事务注解
1)@Transactional,这个注解可以添加到类上面,也可以添加到方法上面
2)如果添加到类上面,这个类里面所有的方法都添加了事务
3)添加的方法,为这一个方法添加事务

2)事务操作(@Transactional参数配置)

在service类上面添加注解@Transactional,在这个注解里面可以配置事务的相关参数
在这里插入图片描述
----------propagation:事务的传播行为(@Transactional(propagation = Propagation.REQUIRED))
1)多事务方法直接进行调用,这个过程中事务时如何进行管理的。例如:一个事务方法调用一个不是事务的方法,不是事务方法调用是事务方法…。
在这里插入图片描述
----------ioslation:事务隔离级别(@Transactional(isolation = Isolation.SERIALIZABLE))
1)事务中有特性隔离性,多事务操作之间不会产生影响。不考虑隔离性会产生很多问题
2)产生的三个问题:脏读、不可重复读、虚读
3)脏读:一个未提交事务读取到另一个未提交事务的数据
4)不可重复读:一个未提交的事务读取到提交了的事务添加的数据
5)虚读:一个未提交的事务读取到提交了的是事务添加的数据
6)设置隔离级别,解决问题
在这里插入图片描述

----------timeout:超时时间
1)事务在多长时间内提交,若不提交就会回滚
2)默认值:-1,表示不超时,设置以秒为单位
----------readOnly:是否只读
1)读:查询操作,写:添加修改操作
2)默认值false,读写操作
3)设置为true,只可以读操作
----------rollbackFor:回滚
1)设置查询那些异常进行事务回滚
----------noRollbackfor:不回滚
2)设置出现那些异常不进行事务回滚

spring5新特性

Spirng框架自带了通用的日志封装(官方建议使用log4j2)

1)引入log4j2相关jar包
在这里插入图片描述
2)创建Log4j2.xml文件(这个名字是固定的)
在这里插入图片描述

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

@Nullable注解可以使用在方法、属性、参数上面,表示方法可以返回为空、属性值、参数值可以为空

Spring框架核心容器支持函数式风格GenericApplicationContext

可以使用java8中的Lambda表达式

Spring支持整合JUnit5

------------整合Junit4
1)引入spring针对测试的依赖
在这里插入图片描述
2)创建测试类,使用注解(@Test)方式完成在这里插入图片描述
------------整合Junit5
1)引入Junit5的jar包
在这里插入图片描述
2)创建测试类,使用注解方式完成
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值