Note_JavaWeb_Spring_尚硅谷

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Note_JavaWeb_Spring_尚硅谷相关的知识,希望对你有一定的参考价值。

常用Api

spring-1

beans-annotation.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-4.0.xsd">

 

    <!-- 配置自动扫描的包: 需要加入 aop 对应的 jar 包 -->

    <context:component-scan base-package="com.atguigu.spring.annotation.generic"></context:component-scan>

 

</beans>

beans.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:util="http://www.springframework.org/schema/util"

    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-4.0.xsd">

   

property

    <!-- 配置一个 bean -->

    <bean id="helloWorld" class="com.atguigu.spring.helloworld.HelloWorld">

        <!-- 为属性赋值 -->

        <property name="user" value="Jerry"></property>

    </bean>

   

    <!-- 配置一个 bean -->

    <bean id="helloWorld2" class="com.atguigu.spring.helloworld.HelloWorld">

        <!-- 为属性赋值 -->

        <!-- 通过属性注入: 通过 setter 方法注入属性值 -->

        <property name="user" value="Tom"></property>

    </bean>

   

constructor-arg

    <!-- 通过构造器注入属性值 -->

    <bean id="helloWorld3" class="com.atguigu.spring.helloworld.HelloWorld">

        <!-- 要求: 在 Bean 中必须有对应的构造器.  -->

        <constructor-arg value="Mike"></constructor-arg>

    </bean>

   

    <!-- 若一个 bean 有多个构造器, 如何通过构造器来为 bean 的属性赋值 -->

    <!-- 可以根据 index 和 value 进行更加精确的定位. (了解) -->

    <bean id="car" class="com.atguigu.spring.helloworld.Car">

        <constructor-arg value="KUGA" index="1"></constructor-arg>

        <constructor-arg value="ChangAnFord" index="0"></constructor-arg>

        <constructor-arg value="250000" type="float"></constructor-arg>

    </bean>

   

    <bean id="car2" class="com.atguigu.spring.helloworld.Car">

        <constructor-arg value="ChangAnMazda"></constructor-arg>

        <!-- 若字面值中包含特殊字符, 则可以使用 DCDATA 来进行赋值. (了解) -->

        <constructor-arg>

            <value><![CDATA[<ATARZA>]]></value>

        </constructor-arg>

        <constructor-arg value="180" type="int"></constructor-arg>

    </bean>

    

    <!-- 配置 bean -->

    <bean id="dao5" class="com.atguigu.spring.ref.Dao"></bean>

 

ref

    <bean id="service" class="com.atguigu.spring.ref.Service">

        <!-- 通过 ref 属性值指定当前属性指向哪一个 bean! -->

        <property name="dao" ref="dao5"></property>

    </bean>

   

内部 bean

    <!-- 声明使用内部 bean -->

    <bean id="service2" class="com.atguigu.spring.ref.Service">

        <property name="dao">

            <!-- 内部 bean, 类似于匿名内部类对象. 不能被外部的 bean 来引用, 也没有必要设置 id 属性 -->

            <bean class="com.atguigu.spring.ref.Dao">

                <property name="dataSource" value="c3p0"></property>

            </bean>

        </property>

    </bean>

   

设置级联属性

    <bean id="action" class="com.atguigu.spring.ref.Action">

        <property name="service" ref="service2"></property>

        <!-- 设置级联属性(了解) -->

        <property name="service.dao.dataSource" value="DBCP2"></property>

    </bean>

   

null

    <bean id="dao2" class="com.atguigu.spring.ref.Dao">

        <!-- 为 Dao 的 dataSource 属性赋值为 null, 若某一个 bean 的属性值不是 null, 使用时需要为其设置为 null(了解) -->

        <property name="dataSource"><null/></property>

    </bean>

   

list

    <!-- 装配集合属性 -->

    <bean id="user" class="com.atguigu.spring.helloworld.User">

        <property name="userName" value="Jack"></property>

        <property name="cars">

            <!-- 使用 list 元素来装配集合属性 -->

            <list>

                <ref bean="car"/>

                <ref bean="car2"/>

            </list>

        </property>

    </bean>

   

util:list

    <!-- 声明集合类型的 bean -->

    <util:list id="cars">

        <ref bean="car"/>

        <ref bean="car2"/>

    </util:list>

   

    <bean id="user2" class="com.atguigu.spring.helloworld.User">

        <property name="userName" value="Rose"></property>

        <!-- 引用外部声明的 list -->

        <property name="cars" ref="cars"></property>

    </bean>

   

p:

    <bean id="user3" class="com.atguigu.spring.helloworld.User"

        p:cars-ref="cars" p:userName="Titannic"></bean>

       

parent

    <!-- bean 的配置能够继承吗 ? 使用 parent 来完成继承 --> 

    <bean id="user4" parent="user" p:userName="Bob"></bean>

   

    <bean id="user6" parent="user" p:userName="维多利亚"></bean>

   

depends-on

    <!-- 测试 depents-on --> 

    <bean id="user5" parent="user" p:userName="Backham" depends-on="user6"></bean>

   

</beans>

beans-auto.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-4.0.xsd">

 

    <!-- 自动装配: 只声明 bean, 而把 bean 之间的关系交给 IOC 容器来完成 -->

    <!-- 

        byType: 根据类型进行自动装配. 但要求 IOC 容器中只有一个类型对应的 bean, 若有多个则无法完成自动装配.

        byName: 若属性名和某一个 bean 的 id 名一致, 即可完成自动装配. 若没有 id 一致的, 则无法完成自动装配

    -->

    <!-- 在使用 XML 配置时, 自动转配用的不多. 但在基于 注解 的配置时, 自动装配使用的较多.  -->

    <bean id="dao" class="com.atguigu.spring.ref.Dao">

        <property name="dataSource" value="C3P0"></property>               

    </bean>

   

Scope : prototype/ singleton

    <!-- 默认情况下 bean 是单例的! -->

    <!-- 但有的时候, bean 就不能使单例的. 例如: Struts2 的 Action 就不是单例的! 可以通过 scope 属性来指定 bean 的作用域 -->

    <!-- 

        prototype: 原型的. 每次调用 getBean 方法都会返回一个新的 bean. 且在第一次调用 getBean 方法时才创建实例

        singleton: 单例的. 每次调用 getBean 方法都会返回同一个 bean. 且在 IOC 容器初始化时即创建 bean 的实例. 默认值

    -->

    <bean id="dao2" class="com.atguigu.spring.ref.Dao" scope="prototype"></bean>

   

autowire

    <bean id="service" class="com.atguigu.spring.ref.Service" autowire="byName"></bean>

   

    <bean id="action" class="com.atguigu.spring.ref.Action" autowire="byType"></bean>

   

context:property-placeholder

    <!-- 导入外部的资源文件 -->

    <context:property-placeholder location="classpath:db.properties"/>

   

dataSource

    <!-- 配置数据源 -->

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">

        <property name="user" value="${jdbc.user}"></property>

        <property name="password" value="${jdbc.password}"></property>

        <property name="driverClass" value="${jdbc.driverClass}"></property>

        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>

       

        <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>

        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>

    </bean>

   

    <!-- 测试 SpEL: 可以为属性进行动态的赋值(了解) -->

    <bean id="girl" class="com.atguigu.spring.helloworld.User">

        <property name="userName" value="周迅"></property>

    </bean>

   

