框架笔记-Spring【待补充】

框架笔记-Spring【待补充】

JavaEE轻量级开元框架,可以整合其他框架。以SpringFramework为核心的框架。

IOC

将对象的创建交给Spring进行创建管理。

SpringIOC是一个容器,对象在容器中进行创建销毁,控制对象与对象之间的依赖关系。

由IOC容器管理的Java对象称为Spring bean,它与关键字new创建的java对象没有任何区别。

控制反转

将创建对象的权利交给第三方容器负责

将对象和对象之间的关系维护交给第三方容器负责

控制反转思想:依赖注入

根据XML方式注入

获取Bean

1、通过bean的id获取

  <bean id="user" class="com.zhang.first.entity.User"></bean>
    
     //加载spring配置文件,创建对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //获取创建对象
       User user = (User) ac.getBean("user");//getBean是加载Beanz中的id,创建对象
        //操作
        user.add();

        logger.info("执行完毕");

2、通过类型获取

 //加载spring配置文件,创建对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //获取创建对象
       User user = (User) ac.getBean(User.class);//,创建对象
        //操作
        user.add();

        logger.info("执行完毕");

3、根据ID和类型获取

public void testUser3(){
        //加载spring配置文件,创建对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //获取创建对象
        User user = (User) ac.getBean("user",User.class);//根据ID和类型获取对象
        //操作
        user.add();

        logger.info("执行完毕");
    }

当类型获取bean时,要求IOC容器中指定类型(class)的bean有且只能有一个,不能有两个不同id,相同class的bean存在

 <bean id="userDaoImpl" class="com.zhang.first.dao.UserDaoImpl"></bean>
     
    //测试接口声明,实现类实例化
    //UserDao userDao = new UserDaoImpl();
   //加载spring配置文件,创建对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //获取创建对象
     //   UserDao userdao = (UserDao) ac.getBean("userDaoImpl");//getBean通过id获取对象和通过class获取都一样
UserDao userdao = (UserDao) ac.getBean(UserDao.class);
        //操作
        userdao.add();

        logger.info("执行完毕");

当bean里有一个接口有两个接口的实例化对象时,通过类获取就会报错

 public void testUser4(){
        //加载spring配置文件,创建对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //获取创建对象
        UserDao userdao = (UserDao) ac.getBean("userDaoImpl");//getBean是加载Beanz中的id,创建对象
        //操作
        userdao.add();

        UserDao userdao2 = (UserDao) ac.getBean("personDaoImpl");//getBean是加载Beanz中的id,创建对象
        //操作
        userdao2.add();

        UserDao userdao3 = (UserDao) ac.getBean(UserDao.class);//上述通过BeanId 获取对象没问题,通过类获取就会报错,因为一个接口,不知道实现哪个类
        //操作
        userdao3.add();
        logger.info("执行完毕");


    }

Spring创建对象的过程中,将对象的属性值通过配置进行注入

常见的实现方式:

set注入

构造注入

Set注入

entity类中,要有set方法,Bean中可直接设置priperty设置值

<bean id="book" class="com.zhang.first.entity.Book">
        <property name="bname" value="前端开发"></property>
        <property name="author" value="小张"/>
    </bean>

构造注入

<bean id="book2" class="com.zhang.first.entity.Book">
        <constructor-arg name="bname" value="开发"></constructor-arg>
        <constructor-arg name="author" value="小张"></constructor-arg>
    </bean> 

BeanFactory工厂 +反射进行实例化

特殊类型注入

如果中间的值为null,则需加null标签

<constructor-arg name="other" ><null></null></constructor-arg>

如果里面有特殊符号,需要转义

<constructor-arg name="other" value="&lt;&gt;"></constructor-arg>  <!--里面是特殊符号需要转义-->

特殊符号还可以使用CDATA

<!--        CDATA标识character,里面是纯文本内容,写什么符号都随意-->
        <constructor-arg name="other" >
            <value>
                <![CDATA[a<b]]>
            </value>
        </constructor-arg>
对象类型注入

引入外部bean:ref引入beanID

<bean id="dept" class="com.zhang.first.entity.Depart">
        <property name="name" value="安保部"></property>
    </bean>

<!--    需要引入depart的bean-->
    <bean id="empy" class="com.zhang.first.entity.Employee">
        <property name="name" value="zhang"></property>
<!--        注入对象属性:ref表示引入bean为refz值的对象-->
        <property name="dept" ref="dept"></property>
    </bean>

