Spring笔记总结

Spring学习笔记总结

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一,第一个spring程序(控制反转)

1.0在pow文件中导入依赖spring四个核心包

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.2.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>5.2.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-beans</artifactId>
  <version>5.2.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-expression</artifactId>
  <version>5.2.9.RELEASE</version>
</dependency>

1.1类路径下创建spring的applicationContext.xml文件

<!--1.scope=“prototype”,使用bean对象时才会创建,表示当前Bean为原型模式
    2.scope=“singleton”,容器创建时就会创建bean对象,表示当前Bean为单例模式,是默认的模式
    3.scope的取值还可以是:request、session。
<?xml version="1.0" encoding="UTF-8"?>
<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">

    <!--相当于:ISomeService someService = new SomeServiceImpl();-->
    <!--1.scope=“prototype”,使用bean对象时才会创建,表示当前Bean为原型模式
        2.scope=“singleton”,容器创建时就会创建bean对象,表示当前Bean为单例模式,是默认的模式
        3.scope的取值还可以是:request、session。
    -->
    <bean id="someService" class="com.yyf.service.SomeServiceImpl" scope="prototype"/>

</beans>

1.2service接口

package com.yyf.service;

public interface ISomeService {
    void doSome();
}

1.3service接口实现类

package com.yyf.service;

public class SomeServiceImpl implements ISomeService {
    public SomeServiceImpl() {
        System.out.println("调用执行无参构造器");
    }

    @Override
    public void doSome() {
        System.out.println("执行doSome()方法");
    }
}

1.3测试类

  • ApplicationContext容器:
    • 当容器对象被创建时,会自动将容器中所有的Bean创建
    • 优点:系统响应速度快
    • 不足:浪费系统资源
    • BeanFactory容器:
    • 当容器对象被创建时,并不会自动创建容器中的Bean,
    • 只有当真正使用该Bean时才会创建这个bean
    • 优点:节省系统资源
    • 缺点:相对来说,系统响应速度慢
public class MyTest
{
    // 当前代码存在的问题:
    // 当前测试类与SomeServiceImpl类完全耦合在一起
    @Test
    public void test01(){
        System.out.println("test01");
        ISomeService someService = new SomeServiceImpl();
        someService.doSome();
    }

    @Test
    public void test02(){
        System.out.println("test02");
        // 获取Spring容器对象,加载spring配置文件(类路径下)
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        ISomeService someService = (ISomeService) ac.getBean("someService");
        someService.doSome();
    }
    @Test
    public void test03(){
        System.out.println("test03");
        // 获取Spring容器对象,加载spring配置文件(项目的根目录下)
        ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
        ISomeService someService = (ISomeService) ac.getBean("someService");
        someService.doSome();
    }
    @Test
    public void test04(){
        System.out.println("test04");
        // 获取Spring容器对象,加载spring配置文件(磁盘目录下D盘)
        ApplicationContext ac = new FileSystemXmlApplicationContext("d:\\applicationContext.xml");
        ISomeService someService = (ISomeService) ac.getBean("someService");
        someService.doSome();
    }
    @Test
    public void test05(){
        System.out.println("test05");
        // 获取Spring容器对象,加载spring配置文件(
        BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
        ISomeService someService = (ISomeService) bf.getBean("someService");
        someService.doSome();
    }

    /*
    * ApplicationContext容器:
    * 当容器对象被创建时,会自动将容器中所有的Bean创建
    * 优点:系统响应速度快
    * 不足:浪费系统资源
    *
    * BeanFactory容器:
    * 当容器对象被创建时,并不会自动创建容器中的Bean,
    * 只有当真正使用该Bean时才会创建这个bean
    * 优点:节省系统资源
    * 缺点:相对来说,系统响应速度慢
    *
    * */
}
2.1依赖注入(设值注入)

2.1.1实体类

public class Student {
    private String name;
    private int age;
    private School school;

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

    public void setAge(int age) {
        this.age = age;
    }

    public void setSchool(School school) {
        this.school = school;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", school=" + school +
                '}';
    }
}
public class School {
    private String sname;

    public void setSname(String sname) {
        this.sname = sname;
    }

    @Override
    public String toString() {
        return "School{" +
                "sname='" + sname + '\'' +
                '}';
    }
}

2.1.2spring的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<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="mySchool" class="com.yyf.di01.School">
        <property name="sname" value="安阳师范学院"/>
    </bean>
    <!--设值注入:底层调用属性对应的set方法-->
    <bean id="student" class="com.yyf.di01.Student">
        <property name="name" value="张三"/>
        <property name="age" value="16"/>
        <property name="school" ref="mySchool"/>
    </bean>

</beans>

2.1.3测试类

public class MyTest
{
    // 设值注入
    @Test
    public void test01(){
        // 获取Spring容器对象,加载spring配置文件(类路径下)
        ApplicationContext ac = new ClassPathXmlApplicationContext("com/yyf/di01/applicationContext.xml");
        Student student = (Student) ac.getBean("student");
        System.out.println(student);
    }
}
3.1构造注入
<bean id="mySchool" class="com.yyf.di02.School">
    <constructor-arg name="sname" value="郑州大学"/>
</bean>
<!--构造注入:底层调用的带参数的构造方法-->
<bean id="student" class="com.yyf.di02.Student">
    <constructor-arg name="name" value="小明"/>
    <constructor-arg name="age" value="15"/>
    <constructor-arg name="school" ref="mySchool"/>
