spring4(2)

Spring Aop基础

切面的五个通知,切点
1.通过注解
(1).将被代理类加入Ioc容器
(2).声明切面,并在切面中写需要使用的通知
把 LoggingAspect类声明为一个切面:需要把该类放到Ioc容器中,再声明为一个切面
多个切面之间: 可以使用@Order注解指定切面的优先级,值越小优先级越高

@Order(5)
@Aspect
@Component
public class LoggingAspect {
(3).在切面类中写需使用的通知
①.定义切点

/**
 * 定义切点:定义一个方法,用于声明切入点表达式.一般地,该方法中再不需要添加其他代码.
 * 使用@Pointcut声明切入点表达式.
 * 后面的其他通知直接使用方法名来直接引用当前切入点表达式.
 */
@Pointcut("execution(public int AtithmeticCalculator.*(int ,int ))")
public void declare() {
}

②.前置通知

//前置通知:声明该方法是一个通知,在目标方法开始之前执行
@Before("declare()")
public void beforeMethod(JoinPoint joinPoint) {
    //获取方法名
    String methodName = joinPoint.getSignature().getName();
    //获取方法传入的参数
    List<Object> args = Arrays.asList(joinPoint.getArgs());
    //打印日志
    System.out.println("The method  " + methodName + " begin with  " + args);
}

③.后置通知

//后置通知:在目标方法执行后(无论是否发生异常)执行的通知和切点
@After("declare()")
public void afterMethod(JoinPoint joinPoint) {
    //获取方法名
    String methodName = joinPoint.getSignature().getName();
    //获取方法传入的参数
    List<Object> args = Arrays.asList(joinPoint.getArgs());
    //打印日志
    System.out.println("The method  " + methodName + " after with  " + args);
}

④.返回通知

/**
 * 返回通知
 * 返回通知可以访问方法的返回值
 *
 * @param joinPoint
 * @param result:方法的返回值
 */
@AfterReturning(value = "declare()", returning = "result")
public void afterReturnMethod(JoinPoint joinPoint, Object result) {
    //获取方法名
    String methodName = joinPoint.getSignature().getName();
    //获取方法传入的参数
    List<Object> args = Arrays.asList(joinPoint.getArgs());
    //打印日志
    System.out.println("The method  " + methodName
            + " afterReturning with  " + args + "  result:" + result);
}

⑤.异常通知

/**
 * 异常通知
 * 指定出现空指针异常才执行afterThrowingMethod方法:为public void afterThrowingMethod(JoinPoint joinPoint,NullPointerException ex) {}
 *
 * @param joinPoint
 * @param ex        异常对象
 */
@AfterThrowing(value = "declare()", throwing = "ex")
public void afterThrowingMethod(JoinPoint joinPoint, Exception ex) {
    //获取方法名
    String methodName = joinPoint.getSignature().getName();
    //获取方法传入的参数
    List<Object> args = Arrays.asList(joinPoint.getArgs());
    //打印日志
    System.out.println("The method  " + methodName + "afterThrowing with  " + args + "  Exception:" + ex);
}

⑥.环绕通知

//    /**
//     * 环绕通知
//     * 环绕通知需携带ProceedingJoinPoint类型的参数
//     * 环绕通知相当于动态代理全过程:ProceedingJoinPoint类型的参数可以决定是否执行目标方法
//     * 且环绕通知必须有返回值,返回值既为目标方法的返回值
//     */
//    @Around("execution( public int AtithmeticCalculator.*(int ,int ))")
//    public Object aroundMethod(ProceedingJoinPoint pjd) {
//        Object result = null;
//        String methodName = pjd.getSignature().getName();
//
//        try {
//            //前置通知
//            System.out.println("The method  " + methodName + " begin with  " + Arrays.asList(pjd.getArgs()));
//            //执行目标方法
//            result = pjd.proceed();
//            //返回通知
//            System.out.println("The method" + methodName + "return with  " + result);
//
//
//        } catch (Throwable e) {
//            //异常通知
//            System.out.println("The method" + methodName + " Exception:" + e);
//        }
//          //后置通知
//        System.out.println("The method" + methodName + " after with"+ Arrays.asList(pjd.getArgs())  );
//        return result;
//    }

}
(3).在spring的配置文件中配置扫描注解,和使Aspectj 注解起作用;