引入内部bean:

 <bean id="dept2" class="com.zhang.first.entity.Depart">
        <property name="name" value="财务部"></property>
    </bean>

    <!--    需要引入depart的bean-->
    <bean id="empy2" class="com.zhang.first.entity.Employee">
        <property name="name" value="huang"></property>
        <!--        注入对象属性:ref表示引入bean为refz值的对象-->
        <property name="dept">
            <bean id="dept2" class="com.zhang.first.entity.Depart">
                <property name="name" value="财务部"></property>
            </bean>
        </property>
    </bean>

级联注入:

<!--级联注入-->
    <bean id="dept3" class="com.zhang.first.entity.Depart">
        <property name="name" value="财务部"></property>
    </bean>

    <bean id="empy3" class="com.zhang.first.entity.Employee">
        <property name="name" value="zhao"></property>
        <!--        注入对象属性:ref表示引入bean为refz值的对象-->
        <property name="dept" ref="dept3"></property>
        <property name="dept.name" value="测试部"></property>   <!--  此为级联注入-->
    </bean>

数组类型注入:

<!--数组类型注入=========================-->
<bean id="dept4" class="com.zhang.first.entity.Depart">
    <property name="name" value="财务部"></property>
</bean>

<bean id="empy4" class="com.zhang.first.entity.Employee">
    <property name="name" value="zhao"></property>
    <!--        注入对象属性:ref表示引入bean为refz值的对象-->
    <property name="dept" ref="dept3"></property>
    <property name="dept.name" value="测试部"></property>   <!--  此为级联注入-->
    <property name="loves">
        <array>
            <value>吃饭</value>
            <value>睡觉</value>
            <value>哈哈</value>
        </array>
    </property>
</bean>
<!--数组类型注入 ====================-->

注入List集合:

<!--List类型注入=========================-->
    <bean id="dept5" class="com.zhang.first.entity.Depart">
        <property name="name" value="财务部"></property>
        <property name="empy">
            <list>
               <ref bean="empy5"></ref>   <!--将其他的list引入-->
                <ref bean="empy6"></ref>
            </list>
        </property>
    </bean>

    <bean id="empy5" class="com.zhang.first.entity.Employee">
        <property name="name" value="找"></property>
        <!--        注入对象属性:ref表示引入bean为refz值的对象-->
        <property name="dept" ref="dept5"></property>

        <property name="loves">
            <array>
                <value>吃饭</value>
                <value>睡觉</value>
                <value>哈哈</value>
            </array>
        </property>
    </bean>
    <bean id="empy6" class="com.zhang.first.entity.Employee">
        <property name="name" value="张"></property>
        <!--        注入对象属性:ref表示引入bean为refz值的对象-->
        <property name="dept" ref="dept5"></property>

        <property name="loves">
            <array>
                <value>打篮球</value>
                <value>攀岩</value>
                <value>滑冰</value>
            </array>
        </property>
    </bean>
    <!--List类型注入 ====================-->

注入Map集合:

<!--    Map注入================-->
    <bean id="tea" class="com.zhang.first.entity.Teacher">
        <property name="td" value="11"></property>
        <property name="tname" value="张老师"></property>
    </bean>
    <bean id="tea2" class="com.zhang.first.entity.Teacher">
        <property name="td" value="12"></property>
        <property name="tname" value="赵老师"></property>
    </bean>

    <bean id="stu" class="com.zhang.first.entity.Student">
        <property name="sid" value="s01"></property>
        <property name="sname" value="小梨花"></property>
        <property name="teacher">
            <map>
                <entry>
                    <key>
                        <value>11</value>
                    </key>
                    <ref bean="tea"></ref>
                </entry>
                <entry>
                    <key>
                        <value>12</value>
                    </key>
                    <ref bean="tea2"></ref>
                </entry>
            </map>
        </property>
    </bean>
    <!--    Map注入================-->

组合注入:使用util,需要引入约束

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       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">
<!--    组合注入================-->
    <bean id="lesson" class="com.zhang.first.entity.Lesson">
        <property name="lid" value="l01"></property>
        <property name="lname" value="语文"></property>
    </bean>
    <bean id="lesson2" class="com.zhang.first.entity.Lesson">
        <property name="lid" value="l02"></property>
        <property name="lname" value="数学"></property>
    </bean>

    <bean id="tea3" class="com.zhang.first.entity.Teacher">
        <property name="td" value="11"></property>
        <property name="tname" value="张老师"></property>
    </bean>
    <bean id="tea4" class="com.zhang.first.entity.Teacher">
        <property name="td" value="12"></property>
        <property name="tname" value="赵老师"></property>
    </bean>


    <bean id="stu2" class="com.zhang.first.entity.Student">
        <property name="sid" value="s01"></property>
        <property name="sname" value="小梨花"></property>
        <property name="teacher" ref="teaMap"></property>
        <property name="lessons" ref="lessonList"></property>
    </bean>

    <util:list id="lessonList">
        <ref bean="lesson"/>
        <ref bean="lesson2"/>
    </util:list>

    <util:map id="teaMap">
       <entry>
           <key>
               <value>t01</value>
           </key>
           <ref bean="tea3"></ref>
       </entry>
        <entry>
            <key>
                <value>t02</value>
            </key>
            <ref bean="tea4"></ref>
        </entry>

    </util:map>
    <!--    组合注入================-->