</bean>
4.1p空间注入

注意需要引入p空间注入的约束,默认调用底层属性的set方法xmlns:p="http://www.springframework.org/schema/p"

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

    <bean id="mySchool" class="com.yyf.di03.School" p:sname="河南大学"/>
    <!--p命名空间注入:底层调用属性对应的set方法-->
    <bean id="student" class="com.yyf.di03.Student" p:name="小红" p:age="18" p:school-ref="mySchool"/>

</beans>
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="mySchool" class="com.yyf.di03.School" p:sname="河南大学"/>
    <!--p命名空间注入:底层调用属性对应的set方法-->
    <bean id="student" class="com.yyf.di03.Student" p:name="小红" p:age="18" p:school-ref="mySchool"/>

</beans>
5.1c空间注入

需要引入c空间的约束,默认调用底层的带参的构造方法 xmlns:c="http://www.springframework.org/schema/c"

<?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:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="mySchool" class="com.yyf.di04.School" c:sname="清华大学"/>
    <!--c命名空间注入:底层调用的带参数的构造方法-->
    <bean id="student" class="com.yyf.di04.Student" c:name="李四" c:age="20" c:school-ref="mySchool"/>

</beans>
6.1数组和集合的赋值

6.1.1实体类

package com.yyf.di05;

import java.util.*;

/**
 * company: www.abc.com
 * Author: Administrator
 * Create Data: 2020/11/4 0004
 */
public class Some {
    private String[] names;
    private List<String> myList;
    private List<School> schools;
    private Set<String> mySet;
    private Map<String,Object> myMap;
    private Properties myPros;

    public String[] getNames() {
        return names;
    }

    public List<String> getMyList() {
        return myList;
    }

    public List<School> getSchools() {
        return schools;
    }

    public Set<String> getMySet() {
        return mySet;
    }

    public Map<String, Object> getMyMap() {
        return myMap;
    }

    public Properties getMyPros() {
        return myPros;
    }

    public void setNames(String[] names) {
        this.names = names;
    }

    public void setMyList(List<String> myList) {
        this.myList = myList;
    }

    public void setSchools(List<School> schools) {
        this.schools = schools;
    }

    public void setMySet(Set<String> mySet) {
        this.mySet = mySet;
    }

    public void setMyMap(Map<String, Object> myMap) {
        this.myMap = myMap;
    }

    public void setMyPros(Properties myPros) {
        this.myPros = myPros;
    }

    @Override
    public String toString() {
        return "Some{" +
                "names=" + Arrays.toString(names) +
                ", myList=" + myList +
                ", schools=" + schools +
                ", mySet=" + mySet +
                ", myMap=" + myMap +
                ", myPros=" + myPros +
                '}';
    }
}

6.1.2配置文件

<?xml version="1.0" encoding="UTF-8"?>
<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="aynu" class="com.yyf.di05.School">
        <property name="sname" value="安阳师范学院"/>
    </bean>
    <bean id="htu" class="com.yyf.di05.School">
        <property name="sname" value="河南师范大学"/>
    </bean>
    <!--数组和集合类型属性赋值-->
    <bean id="some" class="com.yyf.di05.Some">
        <!--数组赋值可以简写,简写时中间逗号应该为英文-->
        <property name="names" value="张三,李四">
            <!--<array>
                <value>张三</value>
                <value>李四</value>
                <value>王五</value>
            </array>-->
        </property>
        <property name="myList">
            <list>
                <value>河南</value>
                <value>河北</value>
                <value>湖南</value>
            </list>
        </property>
        <property name="schools">
            <list>
                <ref bean="aynu"/>
                <ref bean="htu"/>
            </list>
        </property>
        <property name="mySet">
            <set>
                <value>本科</value>
                <value>硕士</value>
                <value>博士</value>
            </set>
        </property>
        <property name="myMap">
            <map>
                <entry key="mobile" value="123456"/>
                <entry key="QQ" value="654321"/>
            </map>
        </property>
        <property name="myPros">
            <props>
                <prop key="email">123456@qq.com</prop>
                <prop key="address">文明大道</prop>
            </props>
        </property>
    </bean>

</beans>
7.1域属性自动注入(byType byName)xml实现

7.1.1实体类

public class Student {
    private String name;
    private int age;
    private School school;
public class School {
    private String sname;
public class MiddleSchool extends School {
    private String address;

7.1.2映射文件

如果使用byName会自动注入Bean的id和属性名相同的bean
如果使用byType则只能存在对应的一个类型的Bean,并且包含其子类。
<bean id="mySchool" class="com.yyf.di06.School">
    <property name="sname" value="清华大学"/>
</bean>
<bean id="school" class="com.yyf.di06.MiddleSchool">
    <property name="sname" value="一中"/>
    <property name="address" value="文明大道"/>
</bean>
<!--<bean id="yourSchool" class="com.yyf.di06.School">
    <property name="sname" value="北京大学"/>
</bean>-->
<!--域属性自动注入
    byType:对应属性符合is-a关系类型的Bean只能存在一个
    byName:Bean的id和属性名相同的bean自动注入
-->
<bean id="student" class="com.yyf.di06.Student" autowire="byName">
    <property name="name" value="小绿"/>
    <property name="age" value="16"/>
</bean>
8.1域属性自动注入(byType byName)注解实现

注解实现需要在pow文件中导入aop的包