<context:component-scan base-package="aop.imple"></context:component-scan>
    <!--使Aspectj 注解起作用:自动匹配的类代理生成对象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

2.基于配置文件的方式配置Aop
(1).定义切面类

package imple;

import org.aspectj.lang.JoinPoint;

import java.util.Arrays;
import java.util.List;

public class LoggingAspect {



    public void beforeMethod(JoinPoint joinPoint) {
        //获取方法名
        String methodName = joinPoint.getSignature().getName();
        //获取方法传入的参数
        List<Object> args = Arrays.asList(joinPoint.getArgs());
        //打印日志
        System.out.println("The method  " + methodName + " begin with  " + args);
    }


    public void afterMethod(JoinPoint joinPoint) {
        //获取方法名
        String methodName = joinPoint.getSignature().getName();
        //获取方法传入的参数
        List<Object> args = Arrays.asList(joinPoint.getArgs());
        //打印日志
        System.out.println("The method  " + methodName + " after with  " + args);
    }


    public void afterReturnMethod(JoinPoint joinPoint, Object result) {
        //获取方法名
        String methodName = joinPoint.getSignature().getName();
        //获取方法传入的参数
        List<Object> args = Arrays.asList(joinPoint.getArgs());
        //打印日志
        System.out.println("The method  " + methodName
                + " afterReturning with  " + args + "  result:" + result);
    }


    public void afterThrowingMethod(JoinPoint joinPoint, Exception ex) {
        //获取方法名
        String methodName = joinPoint.getSignature().getName();
        //获取方法传入的参数
        List<Object> args = Arrays.asList(joinPoint.getArgs());
        //打印日志
        System.out.println("The method  " + methodName + "afterThrowing with  " + args + "  Exception:" + ex);
    }


}

(2).spring配置文件

<?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.xsd">
    <!--配置Bean-->
    <bean id="atithmeticCalculatorImpl" class="imple.AtithmeticCalculatorImpl"></bean>
    <!--配置切面的Bean-->
    <bean id="loggingAspect" class="imple.LoggingAspect"></bean>
    <bean id="vlidationAspect" class="imple.VlidationAspect"></bean>
    <!--配置Aop-->
    <aop:config>
        <!--配置切点表达式-->
        <!--expression:要执行的目标方法
        execution(目标方法)
        目标方法:权限修饰符 返回值 那个包下那个类的那个方法
        *:所有的
        ..所有的参数
        -->
        <aop:pointcut id="pointcut"
                      expression="execution(public int imple.AtithmeticCalculatorImpl.*(..))"></aop:pointcut>
        <!--配置切面及其通知-->
        <aop:aspect ref="loggingAspect" order="2">
            <!--配置通知-->
            <!--method:目标方法执行前或后或出异常所执行的方法-->
            <!--pointcut-ref:引用切点-->
            <aop:before method="beforeMethod" pointcut-ref="pointcut"></aop:before>
            <aop:after method="afterMethod" pointcut-ref="pointcut"></aop:after>
            <aop:after-returning method="afterReturnMethod"
                                 pointcut="execution(public int imple.AtithmeticCalculatorImpl.*(int ,int ))"
                                 returning="result"></aop:after-returning>
            <aop:after-throwing method="afterThrowingMethod" pointcut-ref="pointcut" throwing="ex"></aop:after-throwing>
        </aop:aspect>
        <aop:aspect ref="vlidationAspect" order="1">
            <aop:before method="validateArgs" pointcut-ref="pointcut"></aop:before>
        </aop:aspect>
    </aop:config>
</beans>

注意:假如某个类中的方法为某个切面通知的目标方法(这个类已经加进Ioc容器),则获取这个类的Bean时为代理类的对象,不是被代理类的对象

jdbcTempLate

属性配置文件

jdbc.user=root
jdbc.password=qq2694200519
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///spring3

jdbc.initPoolSize=5
jdbc.maxPoolSize=10

Spring配置文件

<?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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool.xsd">
    <Context:property-placeholder location="db.properties"></Context:property-placeholder>
    <!--配置c3p0数据源-->
    <bean id="DataSouce" 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>

    <!--配置spring的jdbcTempLate-->
    <bean id="jdbcTempLate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="DataSouce"></property>
    </bean>
    
    </beans>

①.执行INSET,DELETE,UPDATE