p命名空间注入

<!--    p命名空间注入==============-->
    <bean id="stu3" class="com.zhang.first.entity.Student"
          p:sid="s03"
    p:sname="小明"
    p:lessons-ref="lessonList"
    p:teacher-ref="teaMap">

    </bean>
    <!--    p命名空间注入==============-->
引入外部文件注入

例如设置mysql值

一般用properties,创建spring配置文件,引入context命名空间,引入属性文件,使用表达式

<!--约束-->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       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
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

新建jdbc.properties

jdbc.username=root
jdbc.password=mysql
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ceshi?serverTimeZone=UTC

在XML文件中引入jdbc.properties路径,注入DruidDataSource

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

<!--    引入jdbc.properties文件-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

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

</beans>

Scope属性

Bean的作用域:

多实例prototype:获取bean时创建对象

单实例Singleton:默认,IOC容器初始化时创建对象

Bean的生命周期:

Bean对象创建(无参构造)

Bean对象属性赋值

bean后置处理器(初始化前)

Bean初始化

Bean后置处理器(初始化后)

Bean对象创建完成,可以使用

bean对象销毁

IOC容器关闭

FactoryBean

创建实现类,实现FactoryBean方法,可以实现类实例化

public class MyFactoryBean implements FactoryBean<User> {
    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }

    @Override
    public User getObject() throws Exception {
        return new User();
    }

    @Override
    public Class<?> getObjectType() {
        return User.class;
    }
}

读取配置文件,即可创建User实例

根据注解方式注入

引入依赖

开启组件扫描

<!--    自动扫描包-->
    <context:component-scan base-package="com.zhang.annotation">
<!--        排除类不扫描,expression为全类名-->
        <context:exclude-filter type="annotation" expression="com.zhang.annotation.entity.User"/>
        
    </context:component-scan>
注解说明
@Component扫描Bean,可以作用在任何层次,Controller、Service、Dao、Entity 等
@Repository作用在dao层,功能和@Component相同
@Service作用在Serviceceng ,功能同上
@Controller作用在Controller层,功能同上

@Autowired 根据类型进行装配

@Autowired
private UserDao dao; // 属性注入


private UserDao dao;
@Autowired
public void setDao (UserDao dao){ //Set方法注入
  this.dao = dao
}

//构造方法注入
//形参注入

//使用两个注解,使用名称注入,此种方法是一个接口,可能有多个实现类,使用Qualifier可以指定实现类 
@Autowired
@Qualifier(value="userRedisDaoImpl")
private UserDao dao;

@Resource

JDK中的,默认根据名称装配,只能用在set方法或属性上,JDK8不需要引入依赖,其他需要引入依赖

<!-- https://mvnrepository.com/artifact/jakarta.annotation/jakarta.annotation-api -->
<dependency>
    <groupId>jakarta.annotation</groupId>
    <artifactId>jakarta.annotation-api</artifactId>
    <version>2.1.1</version>
</dependency>

需要在其他注解上声明名称,Resource注解上声明name。如果resource不指定名称,那么根据属性名字进行注入

@Service("myService")

@Resource(name="myServiceImpl")
private UserService service;

@Resource
private UserService service; //没有指定名称,根据service名称匹配@Service("service")的

//@Resource没有指定名称,其他注解也没有指定名称,会根据类型注入

全注解开发

也没有.xml类扫描包了,可以写配置类@Configuration @ComponentScan(“包名”)开启组件扫描

@Configuration
@ComponentScan("com.zhang.annotation") //扫描全包
public class SpringConfig {
}

 //测试用配置类配置
    @Test
    public void test1(){
      //加载配置类
        ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserController controller = (UserController) ac.getBean(UserController.class);
        controller.run();
    }

AOP

面相切面编程。在不改变代码情况下,增强代码功能,加日志,加权限等。通过预编译的方式和运行期动态代理方式实现,在不修改源码情况下,给程序添加额外的功能。代码更灵活,提高了程序的可复用性。

代理模式

代理对象在执行目标方法前后,可以做其他事情,可以将核心代码和非核心代码分离

静态代理

