• Spring5查缺补漏


    Spring5-基础知识

    笔记简介:

    1、Spring概念

    2、IOC

    3、AOP

    4、JDBCTemplate

    5、事务管理

    6、Spring5里边的新特性

    概述:

    1、Spring框架是一个轻量级 开源的javaEE框架。

    轻量级:引入依赖的jar包数量少,体积小。不再需要依赖其他的组件,可以单独使用。

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

    (2)AOP:面向切面编程。不再修改源代码进行功能的修改增强。

    特点:

    1、方便解耦,简化开发

    2、AOP编程支持

    3、方便程序的测试,整合Junit

    4、方便集成各种框架

    5、支持事务的管理

    6、源码经典

    入门案例-Spring创建对象

    下载Spring5的jar包

    5.2.6GA稳定版本 https://repo.spring.io

    https://repo.spring.io/ui/native/plugins-release/org/springframework/spring/5.2.0.M3/

    1、准备5个jar包

    commons-logging-1.1.1.jar
    spring-beans-5.2.0.M3.jar
    spring-context-5.2.0.M3.jar
    spring-core-5.2.0.M3.jar
    spring-expression-5.2.0.M3.jar

    2、测试代码

    
    <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="user" class="com.pshdhx.User">bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    package com.pshdhx;
    
    import org.junit.Test;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * @Auther: pshdhx
     * @Date: 2023/08/24/14:50
     * @Description:
     */
    public class TestDemo {
        @Test
        public void testAdd(){
            /**
             * 1、加载spring的配置文件
             * 2、获取配置的对象
             */
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
            User user = context.getBean("user",User.class);
            System.out.println("user = " + user);
            user.add();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    IOC容器

    底层原理

    ​ 1、控制反转:把对象创建和对象之前的调用过程,交给Spring进行管理。

    ​ 2、降低耦合度

    ​ 主要用到了xml的解析、工厂设计模式、反射。

    工厂模式:两个类之前的调用,多了一个工厂类

    class UserFactory{
    	public static UserDao getDao(){
    		return new UserDao();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    IOC过程:

    1、xml配置文件,配置要创建的对象

    <bean id="userDao" class="com.pshdhx.UserDao">bean>
    
    • 1

    2、工厂类

    class UserFactory{
    	public static UserDao getDao(){
    		String classValue = class属性值; //xml解析
    		Class clazz = Class.forName(classValue);// 通过反射创建对象        
            return (UserDao)clazz.newInstance(); 	
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    降低耦合度:比如说UserDao的路径改变了,用之前的方式,需要都要改,用现在的方式,只需要改配置文件即可。

    BeanFactory接口:内部使用接口,不提供开发人员使用。加载配置文件的时候,不会创建对象。在使用的时候,采取创建对象。

    ApplicationContext接口:BeanFactory的子接口,功能更强大,一般面向开发人员使用。在加载配置文件的时候,就会创建配置的对象。

    ApplicationContext的实现类:

    在这里插入图片描述

    FileSystem是盘符路径

    classPath是工程路径

    IOC的Bean管理

    1、spring创建对象

    2、spring注入属性【==get set方法】

    IOC接口 BeanFactory

    IOC的bean管理的具体操作,基于xml

    创建对象的时候,默认也是执行无参构造方法,完成对象的创建。如果User对象中是有参构造,那么Spring创建对象报错。

    DI:依赖注入。

    1、使用set方法注入

    public class User {
        private String username;
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public void add(){
            System.out.println("this.username=="+this.username);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    
    <bean id="user" class="com.pshdhx.User">
        <property name="username" value="pansd"/>
    bean>
    
    • 1
    • 2
    • 3
    • 4

    2、使用构造方法注入

    public class User {
        private String username;
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public User(String username) {
            this.username = username;
        }
    
        public void add(){
            System.out.println("this.username=="+this.username);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
        
        <bean id="user" class="com.pshdhx.User">
    
            <constructor-arg name="username" value="pshdhx">constructor-arg>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    P空间注入

    xmlns:p="http://www.springframework.org/schema/p"
        <bean id="user" class="com.pshdhx.User" p:username="pshdhx">
    
    
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注入其他类型

    <property name="username">
        <null/>
    property>
    
    <property name="username">
        <value> 
        	<pshdhx>>]]
        value>
    property>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    注入外部Bean

    <bean id="addressImpl" class="com.pshdhx.Address">bean>
    <bean id="user" class="com.pshdhx.User" >
            <property name="address" ref="addressImpl"/>
    bean>
    
    • 1
    • 2
    • 3
    • 4
    public class User {
        private Address address;
    
        public void setAddress(Address address) {
            this.address = address;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    注入内部bean和级联赋值

    1、一对多关系【部门和员工】

    <bean id="emp" class="com.pshdhx.Emp">
        <property name="ename" value="pshdhx"/>
        <property name="gender" value="male"/>
        <property name="dept">
            <bean id="dept" class="com.pshdhx.Dept">
                <property name="dname" value="IT"/>
            bean>
        property>
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    注入集合:Arr、List、Set、Map

    <bean id="student" class="com.pshdhx.Student">
        <property name="courses">
            <array>
                <value>javavalue>
                <value>DBvalue>
            array>
        property>
        <property name="list">
            <list>
                <value>list1value>
                <value>list2value>
            list>
        property>
        <property name="set">
            <set>
                <value>set1value>
                <value>set2value>
            set>
        property>
        <property name="map">
            <map>
                <entry key="key1" value="value1">entry>
                <entry key="key2" value="value2">entry>
            map>
        property>
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    集合对象为对象

     <property name="courseList">
                <list>
                    <ref bean="course1">ref>
                    <ref bean="course2">ref>
                list>
            property>
      <bean id="course1" class="com.pshdhx.Course">
            <property name="cname" value="Spring5">property>
        bean>
        <bean id="course2" class="com.pshdhx.Course">
            <property name="cname" value="SpringMVC">property>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    抽取公用xml:引入名称空间

    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:util="http://www.springframework.org/schema/util"
           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
                               http://www.springframework.org/schema/util  http://www.springframework.org/schema/util/spring-util.xsd">
        
            <util:list id="bookList">
            <value>Springvalue>
            <value>SpringMVCvalue>
        util:list>
    
        <bean id="book" class="com.pshdhx.Book">
            <property name="bookListString" ref="bookList">
            property>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    IOC的bean管理的具体操作

    Spring里边有普通的Bean,还有另外一种Bean-FactoryBean

    普通Bean特点:在xml中class定义的是什么类型,那么getBean返回的就是什么类型。

    工厂Bean特点:定义类型和返回类型可以不一致。

    package com.pshdhx.factoryBean;
    
    import com.pshdhx.Course;
    import org.springframework.beans.factory.FactoryBean;
    
    /**
     * @Auther: pshdhx
     * @Date: 2023/08/28/13:27
     * @Description:
     */
    public class MyBean implements FactoryBean {
        @Override
        public Object getObject() throws Exception {
            Course course = new Course();
            course.setCname("Java");
            return course;
        }
    
        @Override
        public Class<?> getObjectType() {
            return null;
        }
    
        @Override
        public boolean isSingleton() {
            return false;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    @Test
    public void testMyBean(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
        Course myBean = context.getBean("myBean", Course.class);
        System.out.println("myBean = " + myBean);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Bean的作用域

    作用域:是单实例还是多实例,默认是单实例的。

    getBean两次,看看对象是否是单实例。

    bean标签行中,有个scope属性设置:singleton/prototype

    特点:

    singleton:单实例。加载spring配置文件的时候,创建单实例对象。

    prototype:多实例。不是在加载Spring配置文件的时候创建对象,而是在getBean的时候,创建新的对象。

    request:一次请求

    session:一次会话

    bean的生命周期

    生命周期:从对象的创建到对象的销毁。

    1、通过构造器创建Bean实例。(无参构造)

    2、为Bean的属性值设置值和对其他Bean的引用(调用set方法的过程)。

    ​ 将Bean的实例,传递给后置处理器的方法【初始化之前】

    3、调用Bean里边的初始化的方法(需要进行配置)

    ​ 将Bean的实例,传递给后置处理器的方法【初始化之后】

    4、bean可以使用了,对象可以获取到了

    5、当容器在关闭的时候,bean调用销毁的方法(需要进行配置)。

    代码演示:

    public class BeanInit {
        private String initName;
    
        public BeanInit() {
            System.out.println("第一步:无参构造");
        }
    
        public void setInitName(String initName) {
            this.initName = initName;
            System.out.println("第二步:set设置属性值");
        }
    
        public void initMethod(){
            System.out.println("第三步:Bean初始化方法");
        }
        public void destoryMethod(){
            System.out.println("第五步:Bean销毁方法");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    @Test
    public void testMyBean(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
        BeanInit beanInit = context.getBean("beanInit", BeanInit.class);
        System.out.println("第四步:获取对象"+beanInit);
        context.close();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    结果:

    在这里插入图片描述

    这个初始化的前置和后置方法,并没有和某一个bean做关联,所以说每个Bean的初始化之前和之后,都是会执行这个方法的。

    public class BeforeAfterBeanInit 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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    Bean管理-基于xml的自动装配

    手动装配:bean标签中的

    自动装配:根据指定的装配规则(属性类型和属性名称),spring会自动帮助我们完成注入。

    演示自动装配过程:

    Bean的id的值和类名必须一致。

    byType:相同类型的Bean只能注册一个。

    Bean管理-引入外部的属性文件

    引入:druid.jar的包

    引入context的名称空间

    xmlns:context="http://www.springframework.org/schema/context"
    http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd
        <context:property-placeholder location="classpath:jdbc.properties"/>
    
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="username" value="${db.username}"/>
            <property name="password" value="${db.password}"/>
            <property name="url" value="${db.url}"/>
            <property name="driverClassName" value="${db.driverClassName}"/>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    基于注解实现创建对象和属性注入

    注解:代码的特殊标记@注解名称(属性名=属性值,属性名=属性值)

    注解:

    1、可以在方法中、类中、属性中都可以加注解

    2、目的:简化配置

    @Component:

    @Service:

    @Controller

    @Repository

    (1) 需要额外引入aop的依赖。

    (2)开启组件扫描 引入context

    <context:component-scan base-package="com.pshdhx.annotation" >context:component-scan>
    
    • 1

    (3)创建类,加注解

    @Component
    public class Bean1 {
        public void test(){
            System.out.println("annotation 创建对象");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    组件扫描细节:

       <context:component-scan base-package="com.pshdhx.annotation" >context:component-scan>
        <context:component-scan base-package="com.pshdhx.annotation"  use-default-filters="false">
            
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        context:component-scan>
    
        <context:component-scan base-package="com.pshdhx.annotation" >
            
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
        context:component-scan>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    基于注解实现属性注入

    1、@Autowired:根据属性类型注入

    2、@Qualifier:根据属性名称自动注入,配合autowired一块使用

    3、@Resource:根据类型和名称进行注入

    4、@Value

    @Value(value="pshdhx")
    private String name;
    
    • 1
    • 2

    纯注解开发

    //1、创建配置类、替代xml文件
    @Configuration
    @ComponentScan(basePackages={"com.pshdhx"})
    public class SpringConfig{
    	
    }
    //编写测试类,不再加载xml文件了
    public void test{
    	ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    	
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    AOP

    概念:对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间耦合度降低,提高程序的可重用性,同时提高开发效率。

    AOP的使用场景——登录功能:例如添加权限,if 管理员 if普通用户。

    AOP就是在不通过修改源代码的方式添加新的功能。

    权限管理模块,独立出一个新的模块,配置到主干里边去。

    底层原理:

    使用到了动态代理,增强了类中某个方法的功能。

    (1)有接口的情况:要使用到JDK的动态代理。

    创建出代理对象,通过代理对象实现某些功能。

    public class TestAopJdkProxy {
        public static void main(String[] args) {
            //创建UserDao的代理对象,利用这个对象进行功能的修改操作
            UserDao userDao = (UserDao) Proxy.newProxyInstance(TestAopJdkProxy.class.getClassLoader(), new Class[]{UserDao.class},
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            System.out.println(method.getName() + "方法执行之前,参数是:"+ Arrays.toString(args));
    //                        Object proxy 这个是object对象,没有什么东西
                            Object result = method.invoke(new UserDaoImpl(), args);
                            System.out.println("方法执行之后");
                            return result;
                        }
                    }
            );
            userDao.add(3, 4);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    (2)没接口的情况:要使用到CGLIB动态代理。

    继承某个类,重写方法。【创建子类的代理对象】

    术语

    连接点:可以被增强的方法。

    切入点:真正被增强的方法。

    通知:实际增强的逻辑部分。【前置、后置、环绕、异常、最终通知】

    切面:把通知应用到切入点的过程。

    AOP操作

    使用AspectJ工具实现AOP操作,单独的AOP框架,不是基于Spring的

    1、基于注解的配置方式

    (1)引入jar包

    ​ spring-aspects-5.2.0.M3.jar

    ​ cglib-2.2.jar

    ​ aspectjweaver-1.6.8.jar

    ​ aopalliance-1.0.jar

    (2)切入点表达式,对哪个类中的哪个方法进行增强

    execution([权限修饰符][返回类型][类的全路径][方法名字][参数列表])
    execution(* com.pshdhx.aop.TestClass.add(..))
    execution(* com.pshdhx.aop.TestClass.*(..))
    execution(* com.pshdhx.aop.*.*(..))
    
    • 1
    • 2
    • 3
    • 4

    after是方法之后执行

    afterReturning是返回值返回之后执行

    xmlns:p="http://www.springframework.org/schema/p"
           xmlns:context="http://www.springframework.org/schema/context"
    <context:component-scan base-package="com.pshdhx.aop.aspectj">context:component-scan>
    <aop:aspectj-autoproxy>aop:aspectj-autoproxy>
    
    • 1
    • 2
    • 3
    • 4
    @Component
    @Aspect
    public class UserProxy {
        @Before(value = "execution(* com.pshdhx.aop.aspectj.User.add(..))")
        public void before(){
            System.out.println("前置通知。。。。");
        }
    
        @After(value = "execution(* com.pshdhx.aop.aspectj.User.add(..))")
        public void after(){
            System.out.println("后置通知。。。。");
        }
    
        @Around(value = "execution(* com.pshdhx.aop.aspectj.User.add(..))")
        public void arround(ProceedingJoinPoint p) throws Throwable {
            System.out.println("环绕通知-前置环绕。。。。");
            p.proceed();
            System.out.println("环绕通知-后置环绕。。。。");
    
        }
    
        @AfterReturning(value = "execution(* com.pshdhx.aop.aspectj.User.add(..))")
        public void afterReturning(){
            System.out.println("afterReturning通知。。。。");
        }
    
        @AfterThrowing(value = "execution(* com.pshdhx.aop.aspectj.User.add(..))")
        public void afterThrowing(){
            System.out.println("afterThrowing通知。。。。");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    出现了异常之后,后置环绕通知和afterReturning接收不到。但是,around必须抛出异常,下边才能afterThrowing。

    异常顺序:

    环绕通知-前置环绕。。。。
    前置通知。。。。
    后置通知。。。。
    afterThrowing通知。。。。

    正常顺序:

    环绕通知-前置环绕。。。。
    前置通知。。。。
    User 的add 方法
    环绕通知-后置环绕。。。。
    后置通知。。。。
    afterReturning通知。。。。

    切入点的抽取:

    @AfterReturning(value = "pointCut()")
        public void afterReturning(){
            System.out.println("afterReturning通知。。。。");
    }
    
    @Pointcut(value = "execution(* com.pshdhx.aop.aspectj.User.add(..))")
    public void pointCut(){
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    设置增强类的优先级:

    一个方法被多次增强,可以在类上加一个注解@Order(1) 先执行 @Order(2)后执行

    2、基于xm的配置方式

    
    <bean id="person" class="com.pshdhx.aop.xml.Person">bean>
    <bean id="personProxy" class="com.pshdhx.aop.xml.PersonProxy">bean>
    <aop:config>
        <aop:pointcut id="p" expression="execution(* com.pshdhx.aop.xml.Person.add(..))"/>
    
        <aop:aspect ref="personProxy">
            <aop:before method="before" pointcut-ref="p"/>
        aop:aspect>
    aop:config>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    JdbcTemplate

    Spring框架对JDBC进行了封装,使用JdbcTemplate方便实现对数据库的操作。

    1、引入jar包

    druid-1.1.9.jar
    mysql-connector-java-5.1.8.jar
    spring-jdbc-5.2.0.M3.jar
    spring-orm-5.2.0.M3.jar
    spring-tx-5.2.0.M3.jar

    增删改操作:

    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:aop="http://www.springframework.org/schema/aop"
           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
                               http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd
                               http://www.springframework.org/schema/aop  http://www.springframework.org/schema/aop/spring-aop.xsd
    ">
    
        <context:property-placeholder location="classpath:jdbc.properties"/>
        <context:component-scan base-package="com.pshdhx.jdbctemplate"/>
        <aop:aspectj-autoproxy>aop:aspectj-autoproxy>
    
    
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="username" value="${db.username}"/>
            <property name="password" value="${db.password}"/>
            <property name="url" value="${db.url}"/>
            <property name="driverClassName" value="${db.driverClassName}"/>
        bean>
    
        <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="dataSource"/>
        bean>
    
    
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    @Repository
    public class UserDaoImpl implements UserDao {
        @Autowired
        private JdbcTemplate jdbcTemplate;
    
        @Override
        public int addUser(User user) {
            String sql = "insert user(user_id,username,user_status) values (?,?,?)";
            Object []args = {user.getUserId(),user.getUserName(),user.getUserStatus()};
            int update = jdbcTemplate.update(sql, args);
            return update;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    查询操作:某个值count(*),某条记录,多条记录的集合

    public int findCount() {
        String sql = "select count(*) from user";
        Integer integer = jdbcTemplate.queryForObject(sql, Integer.class);
        return integer;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    查询某一条记录

    public User findUserById(Integer id) {
        String sql = "select * from user where user_id = ?";
        Object []args = {id};
        User user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), args);
        return user;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    查询多条记录

    @Override
    public List<User> queryAllUser() {
        List<User> userL = jdbcTemplate.query("select * from user", new BeanPropertyRowMapper<User>(User.class));
        return userL;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    批量添加:

    @Override
    public void batchImport(List<Object []> userList) {
        String sql = "insert into user values(?,?,?)";
        jdbcTemplate.batchUpdate(sql,userList);
    }
    
    List<Object[]> list = new ArrayList<>();
            Object[] u1 = {12,"12","0"};
            Object[] u2 = {13,"13","1"};
            Object[] u3 = {14,"14","1"};
            list.add(u1);
            list.add(u2);
            list.add(u3);
            userService.batchImport(list);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    事务

    事务特性:

    ​ 原子性:要么都成功,要么都失败。

    ​ 一致性:操作之前和之后,数据一致。

    ​ 隔离性:多个事务操作,不会产生影响。

    ​ 持久性:事务提交之后,存库。

    声明式事务管理

    
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    bean>
    
    
    
    <tx:annotation-driven transaction-manager="transactionManager">tx:annotation-driven>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    propagation:事务的传播行为

    【一个事务的方法被另外一个事务的方法调用,该如何进行处理?】

    1、required传播级别:如果有事务正在运行,当前的方法就在这个事务内运行。否则,就会启动一个新的事务,并在自己的事务内运行。

    举例说明:类是事务A,方法是方法1,类是事务B,方法是方法2。方法1调用方法2,方法1会开启事务A,方法2会加入到事务A

    2、required_new :当前的方法必须启动新事务,并在它自己的事务内运行。如果有事务正在运行,应该将它挂起。

    举例说明:内层事务和外层事务互不影响。

    3、supports:如果有事务在运行,当前的方法就在这个事务内运行。否则,它可以不运行在事务中。

    举例:【方法A单独的调用方法B,如果方法A没有事务,方法B可以不运行在事务中】

    ioslatin:事务的隔离级别

    多事务操作之间不会产生影响

    脏读:读取到了未提交事务的数据。【不提交可能会回滚】

    不可重复读:一个未提交事务,读取到了一个已提交事务修改的数据。
    幻读:一个未提交事务,读取到了一个已提交事务添加的数据。

    脏读不可重复度幻读
    读未提交
    读已提交
    可重复度[Mysql默认]
    串行化
    @Service
    @Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.REPEATABLE_READ)
    public class UserService{
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    事务的其他参数

    1、timeout:事务需要在一定的时间内进行提交。如果不提交,事务需要进行回滚。默认值-1,是不超时的意思。timeout=5,是五秒的意思。

    2、readOnly:是否只读。默认值是false【可以查询,可以增删改】,当设置成true之后,只能进行查询操作。

    3、rollbackFor:回滚【设置哪些异常可以进行回滚】

    4、noRollbackFor:【设置哪些异常不进行异常的回滚】

    @Configuration
    @ComponentScan(basePackages = "com.pshdhx")
    @EnableTransactionManagement
    public class TxConfig {
    
        @Bean
        public DruidDataSource getDruidDataSource(){
            DruidDataSource dataSource = new DruidDataSource();
            dataSource.setUsername("root");
            dataSource.setPassword("pshdhx");
            dataSource.setDriverClassName("com.mysql.jdbc.Driver");
            dataSource.setUrl("jdbc:mysql://localhost:3306/user_db");
            return dataSource;
        }
    
        @Bean
        public JdbcTemplate getJdbcTemplate(DataSource dataSource){
            JdbcTemplate jdbcTemplate = new JdbcTemplate();
            jdbcTemplate.setDataSource(dataSource);
            return jdbcTemplate;
        }
    
        //创建事务管理器
        @Bean
        public DataSourceTransactionManager getDataSourceTransactionManager(DataSource datasource){
            DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
            dataSourceTransactionManager.setDataSource(datasource);
            return dataSourceTransactionManager;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    整合日志框架

    引入jar包

    log4j-core-2.11.2.jar
    log4j-slf4j-impl-2.11.2.jar
    slf4j-api-1.7.30.jar
    log4j-api-2.11.2.jar

    
    
    
    <configuration status="INFO">
        <appenders>
            <console name="Console" target="SYSTEM_OUT">
                    <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} -%msg%n"/>
            console>
        appenders>
    
        <loggers>
            <root level="info">
                <appender-ref ref="Console"/>
            root>
        loggers>
    configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    import com.mysql.jdbc.log.LogFactory;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**
     * @Auther: pshdhx
     * @Date: 2023/09/09/14:49
     * @Description:
     */
    public class UserLogger {
    
        private static final Logger log = LoggerFactory.getLogger(UserLogger.class);
    
        public static void main(String[] args) {
            log.info("测试日志");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    Sui Move智能合约提供更智能和简单的编程
    Jetpack Compose学习(9)——Compose中的列表控件(LazyRow和LazyColumn)
    JavaScript 设计模式之观察者模式
    D. Progressions Covering(思维 + 贪心 + 线段树 + 差分)
    PMP子过程定义总结
    SpringMVC-20-springmvc文件下载
    MatLab命令行常用命令记录
    群晖下虚拟机编译部署WOW服务端TrinityCore
    【DPDK】dpdk样例源码解析之五:dpdk-rss
    MAUI与Blazor共享一套UI,媲美Flutter,实现Windows、macOS、Android、iOS、Web通用UI
  • 原文地址:https://blog.csdn.net/pshdhx/article/details/132777534