init-method/destroy-method

    <bean id="boy" class="com.atguigu.spring.helloworld.User" init-method="init" destroy-method="destroy">

        <property name="userName" value="高胜远"></property>

        <property name="wifeName" value="#{girl.userName}"></property>

    </bean>

   

bean 后置处理器

    <!-- 配置 bean 后置处理器: 不需要配置 id 属性, IOC 容器会识别到他是一个 bean 后置处理器, 并调用其方法 -->

    <bean class="com.atguigu.spring.ref.MyBeanPostProcessor"></bean>

   

factory-method

    <!-- 通过工厂方法的方式来配置 bean -->

    <!-- 1. 通过静态工厂方法: 一个类中有一个静态方法, 可以返回一个类的实例(了解) -->

    <!-- 在 class 中指定静态工厂方法的全类名, 在 factory-method 中指定静态工厂方法的方法名 -->

    <bean id="dateFormat" class="java.text.DateFormat" factory-method="getDateInstance">

        <!-- 可以通过 constructor-arg 子节点为静态工厂方法指定参数 -->

        <constructor-arg value="2"></constructor-arg>

    </bean>

   

    <!-- 2. 实例工厂方法: 先需要创建工厂对象, 再调用工厂的非静态方法返回实例(了解) -->

    <!-- ①. 创建工厂对应的 bean -->

    <bean id="simpleDateFormat" class="java.text.SimpleDateFormat">

        <constructor-arg value="yyyy-MM-dd hh:mm:ss"></constructor-arg>

    </bean>

   

    <!-- ②. 有实例工厂方法来创建 bean 实例 -->

    <!-- factory-bean 指向工厂 bean, factory-method 指定工厂方法(了解) -->

    <bean id="datetime" factory-bean="simpleDateFormat" factory-method="parse">

        <!-- 通过 constructor-arg 执行调用工厂方法需要传入的参数 -->

        <constructor-arg value="1990-12-12 12:12:12"></constructor-arg>

    </bean>

   

    <!-- 配置通过 FactroyBean 的方式来创建 bean 的实例(了解) -->

    <bean id="user" class="com.atguigu.spring.ref.UserBean"></bean>

   

</beans>

db.properties

jdbc.user=root

jdbc.password=1230

jdbc.driverClass=com.mysql.jdbc.Driver

jdbc.jdbcUrl=jdbc:mysql:///test

 

jdbc.initPoolSize=5

jdbc.maxPoolSize=10

 

spring-2

applicationContext.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"

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

 

    <!-- 

        1. 默认情况下, IOC 容器中的 bean 是单例的! 若对象是单例的, 则在创建 IOC 容器时即创建 bean 的实例, 并对 bean 的属性进行初始化.

        2. 可以通过 bean 的 scope 属性来修改 bean 的作用域. 若取值为 prototype, 则 bean 为原型的: 每次向容器获取实例, 得到的都是一个新的对象.

        而且, 不在创建 IOC 容器时创建 bean 的实例了.

        3. IOC 容器中 bean 的生命周期:

        3.1 一般地, 讨论 bean 的生命周期, 是建立在 bean 是单例的基础上的.

        3.2 可以为 bean 指定 init 和 destroy 方法

        3.3 还可以通过 bean 的后置处理器来更加丰富 bean 的生命周期方法(面试时.).

    -->

    <bean id="helloWorld"

        class="com.atguigu.spring.helloworld.HelloWorld"

        scope="singleton"

        init-method="init"

        destroy-method="destroy">

        <property name="userName" value="atguigu"></property>

    </bean>

   

    <!-- 

        1. 在 IOC 容器中配置 bean 之间的关联关系

    -->

    <bean id="userDao"

        class="com.atguigu.spring.ref.UserDao"></bean>

 

    <bean id="userService"

        class="com.atguigu.spring.ref.UserService">

        <property name="userDao" ref="userDao"></property> 

    </bean>

   

    <bean id="userAction"

        class="com.atguigu.spring.ref.UserAction">

        <property name="userService" ref="userService"></property>

    </bean>

 

</beans>

applicationContext-aop.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 http://www.springframework.org/schema/aop/spring-aop-4.0.xsd

        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

 

    <!-- 自动扫描的包 -->

    <context:component-scan base-package="com.atguigu.spring.aop"></context:component-scan>

 

aop:aspectj-autoproxy

    <!-- 使 AspectJ 的注解起作用 -->

    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

 

</beans>

applicationContext-annotation.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-4.0.xsd">

 

    <!-- 配置自动扫描的包 -->

    <context:component-scan base-package="com.atguigu.spring.ref"></context:component-scan>

 

</beans>

aop\ArithmeticCalculator.java

package com.atguigu.spring.aop;

 

public interface ArithmeticCalculator {

 

    int add(int i, int j);

    int sub(int i, int j);

   

    int mul(int i, int j);

    int div(int i, int j);

   

}

aop\ArithmeticCalculatorImpl.java

package com.atguigu.spring.aop;

 

import org.springframework.stereotype.Component;

 

@Component("arithmeticCalculator")

public class ArithmeticCalculatorImpl implements ArithmeticCalculator {

 

    @Override

    public int add(int i, int j) {

        int result = i + j;

        return result;

    }

 

    @Override

    public int sub(int i, int j) {

        int result = i - j;

        return result;

    }

 

    @Override

    public int mul(int i, int j) {

        int result = i * j;

        return result;

    }

 

    @Override

    public int div(int i, int j) {

        int result = i / j;

        return result;

    }

 

}

aop\ArithmeticCalculatorLoggingImpl.java

package com.atguigu.spring.aop;

 

public class ArithmeticCalculatorLoggingImpl implements ArithmeticCalculator {

 

    @Override

    public int add(int i, int j) {

        System.out.println("The method add begins with [" + i + "," + j + "]");

        int result = i + j;

        System.out.println("The method add ends with " + result);

        return result;

    }

 

    @Override

    public int sub(int i, int j) {

        System.out.println("The method sub begins with [" + i + "," + j + "]");

        int result = i - j;

        System.out.println("The method sub ends with " + result);

        return result;

    }

 

    @Override

    public int mul(int i, int j) {

        System.out.println("The method mul begins with [" + i + "," + j + "]");

        int result = i * j;

        System.out.println("The method mul ends with " + result);

        return result;

    }

 

    @Override

    public int div(int i, int j) {

        System.out.println("The method div begins with [" + i + "," + j + "]");

        int result = i / j;

        System.out.println("The method div ends with " + result);

        return result;

    }

 

}

aop\ArithmeticCalculatorLoggingProxy.java

package com.atguigu.spring.aop;

 

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.util.Arrays;

 

public class ArithmeticCalculatorLoggingProxy {

   

    //要代理的对象

    private ArithmeticCalculator target;

   