 <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.2.9.RELEASE</version>
    </dependency>

8.1.1首先在spring主配置文件中注册组件扫描器

<context:component-scan base-package="com.yyf.di01"/>
<?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
       https://www.springframework.org/schema/context/spring-context.xsd">

    <!--注册组件扫描器-->
    <!--
        base-package="com.yyf.di01"表示的意义为:
        系统从com.yyf.di01的包及其所有子孙包中扫描组件,包含自身
        base-package="com.yyf.di01.*"表示的意义为:
        系统从com.yyf.di01的所有子孙包中扫描组件,不包含其自身
    -->
    <context:component-scan base-package="com.yyf.di01"/>

</beans>

8.1.2在实体类中使用注解注入

package com.yyf.di01;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;

*@Component功能相同,但意义不同的其他注解还有三个
* @Repository:注解在Dao上
* @Service:注解在Service上
* @Controller:注解处理器上

@Component("student")
public class Student {
    @Value("小红")
    private String name;
    @Value("16")
    private int age;
    //@Autowired //相当于byType自动注入
    //@Qualifier("mySchool") //相当于byName注入,但需要和@Autowired一起使用
    //@Resource // 默认byType注入
    @Resource(name = "mySchool") //加上name属性赋值后为byName注入
    private School school;

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

    public void setAge(int age) {
        this.age = age;
    }

    public void setSchool(School school) {
        this.school = school;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", school=" + school +
                '}';
    }
}

二、面向切面的编程

2.1引入依赖(除spring的四个核心包)

 <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.6</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.2.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.2.9.RELEASE</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
    <dependency>
      <groupId>aopalliance</groupId>
      <artifactId>aopalliance</artifactId>
      <version>1.0</version>
    </dependency>

2.1.1方法接口类

package com.yyf.service;

public interface ISomeService {
    void doFirst();
    void doSecond();
    String doThird();
}

2.1.2接口实现类

package com.yyf.service;

public class SomeServiceImpl implements ISomeService {
    @Override
    public void doFirst() {
        System.out.println("执行doFirst()方法!");
    }
    @Override
    public void doSecond() {
        System.out.println("执行doSecond()方法!");
        //int a = 1/0;
    }

    @Override
    public String doThird() {
        System.out.println("执行doThird()方法!");
        return "aynu";
    }
}

2.1.3spring主配置文件

注意切入点表达式中的规范
execution(访问权限 返回类型 全限定性方法名(参数列表) 抛出的异常 )
其中 返回类型 和 方法名 是不能省略的
<?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: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/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--注册主业务(目标)对象-->
    <bean id="someService" class="com.yyf.service.SomeServiceImpl"/>
    <!--注册切面-->
    <bean id="myAspect" class="com.yyf.service.MyAspect"/>

    <!--AOP配置-->
    <aop:config>
        <!--切入点表达式-->
        <aop:pointcut id="doFirstPC" expression="execution(* *..SomeServiceImpl.doFirst())"/>
        <aop:pointcut id="doSecondPC" expression="execution(* *..SomeServiceImpl.doSecond())"/>
        <aop:pointcut id="doThirdPC" expression="execution(* *..SomeServiceImpl.doThird())"/>
        <aop:pointcut id="doAllPC" expression="execution(* *..SomeServiceImpl.*())"/>
        <!--切面配置-->
        <aop:aspect ref="myAspect">
            <!--前置通知-->
            <aop:before method="before" pointcut-ref="doFirstPC"/>
            <aop:before method="before2" pointcut-ref="doAllPC"/>

            <!--后置通知-->
            <aop:after method="after" pointcut-ref="doSecondPC"/>

            <!--返回通知-->
            <aop:after-returning method="afterReturning" pointcut-ref="doSecondPC"/>
            <aop:after-returning method="afterReturning2" pointcut-ref="doSecondPC" returning="result"/>

            <!--环绕通知-->
            <aop:around method="around" pointcut-ref="doThirdPC"/>

            <!--异常通知-->
            <aop:after-throwing method="afterThrowing" pointcut-ref="doSecondPC"/>
            <aop:after-throwing method="afterThrowing2" pointcut-ref="doSecondPC" throwing="ex"/>
        </aop:aspect>
    </aop:config>

</beans>

2.1.4切面类

package com.yyf.service;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class MyAspect {
    //前置通知
    public void before(){
        System.out.println("执行前置通知before()方法!");
    }
    public void before2(JoinPoint jp){
        System.out.println("执行前置通知before2()方法 jp = " + jp);
    }
    //后置通知
    public void after(){
        System.out.println("执行后置通知after()方法!");
    }
    //返回通知
    public void afterReturning(){
        System.out.println("执行返回通知afterReturning()方法!");
    }
    // 返回通知可以获取到目标方法的返回结果,但不能改变其结果
    public void afterReturning2(Object result){
        System.out.println("执行返回通知afterReturning2()方法返回结果为 result = " + result+"xxx");
    }

    //环绕通知
    // 环绕通知可以获取到目标方法的返回结果,还可以改变其值
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("执行环绕通知-目标方法执行之前");
        // 执行目标方法
        Object proceed = pjp.proceed();
        System.out.println("执行环绕通知-目标方法执行之后");
        if (proceed != null){
            proceed = ((String)proceed).toUpperCase();
        }
        return proceed;
    }