实现了代码的解耦,但是代码都写死了,不具备灵活性

动态代理

AOP底层是动态代理。使用Proxy.newProxyInstance(ClassLoader,interfaces,handle)

引入依赖

<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>6.0.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>6.0.11</version>
</dependency>
XML实现AOP
<!--Bean.xml文件--> 
<context:component-scan base-package="com.zhang"></context:component-scan>

<!--    开启自动代理,并为目标对象生成代理-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
@Component
@Aspect  //切面类
public class LogAspect {

//    切点表达式
//    executioin(访问修饰符 增强方法返回值 方法所在类全类名 方法名 (参数参数))
    //设置切入点和通知类型
    //通知类型:
    // 前置通知:@Before(value="切入点表达式配置切入点")
    @Before(value="execution(public int com.zhang.CalCulate.*(..))")
    public void beforeMethod(){
        System.out.println("====前置通知====");
    }
    // 返回通知:@AfterReturning()
    @AfterReturning(value="execution(public int com.zhang.CalCulate.*(..))",returning = "result")
    public void afterReturn(JoinPoint joinPoint,Object result){
        String methodName = joinPoint.getSignature().getName();
        Object[]  args = joinPoint.getArgs();
        System.out.println("====返回通知====" +methodName +"方法参数:【" + Arrays.toString(args)+"】结果:"+ result+"========");
    }
    // 异常通知:AfterThrowing()
    @AfterThrowing(value="execution(public int com.zhang.CalCulate.*(..))",throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint,Object ex){
        String methodName = joinPoint.getSignature().getName();
        Object[]  args = joinPoint.getArgs();
        System.out.println("====异常通知====" +methodName +"方法参数:【" + Arrays.toString(args)+"】异常信息:"+ ex+"========");
    }
    // 后置通知:@After()
    @After(value="execution(public int com.zhang.CalCulate.*(..))")
    public void after(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        Object[]  args = joinPoint.getArgs();
        System.out.println("====后置通知====" +methodName +"方法参数:" + Arrays.toString(args)+"========");
    }
    // 环绕通知:@Around(),在之前之后都会通知
    @Around(value="execution(public int com.zhang.CalCulate.*(..))")
    public void around(ProceedingJoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        Object[]  args = joinPoint.getArgs();
        System.out.println("====环绕通知====" +methodName +"方法参数:" + Arrays.toString(args)+"========");
    }

}

//测试
@Test
    public void test(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        CalCulate calculate = (CalCulate) ac.getBean(CalCulate.class);
        calculate.add(1,2);
    }

重用切面表达式

 //重用切面表达式
    @Pointcut("execution(public int com.zhang.CalCulate.*(..))")
    public void printcut(){}
// 在通知类型value中可以直接value="printcut()"

切面配置在XML文件中,LogAspect类中不用注入@After()@Before()等通知类型了

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">


    <context:component-scan base-package="com.zhang"></context:component-scan>

<!--    开启自动代理,并为目标对象生成代理-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

    <aop:config>
<!--       配置切面类 -->
        <aop:aspect ref="logAspect">
<!--                        配置切入点-->
            <aop:pointcut id="pointcut" expression="execution(public int com.zhang.CalCulate.*(..))"/>

<!--            配置五中通知类型-->

<!--            前置通知-->
            <aop:before method="beforeMethod" pointcut-ref="pointcut"></aop:before>
<!--            后置通知-->
            <aop:after method="after" pointcut-ref="pointcut"></aop:after>
<!--            返回通知-->
            <aop:after-returning method="afterReturn" pointcut-ref="pointcut" returning="result" ></aop:after-returning>
<!--            异常通知-->
            <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="ex"></aop:after-throwing>
<!--            环绕通知-->
            <aop:around method="around" pointcut-ref="pointcut"></aop:around>
        </aop:aspect>
    </aop:config>
</beans>

模块组成

Spring-core:核心模块:IOC、AOP、Resource

Spring-data-access:JDBC,ORM,OXM

Spring-web:Spring-mvc,Spring-web

Spring-test:对Junit进行集成

实例开发

创建对象的过程:

加载xml文件

对文件解析

获取xml中bean标签的属性值,id-class

通过反射,根据类路径全路径创建对象

将对象放在Map<String,BeanDefinition>beanDefintionMap中,key存放id,BeanDefinition存放对象

引入Spring相关依赖

<dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.3.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

创建类,定义属性和方法

构建配置文件,XXX.xml

<!--    完成对象的创建-->
    <!--id:w唯一标识
    class:包+类名-->
    <bean id="user" class="com.zhang.first.entity.User"></bean>

进行测试