    public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) {

        super();

        this.target = target;

    }

 

    //返回代理对象

    public ArithmeticCalculator getLoggingProxy(){

        ArithmeticCalculator proxy = null;

       

        ClassLoader loader = target.getClass().getClassLoader();

        Class [] interfaces = new Class[]{ArithmeticCalculator.class};

        InvocationHandler h = new InvocationHandler() {

            /**

             * proxy: 代理对象。 一般不使用该对象

             * method: 正在被调用的方法

             * args: 调用方法传入的参数

             */

            @Override

            public Object invoke(Object proxy, Method method, Object[] args)

                    throws Throwable {

                String methodName = method.getName();

                //打印日志

                System.out.println("[before] The method " + methodName + " begins with " + Arrays.asList(args));

               

                //调用目标方法

                Object result = null;

               

                try {

                    //前置通知

                    result = method.invoke(target, args);

                    //返回通知, 可以访问到方法的返回值

                } catch (NullPointerException e) {

                    e.printStackTrace();

                    //异常通知, 可以访问到方法出现的异常

                }

               

                //后置通知. 因为方法可以能会出异常, 所以访问不到方法的返回值

               

                //打印日志

                System.out.println("[after] The method ends with " + result);

               

                return result;

            }

        };

       

        /**

         * loader: 代理对象使用的类加载器。

         * interfaces: 指定代理对象的类型. 即代理代理对象中可以有哪些方法.

         * h: 当具体调用代理对象的方法时, 应该如何进行响应, 实际上就是调用 InvocationHandler 的 invoke 方法

         */

        proxy = (ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h);

       

        return proxy;

    }

}

aop\LoggingAspect.java

package com.atguigu.spring.aop;

 

import java.util.Arrays;

 

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.annotation.After;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.springframework.stereotype.Component;

 

/**

 * AOP 的 helloWorld

 * 1. 加入 jar 包

 * com.springsource.net.sf.cglib-2.2.0.jar

 * com.springsource.org.aopalliance-1.0.0.jar

 * com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

 * spring-aspects-4.0.0.RELEASE.jar

 *

 * 2. 在 Spring 的配置文件中加入 aop 的命名空间。

 *

 * 3. 基于注解的方式来使用 AOP

 * 3.1 在配置文件中配置自动扫描的包: <context:component-scan base-package="com.atguigu.spring.aop"></context:component-scan>

 * 3.2 加入使 AspjectJ 注解起作用的配置: <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

 * 为匹配的类自动生成动态代理对象.

 *

 * 4. 编写切面类:

 * 4.1 一个一般的 Java 类

 * 4.2 在其中添加要额外实现的功能.

 *

 * 5. 配置切面

 * 5.1 切面必须是 IOC 中的 bean: 实际添加了 @Component 注解

 * 5.2 声明是一个切面: 添加 @Aspect

 * 5.3 声明通知: 即额外加入功能对应的方法.

 * 5.3.1 前置通知: @Before("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(int, int))")

 * @Before 表示在目标方法执行之前执行 @Before 标记的方法的方法体.

 * @Before 里面的是切入点表达式:

 *

 * 6. 在通知中访问连接细节: 可以在通知方法中添加 JoinPoint 类型的参数, 从中可以访问到方法的签名和方法的参数.

 *

 * 7. @After 表示后置通知: 在方法执行之后执行的代码.

 */

 

//通过添加 @Aspect 注解声明一个 bean 是一个切面!

@Aspect

@Component

@Aspect

@Component

public class LoggingAspect {

@Before

    @Before("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(int, int))")

    public void beforeMethod(JoinPoint joinPoint){

        String methodName = joinPoint.getSignature().getName();

        Object [] args = joinPoint.getArgs();

       

        System.out.println("The method " + methodName + " begins with " + Arrays.asList(args));

    }

@After

    @After("execution(* com.atguigu.spring.aop.*.*(..))")

    public void afterMethod(JoinPoint joinPoint){

        String methodName = joinPoint.getSignature().getName();

        System.out.println("The method " + methodName + " ends");

    }

   

}

aop\Main.java

package com.atguigu.spring.aop;

 

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

public class Main {

   

    public static void main(String[] args) {

//      ArithmeticCalculator arithmeticCalculator = new ArithmeticCalculatorImpl();

//     

//      arithmeticCalculator =

//              new ArithmeticCalculatorLoggingProxy(arithmeticCalculator).getLoggingProxy();

//     

//      int result = arithmeticCalculator.add(11, 12);

//      System.out.println("result:" + result);

//     

//      result = arithmeticCalculator.div(21, 3);

//      System.out.println("result:" + result);

       

        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-aop.xml");

        ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) ctx.getBean("arithmeticCalculator");

       

        System.out.println(arithmeticCalculator.getClass().getName());

        

        int result = arithmeticCalculator.add(11, 12);

        System.out.println("result:" + result);

       

        result = arithmeticCalculator.div(21, 3);

        System.out.println("result:" + result);

    }

   

}

helloworld\HelloWorld.java

package com.atguigu.spring.helloworld;

 

public class HelloWorld {

   

    //字段

    private String user;

   

    public HelloWorld() {

        System.out.println("HelloWorld‘s constructor...");

    }

   

    //JavaBean 使用 setter 和 getter 来定义属性

    public void setUserName(String user) {

        System.out.println("setUserName:" + user);

        this.user = user;

    }

   

    public void hello(){

        System.out.println("Hello:" + user);

    }

   

    public void init(){

        System.out.println("init method...");

    }

   

    public void destroy(){

        System.out.println("destroy method...");

    }

   

}

helloworld\Main.java

package com.atguigu.spring.helloworld;

 

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

public class Main {

   

    public static void main(String[] args) {

       

        //1. 创建 IOC 容器

        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

       

        //2. 从 IOC 容器中获取 bean 实例

        HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloWorld");

       

        //3. 调用 bean 的方法

        helloWorld.hello();

       

        HelloWorld helloWorld2 = (HelloWorld) ctx.getBean("helloWorld");

        System.out.println(helloWorld == helloWorld2);

       

        //4. 关闭容器

        ctx.close();

    }

   

}

ref\Main.java

package com.atguigu.spring.ref;

 

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

public class Main {

   

    public static void main(String[] args) {

       

        //1. 创建 IOC 容器

        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-annotation.xml");

       

        UserAction userAction = (UserAction) ctx.getBean("userAction");

        userAction.execute();

    }

   

}

ref\UserAction.java

package com.atguigu.spring.ref;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

 

@Controller

@Controller

public class UserAction {

 

    private UserService userService;

   

@Autowired

    @Autowired

    public void setUserService(UserService userService) {

        this.userService = userService;

    }

   

    public void execute(){

        System.out.println("execute...");

        userService.addNew();

    }

   

}

ref\UserDao.java

package com.atguigu.spring.ref;

 

import org.springframework.stereotype.Repository;

 

@Repository

@Repository

public class UserDao {

 

    public void save(){

        System.out.println("UserDao‘s save...");

    }

   

}

ref\UserService.java

package com.atguigu.spring.ref;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

 

@Service

@Service

public class UserService {

 

    @Autowired

    private UserDao userDao;

   

    public void setUserDao(UserDao userDao) {

        this.userDao = userDao;

    }

   

    public void addNew(){

        System.out.println("addNew...");

        userDao.save();

    }

   

}

 

spring-3

src\applicationContext-xml.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"

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

        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">

 

    <!-- 配置 bean -->

    <bean id="arithmeticCalculator"

        class="com.atguigu.spring.aop.xml.ArithmeticCalculatorImpl"></bean>

 

    <!-- 配置切面的 bean. -->

    <bean id="loggingAspect"

        class="com.atguigu.spring.aop.xml.LoggingAspect"></bean>

 

    <bean id="vlidationAspect"

        class="com.atguigu.spring.aop.xml.VlidationAspect"></bean>

aop:config

    <!-- 配置 AOP -->

<aop:config>

aop:pointcut

        <!-- 配置切点表达式 -->

        <aop:pointcut expression="execution(* com.atguigu.spring.aop.xml.ArithmeticCalculator.*(int, int))"

            id="pointcut"/>