    //异常通知
    public void afterThrowing(){
        System.out.println("执行异常通知afterThrowing");
    }
    //异常通知
    public void afterThrowing2(Exception ex){
        System.out.println("执行异常通知afterThrowing ex = " + ex);
    }
}

2.1.5测试类

@Test
public void test01(){
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    ISomeService someService = (ISomeService) ac.getBean("someService");
    someService.doFirst();
    System.out.println("==================================");
    someService.doSecond();
    System.out.println("==================================");
    System.out.println(someService.doThird());

}

运行结果如下

执行前置通知before()方法!
执行前置通知before2()方法 jp = execution(void com.yyf.service.ISomeService.doFirst())
执行doFirst()方法!
==================================
执行前置通知before2()方法 jp = execution(void com.yyf.service.ISomeService.doSecond())
执行doSecond()方法!
执行返回通知afterReturning2()方法返回结果为 result = nullxxx
执行返回通知afterReturning()方法!
执行后置通知after()方法!
==================================
执行前置通知before2()方法 jp = execution(String com.yyf.service.ISomeService.doThird())
执行环绕通知-目标方法执行之前
执行doThird()方法!
执行环绕通知-目标方法执行之后
AYNU

3.1注解实现
3.1.1spring主配置文件

<?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: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/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--注册主业务(目标)对象-->
    <bean id="someService" class="com.yyf.Service.SomeServiceImpl"/>
    <!--注册切面-->
    <bean id="myAspect" class="com.yyf.Service.MyAspect"/>

    <!--Aspectj动态代理生成器-->
    <aop:aspectj-autoproxy/>

</beans>

3.1.2切面类

package com.yyf.Service;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

@Aspect // 切面类
public class MyAspect {
    //前置通知
    @Before("doFirstPC()")
    public void before(){
        System.out.println("执行前置通知before()方法!");
    }
    @Before("doAllPC()")
    public void before2(JoinPoint jp){
        System.out.println("执行前置通知before2()方法 jp = " + jp);
    }
    //后置通知
    @After("doSecondPC()")
    public void after(){
        System.out.println("执行后置通知after()方法!");
    }
    //返回通知
    @AfterReturning("doSecondPC()")
    public void afterReturning(){
        System.out.println("执行返回通知afterReturning()方法!");
    }
    // 返回通知可以获取到目标方法的返回结果,但不能改变其结果
    @AfterReturning(value = "doSecondPC()",returning = "result")
    public void afterReturning2(Object result){
        System.out.println("执行返回通知afterReturning2()方法返回结果为 result = " + result+"xxx");
    }

    //环绕通知
    // 环绕通知可以获取到目标方法的返回结果,还可以改变其值
    @Around("doThirdPC()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("执行环绕通知-目标方法执行之前");
        // 执行目标方法
        Object proceed = pjp.proceed();
        System.out.println("执行环绕通知-目标方法执行之后");
        if (proceed != null){
            proceed = ((String)proceed).toUpperCase();
        }
        return proceed;
    }

    //异常通知
    @AfterThrowing("doSecondPC()")
    public void afterThrowing(){
        System.out.println("执行异常通知afterThrowing");
    }
    //异常通知
    @AfterThrowing(value = "doSecondPC()", throwing = "ex")
    public void afterThrowing2(Exception ex){
        System.out.println("执行异常通知afterThrowing ex = " + ex);
    }

    @Pointcut("execution(* *..SomeServiceImpl.doFirst())")
    private void doFirstPC(){};
    @Pointcut("execution(* *..SomeServiceImpl.doSecond())")
    private void doSecondPC(){};
    @Pointcut("execution(* *..SomeServiceImpl.doThird())")
    private void doThirdPC(){};
    @Pointcut("execution(* *..SomeServiceImpl.*())")
    private void doAllPC(){};
}
三、使用spring的jdbc访问数剧库

dao (Data Access Object)
3.1引入依赖(除核心包)

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jdbc</artifactId>
  <version>5.2.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.47</version>
</dependency>

3.2实体类

public class Student {
    private Integer id;
    private String name;
    private int age;
    private double score;

3.3dao层接口类

public interface IStudentDao {
    int insertStudent(Student student);

    int updateStudent(Student student);

    int deleteStudent(int id);

    Student selectStudentById(int id);

    List<Student> selectAllStudent();

    List<String> selectAllStudentNames();
}

3.4dao接口实现类

注意
1)首先dao接口要继承spring的  JdbcDaoSupport接口,就可以使用spring的内置jdbc对数剧库进行操作。
2)增删改方法都是使用 this.getJdbcTemplate().update(sql,...属性赋值)方法
3)按条件查询使用 this.getJdbcTemplate().queryForObject
(sql,ids,new StudentRowMapper());属性值必须存放在数组(例:ids)中
同时要输入返回数据的指定类型RowMapper<T>
该类型是一个接口类型,需要创建一个类去实现这个接口
public class StudentRowMapper implements RowMapper<Student> {
    // 该方法功能是:将查询结果集中的一行记录数据转换制定的对象,该方法是有框架自动调用执行的
    // 当查询出总的结果集后,框架会自动遍历总的结果集,每遍历一行记录,就会自动调用一次这个方法
    // 也就是说,只要调用了该方法,就说明当前的结果集中还有数据
    // rs:并非查询出的总结果集,而是这个总结果集中一行记录
    // rowNum:当前遍历行在查询出的总结果集中的索引
    @Override
    public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
        System.out.println("第 "+rowNum +" 行");
        Student student = new Student();
        student.setId(rs.getInt("id"));
        student.setName(rs.getString("name"));
        student.setAge(rs.getInt("age"));
        student.setScore(rs.getDouble("score"));
        return student;
    }
}
注意
4)查询全部数据时需要使用
this.getJdbcTemplate().query(sql,new StudentRowMapper());
5)查询多个记录中的一个属性比如所有学生的姓名,需要使用
this.getJdbcTemplate().queryForList(sql,String.class);
属性是什么类型就返回什么类型的.class
public class StudentDaoImpl extends JdbcDaoSupport implements IStudentDao {