@Test
    public void testUser(){
        //加载spring配置文件,创建对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //获取创建对象
       User user = (User) ac.getBean("user");//getBean是加载Beanz中的id,创建对象
        //操作
        user.add();

    }

日志log4j

级别

  • Trace:最低级别,追踪程序的执行
  • Debug: 调试
  • info:输出重要信息
  • Warn: 警告
  • error:错误
  • Fatal:严重错误

级别高的会自动屏蔽级别低的日志

操作实例

  • 引入依赖

  • 在resource下新建log4j2.xml

     private Logger logger = LoggerFactory.getLogger(TestUser.class);
    
<?xml version="1.0" encoding="UTF-8"?>
<configuration >
    <loggers>
<!--        一般从高到低 trace debug info warn error fatal-->
        <root level="Debug">  <!--  级别高的会覆盖级别低的日志,即只输出比定义的级别更高的日志-->
            <appender-ref ref="mylog" />
            <appender-ref ref="rollingFile" />
            <appender-ref ref="myflie" />
        </root>
    </loggers>

    <appenders>
        <console name="mylog" target="SYSTEM_OUT">  <!--  输出信息到控制台-->
<!--            控制台输出日志格式-->
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-3level %logger{1024} -%msg%n ">

            </PatternLayout>
        </console>


<!--        文件打印出所有信息,每次运行程序会自动清空,由append属性决定,适合临时测试用-->
        <File name="myFile" filename="/Users/nianxinshiyideqiongxiaozi/Desktop/myWorkSpace/mymymy/spring_log/test.log" append="false">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %class{36} %L %M -%msg%xEx%n "/>
        </File>

<!--        可以打印出所有信息,每次超过size 这个size小的日志会自动存入按年份-月份建立的文件夹下进行压缩作为存档-->
        <RollingFile name="rollingFile" filename="/Users/nianxinshiyideqiongxiaozi/Desktop/myWorkSpace/mymymy/spring_log/app.log" filePattern="log/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.">
            <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class"></PatternLayout>
            <SizeBasedTriggeringPolicy size="50MB"/>
            <DefaultRolloverStrategy max="20"></DefaultRolloverStrategy>   <!--     如不设置此属性,则默认为最多同一文件夹下7个文件,这里设置了20-->
        </RollingFile>
    </appenders>
</configuration>

事务

JDBCTemplate

依赖

<!--        数据库-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>

        <!--        数据源-->
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.18</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>6.0.11</version>
        </dependency>

XML文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

<!--    扫描全包-->
    <context:component-scan base-package="com.zhang"></context:component-scan>
<!--    引入外部文件-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

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

    </bean>

<!--    创建JDBCTemplate,注入数据源-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="druidDataSource"></property>
    </bean>
</beans>
 @Autowired
    private JdbcTemplate jdbcTemplate;



    //添加修改删除
    @Test
    void run(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        User user = (User)ac.getBean(User.class);
        //添加
        String sql = "insert into t_user values(?,?,?)";
        int rows = jdbcTemplate.update(sql,"小明",20,"男");
        System.out.println(rows);
    }

开启事务

<!--    注入事务-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="druidDataSource"></property>
    </bean>

<!--    开启事务的注解驱动,通过@transactional所表示的方法或表示类中的方法-->
    <tx:annotation-driven transaction-manager="transactionManager"/>

只读:只能查询,不能增删改

 @Transantional(ReadOnly=true)

超时:在设置超时时间内没有完成,抛出异常回滚

 @Transantional(timeout=3)    //3秒超时就回滚

回滚策略:设置哪些异常不会滚

 @Transantional(noRollbackFor=ArithmeticException.class)    //1/0这样的不回滚

隔离级别:脏读、不可重复度、幻读


全注解开启事务

定义一个Config类,上面@EnableTransactionManagement开启事务管理

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("com.zhang")
@EnableTransactionManagement  //开启事务
public class SpringConfig {

    //配置数据源
    @Bean
    public DataSource getDataSource(){
        DruidDataSource dds = new DruidDataSource();
        dds.setUrl("jdbc:mysql://localhost:3306/ceshi");
        dds.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dds.setUsername("root");
        dds.setPassword("mysql");
        return dds;
    }

    //配置JDBCTemplate
    @Bean(name="jdbcTemplate")
    public JdbcTemplate getJDBCTemplate(DataSource dataSource){
        JdbcTemplate template = new JdbcTemplate();
        template.setDataSource(dataSource);
        return  template;
    }
    
    //配置事务
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){
        DataSourceTransactionManager dstm = new DataSourceTransactionManager();
        dstm.setDataSource(dataSource);
        return dstm;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值