aop:aspect

        <!-- 配置切面及通知 -->

        <aop:aspect ref="loggingAspect" order="2">

            <aop:before method="beforeMethod" pointcut-ref="pointcut"/>

            <aop:after method="afterMethod" pointcut-ref="pointcut"/>

            <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/>

            <aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/>

            <!-- 

            <aop:around method="aroundMethod" pointcut-ref="pointcut"/>

            -->

        </aop:aspect>  

        <aop:aspect ref="vlidationAspect" order="1">

            <aop:before method="validateArgs" pointcut-ref="pointcut"/>

        </aop:aspect>

    </aop:config>

 

</beans>

src\applicationContext.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"

    xmlns:aop="http://www.springframework.org/schema/aop"

    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd

        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-4.0.xsd">

 

    <!-- 配置自动扫描的包 -->

    <context:component-scan base-package="com.atguigu.spring.aop"></context:component-scan>

   

aop:aspectj-autoproxy

    <!-- 配置自动为匹配 aspectJ 注解的 Java 类生成代理对象 -->

    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

   

</beans>

 

aop\ArithmeticCalculator.java

package com.atguigu.spring.aop;

 

public interface ArithmeticCalculator {

 

    int add(int i, int j);

    int sub(int i, int j);

   

    int mul(int i, int j);

    int div(int i, int j);

   

}

aop\ArithmeticCalculatorImpl.java

package com.atguigu.spring.aop;

 

import org.springframework.stereotype.Component;

 

@Component("arithmeticCalculator")

@Component("arithmeticCalculator")

public class ArithmeticCalculatorImpl implements ArithmeticCalculator {

 

    @Override

    public int add(int i, int j) {

        int result = i + j;

        return result;

    }

 

    @Override

    public int sub(int i, int j) {

        int result = i - j;

        return result;

    }

 

    @Override

    public int mul(int i, int j) {

        int result = i * j;

        return result;

    }

 

    @Override

    public int div(int i, int j) {

        int result = i / j;

        return result;

    }

 

}

aop\LoggingAspect.java

package com.atguigu.spring.aop;

 

import java.util.Arrays;

 

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.annotation.After;

import org.aspectj.lang.annotation.AfterReturning;

import org.aspectj.lang.annotation.AfterThrowing;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.aspectj.lang.annotation.Pointcut;

import org.springframework.core.annotation.Order;

import org.springframework.stereotype.Component;

 

/**

 * 可以使用 @Order 注解指定切面的优先级, 值越小优先级越高

 */

@Order(2)

@Aspect

@Component

@Order(2)

@Aspect

@Component

public class LoggingAspect {

   

@Pointcut

    /**

     * 定义一个方法, 用于声明切入点表达式. 一般地, 该方法中再不需要添入其他的代码.

     * 使用 @Pointcut 来声明切入点表达式.

     * 后面的其他通知直接使用方法名来引用当前的切入点表达式.

     */

    @Pointcut("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(..))")

    public void declareJointPointExpression(){}

   

@Before

    /**

     * 在 com.atguigu.spring.aop.ArithmeticCalculator 接口的每一个实现类的每一个方法开始之前执行一段代码

     */

    @Before("declareJointPointExpression()")

    public void beforeMethod(JoinPoint joinPoint){

        String methodName = joinPoint.getSignature().getName();

        Object [] args = joinPoint.getArgs();

       

        System.out.println("The method " + methodName + " begins with " + Arrays.asList(args));

    }

@After

    /**

     * 在方法执行之后执行的代码. 无论该方法是否出现异常

     */

    @After("declareJointPointExpression()")

    public void afterMethod(JoinPoint joinPoint){

        String methodName = joinPoint.getSignature().getName();

        System.out.println("The method " + methodName + " ends");

    }

   

@AfterReturning

    /**

     * 在方法法正常结束受执行的代码

     * 返回通知是可以访问到方法的返回值的!

     */

    @AfterReturning(value="declareJointPointExpression()",

            returning="result")

    public void afterReturning(JoinPoint joinPoint, Object result){

        String methodName = joinPoint.getSignature().getName();

        System.out.println("The method " + methodName + " ends with " + result);

    }

   

@AfterThrowing

    /**

     * 在目标方法出现异常时会执行的代码.

     * 可以访问到异常对象; 且可以指定在出现特定异常时在执行通知代码

     */

    @AfterThrowing(value="declareJointPointExpression()",

            throwing="e")

    public void afterThrowing(JoinPoint joinPoint, Exception e){

        String methodName = joinPoint.getSignature().getName();

        System.out.println("The method " + methodName + " occurs excetion:" + e);

    }

   

@Around

    /**

     * 环绕通知需要携带 ProceedingJoinPoint 类型的参数.

     * 环绕通知类似于动态代理的全过程: ProceedingJoinPoint 类型的参数可以决定是否执行目标方法.

     * 且环绕通知必须有返回值, 返回值即为目标方法的返回值

     */

    /*

    @Around("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(..))")

    public Object aroundMethod(ProceedingJoinPoint pjd){

       

        Object result = null;

        String methodName = pjd.getSignature().getName();

       

        try {

            //前置通知

            System.out.println("The method " + methodName + " begins with " + Arrays.asList(pjd.getArgs()));

            //执行目标方法

            result = pjd.proceed();

            //返回通知

            System.out.println("The method " + methodName + " ends with " + result);

        } catch (Throwable e) {

            //异常通知

            System.out.println("The method " + methodName + " occurs exception:" + e);

            throw new RuntimeException(e);

        }

        //后置通知

        System.out.println("The method " + methodName + " ends");

       

        return result;

    }

    */

}

aop\Main.java

package com.atguigu.spring.aop;

 

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

public class Main {

   

    public static void main(String[] args) {

       

        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) ctx.getBean("arithmeticCalculator");

       

        System.out.println(arithmeticCalculator.getClass().getName());

       

        int result = arithmeticCalculator.add(1, 2);

        System.out.println("result:" + result);

       

        result = arithmeticCalculator.div(1000, 10);

        System.out.println("result:" + result);

    }

   

}

aop\VlidationAspect.java

package com.atguigu.spring.aop;

 

import java.util.Arrays;

 

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.springframework.core.annotation.Order;

import org.springframework.stereotype.Component;

 

@Order(1)

@Aspect

@Component

@Order(1)

@Aspect

@Component

public class VlidationAspect {

 

@Before

    @Before("com.atguigu.spring.aop.LoggingAspect.declareJointPointExpression()")

    public void validateArgs(JoinPoint joinPoint){

        System.out.println("-->validate:" + Arrays.asList(joinPoint.getArgs()));

    }

   

}

aop\xml\ArithmeticCalculator.java

package com.atguigu.spring.aop.xml;

 

public interface ArithmeticCalculator {

 

    int add(int i, int j);

    int sub(int i, int j);

   

    int mul(int i, int j);

    int div(int i, int j);

   

}

aop\xml\ArithmeticCalculatorImpl.java

package com.atguigu.spring.aop.xml;

 

public class ArithmeticCalculatorImpl implements ArithmeticCalculator {

 

    @Override

    public int add(int i, int j) {

        int result = i + j;

        return result;

    }

 

    @Override

    public int sub(int i, int j) {

        int result = i - j;

        return result;

    }

 

    @Override

    public int mul(int i, int j) {

        int result = i * j;

        return result;

    }

 

    @Override

    public int div(int i, int j) {

        int result = i / j;

        return result;

    }

 

}

aop\xml\LoggingAspect.java

package com.atguigu.spring.aop.xml;

 