    @Override
    public int insertStudent(Student student) {
        String sql = "insert into student (name,age,score) values(?,?,?)";
        return this.getJdbcTemplate().update(sql,student.getName(),student.getAge(),student.getScore());
    }

    @Override
    public int updateStudent(Student student) {
        String sql = "update student set name = ?,age = ?,score = ? where id = ?";
        return this.getJdbcTemplate().update(sql,student.getName(),student.getAge(),student.getScore(),student.getId());
    }

    @Override
    public int deleteStudent(int id) {
        String sql = "delete from student where id = ?";
        return this.getJdbcTemplate().update(sql,id);
    }

    @Override
    public Student selectStudentById(int id) {
        String sql = "select id,name,age,score from student where id = ?";
        Object[] ids = {id};
        return this.getJdbcTemplate().queryForObject(sql,ids,new StudentRowMapper());
    }

    @Override
    public List<Student> selectAllStudent() {
        String sql = "select id,name,age,score from student";
        return this.getJdbcTemplate().query(sql,new StudentRowMapper());
    }

    @Override
    public List<String> selectAllStudentNames() {
        String sql = "select name from student";
        return this.getJdbcTemplate().queryForList(sql,String.class);
    }
}

3.5RowMapper接口

package com.yyf.dao;
import com.yyf.beans.Student;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;

public class StudentRowMapper implements RowMapper<Student> {
    // 该方法功能是:将查询结果集中的一行记录数据转换制定的对象,该方法是有框架自动调用执行的
    // 当查询出总的结果集后,框架会自动遍历总的结果集,每遍历一行记录,就会自动调用一次这个方法
    // 也就是说,只要调用了该方法,就说明当前的结果集中还有数据
    // rs:并非查询出的总结果集,而是这个总结果集中一行记录
    // rowNum:当前遍历行在查询出的总结果集中的索引
    @Override
    public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
        System.out.println("第 "+rowNum +" 行");
        Student student = new Student();
        student.setId(rs.getInt("id"));
        student.setName(rs.getString("name"));
        student.setAge(rs.getInt("age"));
        student.setScore(rs.getDouble("score"));
        return student;
    }
}

3.6service接口类

public interface IStudentService {
    int addStudent(Student student);

    int modifyStudent(Student student);

    int removeStudent(int i);

    Student findStudentById(int id);

    List<Student> findAllStudent();

    List<String> findAllStudentNames();
}

3.7service实现类

public class StudentServiceImpl implements IStudentService {
    private IStudentDao studentDao;

    public void setStudentDao(IStudentDao studentDao) {
        this.studentDao = studentDao;
    }

    @Override
    public int addStudent(Student student) {
        return studentDao.insertStudent(student);
    }

    @Override
    public int modifyStudent(Student student) {
        return studentDao.updateStudent(student);
    }

    @Override
    public int removeStudent(int id) {
        return studentDao.deleteStudent(id);
    }

    @Override
    public Student findStudentById(int id) {
        return studentDao.selectStudentById(id);
    }

    @Override
    public List<Student> findAllStudent() {
        return studentDao.selectAllStudent();
    }

    @Override
    public List<String> findAllStudentNames() {
        return studentDao.selectAllStudentNames();
    }
}

3.9spring主配置文件
使用第三方数据源需要引入第三方依赖

<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid</artifactId>
  <version>1.2.3</version>
</dependency>
<?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: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/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--注册DataSource数据源:Spring内置的-->
    <!--<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///test"/>
        <property name="username" value="root"/>
        <property name="password" value="12345678"/>
    </bean>-->

    <!--druid数据源-->
    <bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///test"/>
        <property name="username" value="root"/>
        <property name="password" value="12345678"/>
    </bean>

    <!--注册dao层对象-->
    <bean id="studentDao" class="com.yyf.dao.StudentDaoImpl">
        <property name="dataSource" ref="myDataSource"/>
    </bean>

    <!--注册Service层对象-->
    <bean id="studentService" class="com.yyf.Service.StudentServiceImpl">
        <property name="studentDao" ref="studentDao"/>
    </bean>

</beans>
四、spring的事务管理

4.1 引入依赖

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.2.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.2.9.RELEASE</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.6</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
    <dependency>
      <groupId>aopalliance</groupId>
      <artifactId>aopalliance</artifactId>
      <version>1.0</version>
    </dependency>

4.2dao接口方法

public interface IAccountDao {
    void insertAccount(String aname, double money);

    void updateAccount(String aname, double money);
}
public interface IStockDao {
    void insertStock(String sname, int amount);

    void updateStock(String sname, int amount);
}

4.3dao接口实现类