@Test
public void textUpdate() {
    String sql = "UPDATE book SET author= ? WHERE id=?";
    jdbcTemplate.update(sql, "李一", 3);
}

②.执行批量更新,批量的INSET,DELETE,UPDATE

@Test
public void textBatchUpdate() {
    String sql = "INSERT INTO trade (tradeTime,userId) VALUES(?,?)";
    List<Object[]> batchArgs = new ArrayList<>();

    for (int i = 0; i < 5; i++) {
        batchArgs.add(new Object[]{new Date(), i});
    }
    jdbcTemplate.batchUpdate(sql, batchArgs);
}

③.从数据库中获取一条记录,实际上得到一个对象

/**
     * 从数据库中获取一条记录,实际上得到一个对象
     * 注意:不是调用queryForObject(sql,book.class,3)方法
     * 而需调用queryForObject(String sql, RowMapper<T> rowMapper, Object... args)
     * 1.RowMapper:指定如何去映射结果集的行,常用的实现类为BeanPropertyRowMapper
     * 2.使用sql中列的别名完成列名和类属性名的映射,例如last_name lastName
     * 3.不支持级联属性
     */
    @Test
    public void textQueryForObject() {
        String sql = "SELECT id,author,title,price,publishingDate,salesAmount,storeNumber,remar remark FROM book WHERE id=?";
//        book b =jdbcTemplate.queryForObject(sql,book.class,3);
        RowMapper<book> rowMapper = new BeanPropertyRowMapper<>(book.class);
        book b = jdbcTemplate.queryForObject(sql, rowMapper, 3);
        System.out.println(b);
    }

④.查询实体类的集合

/**
 * 查询实体类的集合
 * 注意,调用的不是queryForList方法
 */
@Test
public void textQueryForList() {
    String sql = "SELECT id,author,title,price,publishingDate,salesAmount,storeNumber,remar remark FROM book WHERE id>?";
    List<book> books = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(book.class), 1);
    System.out.println(books);
}

⑤.获取单个列的值

/**
 * 获取单个列的值,或做统计查询
 * 使用queryForObject(String sql, Class<T> requiredType)
 */
@Test
public void textQueryForObject2() {
    String sql = "SELECT COUNT(id) FROM book";
    Long count = jdbcTemplate.queryForObject(sql, Long.class);
    System.out.println(count);
}

NamedParameterJdbcTemplate

Spring配置文件

<?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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool.xsd">
    <Context:property-placeholder location="db.properties"></Context:property-placeholder>
    <!--配置c3p0数据源-->
    <bean id="DataSouce" 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>
    <!--使用NamedParameterJdbcTemplate需要配置jdbcTempLate-->
<bean id="jdbcTempLate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="DataSouce"></property>
</bean>
      <!--配置NamedParameterJdbcTemplate,该对象可以使用具名参数,其没有无参数的构造器,所以必须为其构造器指定参数-->
    <bean id="namedParameterJdbcTemplate"
          class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
        <constructor-arg ref="DataSouce"></constructor-arg>
    </bean>
    <Context:component-scan base-package="tx"></Context:component-scan>
</beans>

使用具名参数

/**
 * 使用具名参数时,可以使用update(String sql, SqlParameterSource paramSource)进行更新操作
 * 1.sql语句参数名和类的属性必须一致!
 * 2.使用SqlParameterSource接口的实现类BeanPropertySqlParameterSource作为参数
 */
@Test
public void testNamedParameterJdbcTemplate2() {
    String sql = "INSERT INTO trade (tradeTime,userId) VALUES(:tradeTime,:userId)";
    trade trade = new trade(new Date(),5);
    SqlParameterSource parameterSource=new BeanPropertySqlParameterSource(trade);
    namedParameterJdbcTemplate.update(sql,parameterSource);
}

/**
 * 可以为参数起名字
 * 好处:若有多个参数,则不用去对应位置,直接对应参数名,便于维护
 * 缺点:较为麻烦
 */
@Test
public void testNamedParameterJdbcTemplate() {
    String sql = "INSERT INTO trade (tradeTime,userId) VALUES(:tradeTime,:userId)";
    Map<String, Object> paramMap = new HashMap<>();
    paramMap.put("tradeTime", new Date());
    paramMap.put("userId", 8);
    namedParameterJdbcTemplate.update(sql, paramMap);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值