import java.util.Arrays;

 

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.Around;

 

public class LoggingAspect {

   

    public void beforeMethod(JoinPoint joinPoint){

        String methodName = joinPoint.getSignature().getName();

        Object [] args = joinPoint.getArgs();

       

        System.out.println("The method " + methodName + " begins with " + Arrays.asList(args));

    }

   

    public void afterMethod(JoinPoint joinPoint){

        String methodName = joinPoint.getSignature().getName();

        System.out.println("The method " + methodName + " ends");

    }

   

    public void afterReturning(JoinPoint joinPoint, Object result){

        String methodName = joinPoint.getSignature().getName();

        System.out.println("The method " + methodName + " ends with " + result);

    }

   

    public void afterThrowing(JoinPoint joinPoint, Exception e){

        String methodName = joinPoint.getSignature().getName();

        System.out.println("The method " + methodName + " occurs excetion:" + e);

    }

   

    @Around("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(..))")

    public Object aroundMethod(ProceedingJoinPoint pjd){

       

        Object result = null;

        String methodName = pjd.getSignature().getName();

       

        try {

            //前置通知

            System.out.println("The method " + methodName + " begins with " + Arrays.asList(pjd.getArgs()));

            //执行目标方法

            result = pjd.proceed();

            //返回通知

            System.out.println("The method " + methodName + " ends with " + result);

        } catch (Throwable e) {

            //异常通知

            System.out.println("The method " + methodName + " occurs exception:" + e);

            throw new RuntimeException(e);

        }

        //后置通知

        System.out.println("The method " + methodName + " ends");

       

        return result;

    }

}

aop\xml\Main.java

package com.atguigu.spring.aop.xml;

 

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

public class Main {

   

    public static void main(String[] args) {

       

        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-xml.xml");

        ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) ctx.getBean("arithmeticCalculator");

       

        System.out.println(arithmeticCalculator.getClass().getName());

       

        int result = arithmeticCalculator.add(1, 2);

        System.out.println("result:" + result);

       

        result = arithmeticCalculator.div(1000, 0);

        System.out.println("result:" + result);

    }

   

}

aop\xml\VlidationAspect.java

package com.atguigu.spring.aop.xml;

 

import java.util.Arrays;

 

import org.aspectj.lang.JoinPoint;

 

public class VlidationAspect {

 

    public void validateArgs(JoinPoint joinPoint){

        System.out.println("-->validate:" + Arrays.asList(joinPoint.getArgs()));

    }

   

}

 

spring-4

src\applicationContext-tx-xml.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"

    xmlns:tx="http://www.springframework.org/schema/tx"

    xmlns:aop="http://www.springframework.org/schema/aop"

    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd

        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd

        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

   

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

   

    <!-- 导入资源文件 -->

    <context:property-placeholder location="classpath:db.properties"/>

   

    <!-- 配置 C3P0 数据源 -->

    <bean id="dataSource"

        class="com.mchange.v2.c3p0.ComboPooledDataSource">

        <property name="user" value="${jdbc.user}"></property>

        <property name="password" value="${jdbc.password}"></property>

        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>

        <property name="driverClass" value="${jdbc.driverClass}"></property>

 

        <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>

        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>

    </bean>

   

    <!-- 配置 Spirng 的 JdbcTemplate -->

    <bean id="jdbcTemplate"

        class="org.springframework.jdbc.core.JdbcTemplate">

        <property name="dataSource" ref="dataSource"></property>

    </bean>

   

    <!-- 配置 bean -->

    <bean id="bookShopDao" class="com.atguigu.spring.tx.xml.BookShopDaoImpl">

        <property name="jdbcTemplate" ref="jdbcTemplate"></property>

    </bean>

   

    <bean id="bookShopService" class="com.atguigu.spring.tx.xml.service.impl.BookShopServiceImpl">

        <property name="bookShopDao" ref="bookShopDao"></property>

    </bean>

   

    <bean id="cashier" class="com.atguigu.spring.tx.xml.service.impl.CashierImpl">

        <property name="bookShopService" ref="bookShopService"></property>

    </bean>

   

    <!-- 1. 配置事务管理器 -->

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

        <property name="dataSource" ref="dataSource"></property>

    </bean>

   

    <!-- 2. 配置事务属性 -->

    <tx:advice id="txAdvice" transaction-manager="transactionManager">

        <tx:attributes>

            <!-- 根据方法名指定事务的属性 -->

            <tx:method name="purchase" propagation="REQUIRES_NEW"/>

            <tx:method name="get*" read-only="true"/>

            <tx:method name="find*" read-only="true"/>

            <tx:method name="*"/>

        </tx:attributes>

    </tx:advice>

   

    <!-- 3. 配置事务切入点, 以及把事务切入点和事务属性关联起来 -->

    <aop:config>

        <aop:pointcut expression="execution(* com.atguigu.spring.tx.xml.service.*.*(..))"

            id="txPointCut"/>

        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> 

    </aop:config>

   

</beans>

src\applicationContext.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"

    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/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd

        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

   

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

   

    <!-- 导入资源文件 -->

    <context:property-placeholder location="classpath:db.properties"/>

   

    <!-- 配置 C3P0 数据源 -->

    <bean id="dataSource"

        class="com.mchange.v2.c3p0.ComboPooledDataSource">

        <property name="user" value="${jdbc.user}"></property>

        <property name="password" value="${jdbc.password}"></property>

        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>

        <property name="driverClass" value="${jdbc.driverClass}"></property>

 

        <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>

        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>

    </bean>

   

    <!-- 配置 Spirng 的 JdbcTemplate -->

    <bean id="jdbcTemplate"

        class="org.springframework.jdbc.core.JdbcTemplate">

        <property name="dataSource" ref="dataSource"></property>

    </bean>

   

    <!-- 配置 NamedParameterJdbcTemplate, 该对象可以使用具名参数, 其没有无参数的构造器, 所以必须为其构造器指定参数 -->

    <bean id="namedParameterJdbcTemplate"

        class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">

        <constructor-arg ref="dataSource"></constructor-arg>   

    </bean>

   

    <!-- 配置事务管理器 -->

    <bean id="transactionManager"

        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

        <property name="dataSource" ref="dataSource"></property>

    </bean>

   

    <!-- 启用事务注解 -->

    <tx:annotation-driven transaction-manager="transactionManager"/>

   

</beans>

 

jdbc\Department.java

package com.atguigu.spring.jdbc;

 

public class Department {

 

    private Integer id;

    private String name;

 

    public Integer getId() {

        return id;

    }

 

    public void setId(Integer id) {

        this.id = id;

    }

 

    public String getName() {

        return name;

    }

 

    public void setName(String name) {

        this.name = name;

    }

 

    @Override

    public String toString() {

        return "Department [id=" + id + ", name=" + name + "]";

    }

 

}

jdbc\DepartmentDao.java

package com.atguigu.spring.jdbc;

 

import javax.sql.DataSource;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.jdbc.core.BeanPropertyRowMapper;

import org.springframework.jdbc.core.RowMapper;

import org.springframework.jdbc.core.support.JdbcDaoSupport;

import org.springframework.stereotype.Repository;

 

/**

 * 不推荐使用 JdbcDaoSupport, 而推荐直接使用 JdbcTempate 作为 Dao 类的成员变量

 */

@Repository

public class DepartmentDao extends JdbcDaoSupport{

 

    @Autowired

    public void setDataSource2(DataSource dataSource){

        setDataSource(dataSource);

    }

 