public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {
    @Override
    public void insertAccount(String aname, double money) {
        String sql = "insert into account (aname,balance) values(?,?)";
        this.getJdbcTemplate().update(sql,aname,money);
    }

    @Override
    public void updateAccount(String aname, double money) {
        String sql = "update account set balance = balance - ? where aname = ?";
        this.getJdbcTemplate().update(sql,money,aname);
    }
}
public class StockDaoImpl extends JdbcDaoSupport implements IStockDao {
    @Override
    public void insertStock(String sname, int amount) {
        String sql = "insert into stock (sname,count) values(?,?)";
        this.getJdbcTemplate().update(sql,sname,amount);
    }

    @Override
    public void updateStock(String sname, int amount) {
        String sql = "update stock set count = count + ? where sname = ?";
        this.getJdbcTemplate().update(sql,amount,sname);
    }
}

4.4service接口

public interface IStockService {
    void createAccount(String aname,double money);
    void createStock(String sname,int amount);
    void buyStock(String aname,double money,String sname,int amount) throws Exception;
}

4.5service实现类
在用户购买股票时设置一个异常的发生

public class StockServiceImpl implements IStockService {
    private IAccountDao accountDao;
    private IStockDao stockDao;

    public void setAccountDao(IAccountDao accountDao) {
        this.accountDao = accountDao;
    }

    public void setStockDao(IStockDao stockDao) {
        this.stockDao = stockDao;
    }

    @Override
    public void createAccount(String aname, double money) {
        accountDao.insertAccount(aname,money);
    }

    @Override
    public void createStock(String sname, int amount) {
        stockDao.insertStock(sname,amount);
    }

    @Override
    public void buyStock(String aname, double money, String sname, int amount) throws Exception {
        // 银行账户花钱
        accountDao.updateAccount(aname,money);
        if (1 == 1){
            throw new Exception("股票异常");
        }
        //股票账户买入
        stockDao.updateStock(sname,amount);
    }
}
spring事务的五种隔离级别和七种传播方式
一、解释
1.脏读:当一个事务读取某个数据,并对它进行了修改,但是未提交到数据库;这时,另一个事务也访问到了这个数据,并进行了进一步的处理,就产生了未提交的数据依赖的关系。脏数据就是指修改了但未提交,处于待定状态的数据(可能提交也可能回滚)。

2.不可重复读:一个事务多次读取一条数据,在两次读取同一数据的中间,有另一个事务读取这个数据并进行了修改,则会导致该事务两次读取到的数据内容不一致。这就称为不可重复读。

3.幻读:是指当事务非独立执行时发生的一种现象。当一个事务对一个表中的所有行的某项数据进行了修改,例如从“a”修改为“b”;而这时另一个事务对这个表进行了插入操作,依然以“a”的值作为提交的数据。当事务1重新查询的时候,会发现又出现了修改前的数据,以为是未修改,像出现了幻觉一样,这就是幻读,也叫虚读。

二、五种事务隔离级别
Spring在TransactionDefinition接口中定义了一下五个不同的事务隔离级别:

1.ISOLATION_DEFAULT:这是一个PlatformTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。

2.ISOLATION_READ_UNCOMMITTED: 这是事务最低的一个隔离级别。它表示允许事务2访问到事务1未提交的数据,所以,这种隔离级别会产生脏读、幻读、不可重复读。

3.ISOLATION_READ_COMMITTED: 保证了事务1修改后的数据提交后才能被事务2读取,未提交的数据不能被其他事务读取。这就避免了脏读,但不可避免幻读和不可重复读。

4.ISOLATION_REPEATABLE_READ: 既保证了一个事务未提交的已修改数据不能被其他事务读取,也保证了不会发生不可重复读,但不能避免幻读。

5.ISOLATION_SERIALIZABLE: 花费代价最高但是最可靠的一种事务隔离级别。事务被处理为顺序执行,避免了幻读、不可重复读。脏读。

三、七种事务传播机制
在声明式的事务处理中,要配置一个切面, 其中就用到了propagation,表示打算对这些方法怎么使用事务:

1.PROPAGATION_REQUIRED: 如果当前存在一个事务,则支持当前事务。如果没有事务,则开启一个新事务。

2.PROPAGATION_SUPPORTS: 如果存在事务,则支持当前事务。如果没有,以非事务方式执行。

3.PROPAGATION_MANDOTARY: 如果存在事务,则支持当前事务;如果没有一个活动的事务,则抛出异常。

4.PROPAGATION_REQUIRES_NEW: 总是开启一个新事务;如果当前存在事务,就把当期事务挂起。

5.PROPAGATION_NOT_SUPPORTED: 总是非事务的执行,并挂起任何存在的事务。

6.PROPAGATION_NEVER: 总是以非事务方式执行,如果存在一个活动的事务,就抛出异常。

7.PROPAGATION_NESTED: 如果当前事务存在,支持当前事务,并运行在一个嵌套的事务中;如果没有活动的事务,就新建一个事务。