    public Department get(Integer id){

        String sql = "SELECT id, dept_name name FROM departments WHERE id = ?";

        RowMapper<Department> rowMapper = new BeanPropertyRowMapper<>(Department.class);

        return getJdbcTemplate().queryForObject(sql, rowMapper, id);

    }

   

}

jdbc\Employee.java

package com.atguigu.spring.jdbc;

 

public class Employee {

   

    private Integer id;

    private String lastName;

    private String email;

   

    private Integer dpetId;

 

    public Integer getId() {

        return id;

    }

 

    public void setId(Integer id) {

        this.id = id;

    }

 

    public String getLastName() {

        return lastName;

    }

 

    public void setLastName(String lastName) {

        this.lastName = lastName;

    }

 

    public String getEmail() {

        return email;

    }

 

    public void setEmail(String email) {

        this.email = email;

    }

 

    public Integer getDpetId() {

        return dpetId;

    }

 

    public void setDpetId(Integer dpetId) {

        this.dpetId = dpetId;

    }

 

    @Override

    public String toString() {

        return "Employee [id=" + id + ", lastName=" + lastName + ", email="

                + email + ", dpetId=" + dpetId + "]";

    }

 

   

}

jdbc\EmployeeDao.java

package com.atguigu.spring.jdbc;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.jdbc.core.BeanPropertyRowMapper;

import org.springframework.jdbc.core.JdbcTemplate;

import org.springframework.jdbc.core.RowMapper;

import org.springframework.stereotype.Repository;

 

@Repository

public class EmployeeDao {

   

    @Autowired

    private JdbcTemplate jdbcTemplate;

   

    public Employee get(Integer id){

        String sql = "SELECT id, last_name lastName, email FROM employees WHERE id = ?";

        RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<>(Employee.class);

        Employee employee = jdbcTemplate.queryForObject(sql, rowMapper, id);

       

        return employee;

    }

}

jdbc\JDBCTest.java

package com.atguigu.spring.jdbc;

 

import java.sql.SQLException;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

 

import javax.sql.DataSource;

 

import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import org.springframework.jdbc.core.BeanPropertyRowMapper;

import org.springframework.jdbc.core.JdbcTemplate;

import org.springframework.jdbc.core.RowMapper;

import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;

import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import org.springframework.jdbc.core.namedparam.SqlParameterSource;

 

public class JDBCTest {

   

    private ApplicationContext ctx = null;

    private JdbcTemplate jdbcTemplate;

    private EmployeeDao employeeDao;

    private DepartmentDao departmentDao;

    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

   

    {

        ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");

        employeeDao = ctx.getBean(EmployeeDao.class);

        departmentDao = ctx.getBean(DepartmentDao.class);

        namedParameterJdbcTemplate = ctx.getBean(NamedParameterJdbcTemplate.class);

    }

   

    /**

     * 使用具名参数时, 可以使用 update(String sql, SqlParameterSource paramSource) 方法进行更新操作

     * 1. SQL 语句中的参数名和类的属性一致!

     * 2. 使用 SqlParameterSource 的 BeanPropertySqlParameterSource 实现类作为参数.

     */

    @Test

    public void testNamedParameterJdbcTemplate2(){

        String sql = "INSERT INTO employees(last_name, email, dept_id) "

                + "VALUES(:lastName,:email,:dpetId)";

       

        Employee employee = new Employee();

        employee.setLastName("XYZ");

        employee.setEmail("[email protected]");

        employee.setDpetId(3);

       

        SqlParameterSource paramSource = new BeanPropertySqlParameterSource(employee);

        namedParameterJdbcTemplate.update(sql, paramSource);

    }

   

    /**

     * 可以为参数起名字.

     * 1. 好处: 若有多个参数, 则不用再去对应位置, 直接对应参数名, 便于维护

     * 2. 缺点: 较为麻烦.

     */

    @Test

    public void testNamedParameterJdbcTemplate(){

        String sql = "INSERT INTO employees(last_name, email, dept_id) VALUES(:ln,:email,:deptid)";

       

        Map<String, Object> paramMap = new HashMap<>();

        paramMap.put("ln", "FF");

        paramMap.put("email", "[email protected]");

        paramMap.put("deptid", 2);

       

        namedParameterJdbcTemplate.update(sql, paramMap);

    }

   

    @Test

    public void testDepartmentDao(){

        System.out.println(departmentDao.get(1));

    }

   

    @Test

    public void testEmployeeDao(){

        System.out.println(employeeDao.get(1));

    }

   

    /**

     * 获取单个列的值, 或做统计查询

     * 使用 queryForObject(String sql, Class<Long> requiredType)

     */

    @Test

    public void testQueryForObject2(){

        String sql = "SELECT count(id) FROM employees";

        long count = jdbcTemplate.queryForObject(sql, Long.class);

       

        System.out.println(count);

    }

   

    /**

     * 查到实体类的集合

     * 注意调用的不是 queryForList 方法

     */

    @Test

    public void testQueryForList(){

        String sql = "SELECT id, last_name lastName, email FROM employees WHERE id > ?";

        RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<>(Employee.class);

        List<Employee> employees = jdbcTemplate.query(sql, rowMapper,5);

       

        System.out.println(employees);

    }

   

    /**

     * 从数据库中获取一条记录, 实际得到对应的一个对象

     * 注意不是调用 queryForObject(String sql, Class<Employee> requiredType, Object... args) 方法!

     * 而需要调用 queryForObject(String sql, RowMapper<Employee> rowMapper, Object... args)

     * 1. 其中的 RowMapper 指定如何去映射结果集的行, 常用的实现类为 BeanPropertyRowMapper

     * 2. 使用 SQL 中列的别名完成列名和类的属性名的映射. 例如 last_name lastName

     * 3. 不支持级联属性. JdbcTemplate 到底是一个 JDBC 的小工具, 而不是 ORM 框架

     */

    @Test

    public void testQueryForObject(){

        String sql = "SELECT id, last_name lastName, email, dept_id as \"department.id\" FROM employees WHERE id = ?";

        RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<>(Employee.class);

        Employee employee = jdbcTemplate.queryForObject(sql, rowMapper, 1);

       

        System.out.println(employee);

    }

   

    /**

     * 执行批量更新: 批量的 INSERT, UPDATE, DELETE

     * 最后一个参数是 Object[] 的 List 类型: 因为修改一条记录需要一个 Object 的数组, 那么多条不就需要多个 Object 的数组吗

     */

    @Test

    public void testBatchUpdate(){

        String sql = "INSERT INTO employees(last_name, email, dept_id) VALUES(?,?,?)";

       

        List<Object[]> batchArgs = new ArrayList<>();

       

        batchArgs.add(new Object[]{"AA", "[email protected]", 1});

        batchArgs.add(new Object[]{"BB", "[email protected]", 2});

        batchArgs.add(new Object[]{"CC", "[email protected]", 3});

        batchArgs.add(new Object[]{"DD", "[email protected]", 3});

        batchArgs.add(new Object[]{"EE", "[email protected]", 2});

       

        jdbcTemplate.batchUpdate(sql, batchArgs);

    }

   

    /**

     * 执行 INSERT, UPDATE, DELETE

     */

    @Test

    public void testUpdate(){

        String sql = "UPDATE employees SET last_name = ? WHERE id = ?";

        jdbcTemplate.update(sql, "Jack", 5);

    }

   

    @Test

    public void testDataSource() throws SQLException {

        DataSource dataSource = ctx.getBean(DataSource.class);

        System.out.println(dataSource.getConnection());

    }

 

}

tx\BookShopDao.java

package com.atguigu.spring.tx;

 

public interface BookShopDao {

 

    //根据书号获取书的单价

    public int findBookPriceByIsbn(String isbn);

   

    //更新数的库存. 使书号对应的库存 - 1

    public void updateBookStock(String isbn);

   

    //更新用户的账户余额: 使 username 的 balance - price

    public void updateUserAccount(String username, int price);

}

tx\BookShopDaoImpl.java

package com.atguigu.spring.tx;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.jdbc.core.JdbcTemplate;

import org.springframework.stereotype.Repository;

 

@Repository("bookShopDao")

public class BookShopDaoImpl implements BookShopDao {

 

    @Autowired

    private JdbcTemplate jdbcTemplate;

   

    @Override

    public int findBookPriceByIsbn(String isbn) {

        String sql = "SELECT price FROM book WHERE isbn = ?";

        return jdbcTemplate.queryForObject(sql, Integer.class, isbn);

    }

 

    @Override

    public void updateBookStock(String isbn) {

        //检查书的库存是否足够, 若不够, 则抛出异常

        String sql2 = "SELECT stock FROM book_stock WHERE isbn = ?";

        int stock = jdbcTemplate.queryForObject(sql2, Integer.class, isbn);

        if(stock == 0){

            throw new BookStockException("库存不足!");

        }

       

        String sql = "UPDATE book_stock SET stock = stock -1 WHERE isbn = ?";

        jdbcTemplate.update(sql, isbn);

    }

 

    @Override

    public void updateUserAccount(String username, int price) {

        //验证余额是否足够, 若不足, 则抛出异常

        String sql2 = "SELECT balance FROM account WHERE username = ?";

        int balance = jdbcTemplate.queryForObject(sql2, Integer.class, username);

        if(balance < price){

            throw new UserAccountException("余额不足!");

        }

       

        String sql = "UPDATE account SET balance = balance - ? WHERE username = ?";

        jdbcTemplate.update(sql, price, username);

    }

 

}

tx\BookShopService.java

package com.atguigu.spring.tx;

 

public interface BookShopService {

   

    public void purchase(String username, String isbn);

   

}

tx\BookShopServiceImpl.java

package com.atguigu.spring.tx;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Isolation;

import org.springframework.transaction.annotation.Propagation;

import org.springframework.transaction.annotation.Transactional;

 

@Service("bookShopService")

public class BookShopServiceImpl implements BookShopService {

 

    @Autowired

    private BookShopDao bookShopDao;

   

    //添加事务注解

    //1.使用 propagation 指定事务的传播行为, 即当前的事务方法被另外一个事务方法调用时

    //如何使用事务, 默认取值为 REQUIRED, 即使用调用方法的事务

    //REQUIRES_NEW: 事务自己的事务, 调用的事务方法的事务被挂起.

    //2.使用 isolation 指定事务的隔离级别, 最常用的取值为 READ_COMMITTED

    //3.默认情况下 Spring 的声明式事务对所有的运行时异常进行回滚. 也可以通过对应的

    //属性进行设置. 通常情况下去默认值即可.

    //4.使用 readOnly 指定事务是否为只读. 表示这个事务只读取数据但不更新数据,

    //这样可以帮助数据库引擎优化事务. 若真的事一个只读取数据库值的方法, 应设置 readOnly=true

    //5.使用 timeout 指定强制回滚之前事务可以占用的时间. 

//  @Transactional(propagation=Propagation.REQUIRES_NEW,

//          isolation=Isolation.READ_COMMITTED,

//          noRollbackFor={UserAccountException.class})

    @Transactional(propagation=Propagation.REQUIRES_NEW,

            isolation=Isolation.READ_COMMITTED,

            readOnly=false,

            timeout=3)

    @Override

    public void purchase(String username, String isbn) {

       

        try {

            Thread.sleep(5000);

        } catch (InterruptedException e) {}

       

        //1. 获取书的单价

        int price = bookShopDao.findBookPriceByIsbn(isbn);

       

        //2. 更新数的库存

        bookShopDao.updateBookStock(isbn);

       

        //3. 更新用户余额

        bookShopDao.updateUserAccount(username, price);

    }

 

}

tx\BookStockException.java

package com.atguigu.spring.tx;

 

public class BookStockException extends RuntimeException{

 

    /**

     *

     */

    private static final long serialVersionUID = 1L;

 

    public BookStockException() {

        super();

        // TODO Auto-generated constructor stub

    }

 

    public BookStockException(String message, Throwable cause,

            boolean enableSuppression, boolean writableStackTrace) {

        super(message, cause, enableSuppression, writableStackTrace);

        // TODO Auto-generated constructor stub

    }

 

    public BookStockException(String message, Throwable cause) {

        super(message, cause);

        // TODO Auto-generated constructor stub

    }

 

    public BookStockException(String message) {

        super(message);

        // TODO Auto-generated constructor stub

    }

 

    public BookStockException(Throwable cause) {

        super(cause);

        // TODO Auto-generated constructor stub

    }

 

   

}

tx\Cashier.java

package com.atguigu.spring.tx;

 

import java.util.List;

 

public interface Cashier {

 

    public void checkout(String username, List<String> isbns);

   

}

tx\CashierImpl.java

package com.atguigu.spring.tx;

 

import java.util.List;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

 

@Service("cashier")

public class CashierImpl implements Cashier {

 

    @Autowired

    private BookShopService bookShopService;

   

    @Transactional

    @Override

    public void checkout(String username, List<String> isbns) {

        for(String isbn: isbns){

            bookShopService.purchase(username, isbn);

        }

    }

 

}

tx\SpringTransactionTest.java

package com.atguigu.spring.tx;

 

import static org.junit.Assert.*;

 

import java.util.Arrays;

 

import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

public class SpringTransactionTest {

 

    private ApplicationContext ctx = null;

    private BookShopDao bookShopDao = null;

    private BookShopService bookShopService = null;

    private Cashier cashier = null;

   

    {

        ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        bookShopDao = ctx.getBean(BookShopDao.class);

        bookShopService = ctx.getBean(BookShopService.class);

        cashier = ctx.getBean(Cashier.class);

    }

   

    @Test

    public void testTransactionlPropagation(){

        cashier.checkout("AA", Arrays.asList("1001", "1002"));

    }

   

    @Test

    public void testBookShopService(){

        bookShopService.purchase("AA", "1001");

    }

   

    @Test

    public void testBookShopDaoUpdateUserAccount(){

        bookShopDao.updateUserAccount("AA", 200);

    }

   

    @Test

    public void testBookShopDaoUpdateBookStock(){

        bookShopDao.updateBookStock("1001");

    }

   

    @Test

    public void testBookShopDaoFindPriceByIsbn() {

        System.out.println(bookShopDao.findBookPriceByIsbn("1001"));

    }

 

}

tx\UserAccountException.java

package com.atguigu.spring.tx;

 

public class UserAccountException extends RuntimeException{

 

    /**

     *

     */

    private static final long serialVersionUID = 1L;

 

    public UserAccountException() {

        super();

        // TODO Auto-generated constructor stub

    }

 

    public UserAccountException(String message, Throwable cause,

            boolean enableSuppression, boolean writableStackTrace) {

        super(message, cause, enableSuppression, writableStackTrace);

        // TODO Auto-generated constructor stub

    }

 