4.6spring主配置文件

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--注册DataSource数据源:Spring内置的-->
    <!--<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///test"/>
        <property name="username" value="root"/>
        <property name="password" value="12345678"/>
    </bean>-->
    <!--===================IoC=======================-->
    <!--druid数据源-->
    <bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///test"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>

    <!--注册dao层对象-->
    <bean id="accountDao" class="com.yyf.dao.AccountDaoImpl">
        <property name="dataSource" ref="myDataSource"/>
    </bean>
    <bean id="stockDao" class="com.yyf.dao.StockDaoImpl">
        <property name="dataSource" ref="myDataSource"/>
    </bean>

    <!--注册Service层对象-->
    <bean id="stockService" class="com.yyf.Service.StockServiceImpl">
        <property name="accountDao" ref="accountDao"/>
        <property name="stockDao" ref="stockDao"/>
    </bean>

    <!--=====================AOP=========================-->
    <!--注册平台事务管理器-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="myDataSource"/>
    </bean>

    <!--注册事务通知-->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <!--指定连接点-->
        <tx:attributes>
            <tx:method name="create*" isolation="DEFAULT" propagation="REQUIRED"/>
            <tx:method name="buyStock" isolation="DEFAULT" propagation="REQUIRED" rollback-for="Exception"/>
        </tx:attributes>
    </tx:advice>

    <!--AOP配置-->
    <aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* *..StockServiceImpl.*(..))"/>
    </aop:config>
</beans>
4.2注解实现

4.2.1spring主配置文件
需要注册事务平台管理器,id默认值为transactionManager
如果更名,则需要事务管理的注解驱动中配置
transaction-manager属性值

<tx:annotation-driven transaction-manager="txManager"/>
<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--注册DataSource数据源:Spring内置的-->
    <!--<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///test"/>
        <property name="username" value="root"/>
        <property name="password" value="12345678"/>
    </bean>-->
    <!--===================IoC=======================-->
    <!--druid数据源-->
    <bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///test"/>
        <property name="username" value="root"/>
        <property name="password" value="12345678"/>
    </bean>

    <!--注册dao层对象-->
    <bean id="accountDao" class="com.yyf.dao.AccountDaoImpl">
        <property name="dataSource" ref="myDataSource"/>
    </bean>
    <bean id="stockDao" class="com.yyf.dao.StockDaoImpl">
        <property name="dataSource" ref="myDataSource"/>
    </bean>

    <!--注册Service层对象-->
    <bean id="stockService" class="com.yyf.Service.StockServiceImpl">
        <property name="accountDao" ref="accountDao"/>
        <property name="stockDao" ref="stockDao"/>
    </bean>

    <!--=====================AOP=========================-->
    <!--注册平台事务管理器-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="myDataSource"/>
    </bean>

    <!--注册事务的注解驱动-->
    <!--
        如果平台事务管理器的id为transactionManager,以下transaction-manager属性不需要配置
        如果平台事务管理器的id不为transactionManager,以下transaction-manager属性必须配置
    -->
    <tx:annotation-driven transaction-manager="txManager"/>

</beans>

4.2.2service实现类,在此类添加注解
只需要在指定方法前加注解

 @Transactional(rollbackForClassName = "Exception")
public class StockServiceImpl implements IStockService {
    private IAccountDao accountDao;
    private IStockDao stockDao;

    public void setAccountDao(IAccountDao accountDao) {
        this.accountDao = accountDao;
    }

    public void setStockDao(IStockDao stockDao) {
        this.stockDao = stockDao;
    }

    @Override
    public void createAccount(String aname, double money) {
        accountDao.insertAccount(aname,money);
    }

    @Override
    public void createStock(String sname, int amount) {
        stockDao.insertStock(sname,amount);
    }

    @Override
    @Transactional(rollbackForClassName = "Exception")
    public void buyStock(String aname, double money, String sname, int amount) throws Exception {
        // 银行账户花钱
        accountDao.updateAccount(aname,money);
        if (1 == 1){
            throw new Exception("股票异常");
        }
        //股票账户买入
        stockDao.updateStock(sname,amount);
    }
}
五、spring与mybatis整合

5.1引入mybatis依赖,spring的核心依赖,数剧库驱动依赖,mybatis和spring整合包,第三方数据源。

 <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.2.9.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.47</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.2.3</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.6</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.6</version>
    </dependency>

5.2实体类

public class Student {
    private Integer id;
    private String name;
    private int age;
    private double score;

5.3.1dao接口

public interface IStudentDao {
    int insertStudent(Student student);

    int updateStudent(Student student);

    int deleteStudent(int id);

    Student selectStudentById(int id);

    List<Student> selectAllStudent();

    List<String> selectAllStudentNames();
}

5.3.2dao接口的映射文件xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yyf.dao.IStudentDao">
    