    public UserAccountException(String message, Throwable cause) {

        super(message, cause);

        // TODO Auto-generated constructor stub

    }

 

    public UserAccountException(String message) {

        super(message);

        // TODO Auto-generated constructor stub

    }

 

    public UserAccountException(Throwable cause) {

        super(cause);

        // TODO Auto-generated constructor stub

    }

 

   

   

}

tx\xml\BookShopDao.java

package com.atguigu.spring.tx.xml;

 

public interface BookShopDao {

 

    //根据书号获取书的单价

    public int findBookPriceByIsbn(String isbn);

   

    //更新数的库存. 使书号对应的库存 - 1

    public void updateBookStock(String isbn);

   

    //更新用户的账户余额: 使 username 的 balance - price

    public void updateUserAccount(String username, int price);

}

tx\xml\BookShopDaoImpl.java

package com.atguigu.spring.tx.xml;

 

import org.springframework.jdbc.core.JdbcTemplate;

 

public class BookShopDaoImpl implements BookShopDao {

 

    private JdbcTemplate jdbcTemplate;

   

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {

        this.jdbcTemplate = jdbcTemplate;

    }

   

    @Override

    public int findBookPriceByIsbn(String isbn) {

        String sql = "SELECT price FROM book WHERE isbn = ?";

        return jdbcTemplate.queryForObject(sql, Integer.class, isbn);

    }

 

    @Override

    public void updateBookStock(String isbn) {

        //检查书的库存是否足够, 若不够, 则抛出异常

        String sql2 = "SELECT stock FROM book_stock WHERE isbn = ?";

        int stock = jdbcTemplate.queryForObject(sql2, Integer.class, isbn);

        if(stock == 0){

            throw new BookStockException("库存不足!");

        }

       

        String sql = "UPDATE book_stock SET stock = stock -1 WHERE isbn = ?";

        jdbcTemplate.update(sql, isbn);

    }

 

    @Override

    public void updateUserAccount(String username, int price) {

        //验证余额是否足够, 若不足, 则抛出异常

        String sql2 = "SELECT balance FROM account WHERE username = ?";

        int balance = jdbcTemplate.queryForObject(sql2, Integer.class, username);

        if(balance < price){

            throw new UserAccountException("余额不足!");

        }

       

        String sql = "UPDATE account SET balance = balance - ? WHERE username = ?";

        jdbcTemplate.update(sql, price, username);

    }

 

}

tx\xml\BookStockException.java

package com.atguigu.spring.tx.xml;

 

public class BookStockException extends RuntimeException{

 

    /**

     *

     */

    private static final long serialVersionUID = 1L;

 

    public BookStockException() {

        super();

        // TODO Auto-generated constructor stub

    }

 

    public BookStockException(String message, Throwable cause,

            boolean enableSuppression, boolean writableStackTrace) {

        super(message, cause, enableSuppression, writableStackTrace);

        // TODO Auto-generated constructor stub

    }

 

    public BookStockException(String message, Throwable cause) {

        super(message, cause);

        // TODO Auto-generated constructor stub

    }

 

    public BookStockException(String message) {

        super(message);

        // TODO Auto-generated constructor stub

    }

 

    public BookStockException(Throwable cause) {

        super(cause);

        // TODO Auto-generated constructor stub

    }

 

   

}

tx\xml\SpringTransactionTest.java

package com.atguigu.spring.tx.xml;

 

import java.util.Arrays;

 

import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

import com.atguigu.spring.tx.xml.service.BookShopService;

import com.atguigu.spring.tx.xml.service.Cashier;

 

public class SpringTransactionTest {

 

    private ApplicationContext ctx = null;

    private BookShopDao bookShopDao = null;

    private BookShopService bookShopService = null;

    private Cashier cashier = null;

   

    {

        ctx = new ClassPathXmlApplicationContext("applicationContext-tx-xml.xml");

        bookShopDao = ctx.getBean(BookShopDao.class);

        bookShopService = ctx.getBean(BookShopService.class);

        cashier = ctx.getBean(Cashier.class);

    }

   

    @Test

    public void testTransactionlPropagation(){

        cashier.checkout("AA", Arrays.asList("1001", "1002"));

    }

   

    @Test

    public void testBookShopService(){

        bookShopService.purchase("AA", "1001");

    }

   

}

tx\xml\UserAccountException.java

package com.atguigu.spring.tx.xml;

 

public class UserAccountException extends RuntimeException{

 

    /**

     *

     */

    private static final long serialVersionUID = 1L;

 

    public UserAccountException() {

        super();

        // TODO Auto-generated constructor stub

    }

 

    public UserAccountException(String message, Throwable cause,

            boolean enableSuppression, boolean writableStackTrace) {

        super(message, cause, enableSuppression, writableStackTrace);

        // TODO Auto-generated constructor stub

    }

 

    public UserAccountException(String message, Throwable cause) {

        super(message, cause);

        // TODO Auto-generated constructor stub

    }

 

    public UserAccountException(String message) {

        super(message);

        // TODO Auto-generated constructor stub

    }

 

    public UserAccountException(Throwable cause) {

        super(cause);

        // TODO Auto-generated constructor stub

    }

 

   

   

}

tx\xml\service\BookShopService.java

package com.atguigu.spring.tx.xml.service;

 

public interface BookShopService {

   

    public void purchase(String username, String isbn);

   

}

tx\xml\service\Cashier.java

package com.atguigu.spring.tx.xml.service;

 

import java.util.List;

 

public interface Cashier {

 

    public void checkout(String username, List<String> isbns);

   

}

tx\xml\service\impl\BookShopServiceImpl.java

package com.atguigu.spring.tx.xml.service.impl;

 

import com.atguigu.spring.tx.xml.BookShopDao;

import com.atguigu.spring.tx.xml.service.BookShopService;

 

 

public class BookShopServiceImpl implements BookShopService {

 

    private BookShopDao bookShopDao;

   

    public void setBookShopDao(BookShopDao bookShopDao) {

        this.bookShopDao = bookShopDao;

    }

   

    @Override

    public void purchase(String username, String isbn) {

       

        try {

            Thread.sleep(1000);

        } catch (InterruptedException e) {}

       

        //1. 获取书的单价

        int price = bookShopDao.findBookPriceByIsbn(isbn);

       

        //2. 更新数的库存

        bookShopDao.updateBookStock(isbn);

       

        //3. 更新用户余额

        bookShopDao.updateUserAccount(username, price);

    }

 

}

tx\xml\service\impl\CashierImpl.java

package com.atguigu.spring.tx.xml.service.impl;

 

import java.util.List;

 

import com.atguigu.spring.tx.xml.service.BookShopService;

import com.atguigu.spring.tx.xml.service.Cashier;

 

public class CashierImpl implements Cashier {

 

    private BookShopService bookShopService;

   

    public void setBookShopService(BookShopService bookShopService) {

        this.bookShopService = bookShopService;

    }

   

    @Override

    public void checkout(String username, List<String> isbns) {

        for(String isbn: isbns){

            bookShopService.purchase(username, isbn);

        }

    }

 

}

 

End

以上是关于Note_JavaWeb_Spring_尚硅谷的主要内容,如果未能解决你的问题,请参考以下文章

视频分享尚硅谷HTML5前端视频_React视频

尚硅谷视频学校教程1

尚硅谷MyBatis_1_Mybatis简介

架构师 之 狂刷小视频Spring5

Flink 尚硅谷学习笔记

尚硅谷RBAC权限实战视频