    <insert id="insertStudent">
        insert into student (name,age,score) values(#{name},#{age},#{score})
    </insert>
    <update id="updateStudent">
        update student set name=#{name},age=#{age},score=#{score} where id = #{id}
    </update>
    <delete id="deleteStudent">
        delete from student where id = #{xx}
    </delete>
    <select id="selectStudentById" resultType="Student">
        select id,name,age,score from student where id = #{id}
    </select>
    <select id="selectAllStudent" resultType="Student">
        select id,name,age,score from student
    </select>
    <select id="selectAllStudentNames" resultType="String">
        select name from student
    </select>
    
</mapper>

5.4service接口

public interface IStudentService {
    int addStudent(Student student);

    int modifyStudent(Student student);

    int removeStudent(int i);

    Student findStudentById(int id);

    List<Student> findAllStudent();

    List<String> findAllStudentNames();
}

5.5service接口实现类

public class StudentServiceImpl implements IStudentService {
    private IStudentDao studentDao;

    public void setStudentDao(IStudentDao studentDao) {
        this.studentDao = studentDao;
    }

    @Override
    public int addStudent(Student student) {
        return studentDao.insertStudent(student);
    }

    @Override
    public int modifyStudent(Student student) {
        return studentDao.updateStudent(student);
    }

    @Override
    public int removeStudent(int id) {
        return studentDao.deleteStudent(id);
    }

    @Override
    public Student findStudentById(int id) {
        return studentDao.selectStudentById(id);
    }

    @Override
    public List<Student> findAllStudent() {
        return studentDao.selectAllStudent();
    }

    @Override
    public List<String> findAllStudentNames() {
        return studentDao.selectAllStudentNames();
    }
}

5.6spring主配置文件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:aop="http://www.springframework.org/schema/aop"
       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/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--注册DataSource数据源:Spring内置的-->
    <!--<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///test"/>
        <property name="username" value="root"/>
        <property name="password" value="12345678"/>
    </bean>-->

    <!--加载jdbc属性文件-->
    <context:property-placeholder location="jdbc.properties"/>

    <!--druid数据源-->
    <bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!--注册sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="myDataSource"/>
        <!--mybatis的主配置文件加载-->
        <property name="configLocation" value="mybatis.xml"/>
    </bean>

    <!--注册dao层代理对象-->
    <!--<bean id="studentDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        <property name="mapperInterface" value="com.yyf.dao.IStudentDao"/>
    </bean>-->
    <!--使用MapperScannerConfigurer生成指定包下接口的代理对象的名称为接口的简单类名-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <property name="basePackage" value="com.yyf.dao"/>
    </bean>

    <!--注册Service层对象-->
    <bean id="studentService" class="com.yyf.Service.StudentServiceImpl">
        <property name="studentDao" ref="IStudentDao"/>
    </bean>

</beans>

5.7mybatis配置文件xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--指定别名-->
    <typeAliases>
        <package name="com.yyf.beans"/>
    </typeAliases>
    <!--注册映射文件-->
    <mappers>
        <package name="com.yyf.dao"/>
    </mappers>
</configuration>

5.7.1引入log2j依赖

 <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>2.14.0</version>
    </dependency>

5.7.2日志配置文件

日志访问级别

分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、ALL或者您定义的级别。Log4j建议只使用四个级别,优先级 从高到低分别是 ERROR、WARN、INFO、DEBUG。 日志记录器(Logger)的行为是分等级的:

日志记录器(Logger)是日志处理的核心组件。log4j具有5种正常级别(Level)。:

1.static Level DEBUG :

DEBUG Level指出细粒度信息事件对调试应用程序是非常有帮助的。

2.static Level INFO

INFO level表明 消息在粗粒度级别上突出强调应用程序的运行过程。

3.static Level WARN

WARN level表明会出现潜在错误的情形。

4.static Level ERROR

ERROR level指出虽然发生错误事件,但仍然不影响系统的继续运行。

5.static Level FATAL

FATAL level指出每个严重的错误事件将会导致应用程序的退出。

另外,还有两个可用的特别的日志记录级别:

1.static Level ALL

ALL Level是最低等级的,用于打开所有日志记录。

2.static Level OFF

OFF Level是最高等级的,用于关闭所有日志记录。

log的主要节点

log配置文件主要包含三个节点:Logger、Appender、Layout。
Logger:配置打印日志的级别,输出日志的程序范围,以及关联的Appender。
Appender:配置日志的输出形式,输出策略等。
Layout:配置每条日志的内容格式。

<?xml version="1.0" encoding="UTF-8"?>

<configuration status="OFF">
	<appenders>
		<Console name="myConsole" target="SYSTEM_OUT">
			<PatternLayout pattern="[%-5p] %m%n" />
		</Console>
	</appenders>
	
	<loggers>
		<logger name="com.yyf.dao.IStudentDao" level="trace" additivity="false">
			<appender-ref ref="myConsole" />
		</logger>
		<!--<root level="debug">
			<appender-ref ref="myConsole" />
		</root>-->
	</loggers>
	
5.8 创建资源文件resources 将所有配置文件放在资源文件中
六、spring和web的整合

6.1创建web项目
6.2引入springmvc的依赖(上述依赖也需要)

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.2.0.RELEASE</version>
    </dependency>

6.3创建配置spring和mybatis的主配置文件
6.4创建实体类,dao,service接口及其实现类
6.5创建servlet类

package com.abc.servlets;

import com.abc.beans.Student;
import com.abc.service.IStudentService;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class RegisterServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /*ApplicationContext ac;*/
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("123456");
        response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("utf-8");
        // 1.获取请求参数
        String name = request.getParameter("name");
        String ageStr = request.getParameter("age");
        String scoreStr = request.getParameter("score");

        Integer age = Integer.valueOf(ageStr);
        Double score = Double.valueOf(scoreStr);

        // 2.将请求参数封装为Student对象
        Student student = new Student(name,age,score);

        // 3.获取Spring容器对象
		/*WebApplicationContext ac = (WebApplicationContext) this.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
		System.out.println(ac);*/
        WebApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());

        // 4.从容器中获取service对象
        IStudentService service = (IStudentService) ac.getBean("studentService");


        // 5.调用Service对象的saveStudent()方法将student对象写入到DB
        service.saveStudent(student);

        // 6.页面跳转
        request.getRequestDispatcher("/welcome.jsp").forward(request, response);

    }
}

已完结。。。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值