AOP简述

面向切面编程,扩展功能不修改源代码实现。AOP采用横向抽取机制,取代了传统的纵向继承体系重复代码。

AOP底层原理

AOP操作相关术语

  • 链接点:类里面的被增强的方法。
  • 切入点:类里面的增强的方法,在实际操作中,实际增强的方法叫切入点。
  • 通知/增强:增强的逻辑,称为增强,比如扩展日志功能,这个日志功能称为增强。 前置通知:在方法之前执行 后置通知:在方法之后执行 异常通知:出现异之后执行 最终通知:在后置之后执行 环绕通知:在方法之前和之后执行
  • 切面:把增强应用到具体的方法上面,这个过程称为切面。把增强用到切入点的过程。

Spring的AOP操作

Aspectj框架

在Spring进行aop操作,使用Aspectj框架,这个框架本身不是Spring的一部分,只是一起使用进行AOP操作。

  • 版本在2.0以后支持切点表达式支持。

基于Aspectj实现AOP操作

  • 相关ja包

aopalliance,aspectjweaver,spring-aop,spring-aspects

  • 创建Spring核心配置文件导入AOP约束。 xml <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">

基于Aspectj的xml实现

  • 常用表达式 通过execution函数表达式实现。

execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)

  • execution(* /增强方法的全路径/): *代表任意修饰符,空格后跟随增强方法的全路径。
  • execution(* com.Hello.*):代表该类的所有方法
  • execution(* .(..))
  • execution(* save*(..)) 表示以save开头的方法进行增强。

xml配置代码

<!--1.配置类-->
    <bean id="book" class="aop.Book"/>
    <bean id="myBook" class="aop.MyBook"/>
    <!--2.配置aop操作-->
    <aop:config>
        <!--2.1配置切入点-->
        <aop:pointcut id="pointcut1" expression="execution(* aop.Book.add())"/>
        <!--2.2配置切面-->
        <aop:aspect ref="myBook">
            <aop:before method="before1" pointcut-ref="pointcut1"/>
        </aop:aspect>
    </aop:config>

基于Aspectj的注解实现

创建类的对象,在spring的配置文件中开启aop操作。

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

通过注解来实现。

在增强类上 @Aspect注解类,@Before注解方法(前置通知)。

  • @Before
  • @AfterReturning
  • @Around
  • @AfterThrowing
  • @After

Spring的JdbcTemplate操作

Springdao层,使用JdbcTemplate,Spring为各种支持的持久化技术,都提供了简单操作的模板和回调。

ORM持久化技术 模板类
JDBC org.springframework.jdbc.core.JdbcTemplate
Hibemate5.0 org.springframework.orm.hibernate5.HibernateTemplate
IBatis(MyBatis) org.springframework.orm.ibatis.sqlMapClientTempate
JPA org.springframework.orm.jpa.JpaTempate

JdbcTemplate使用

都是对数据库进行crud操作。

  • 导入JdbcTemplate相关jar包

spring-jdbc spring-tx

  • 创建对象设置数据库信息,比如:加载驱动,设置url,用户名,密码等。 实例代码
DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUsername("root");
        dataSource.setUrl("jdbc:mysql://localhost:3306/JdbcDemo");
        dataSource.setPassword("12qwaszx");
  • 创建 JdbcTemplate模板对象,设置数据源。
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
  • 调用JdbcTemplate对象里面的方法实现操作。

添加

    String sql = "INSERT INTO jdbcTest (id, name, password) VALUES (?,?,?)";
    jdbcTemplate.update(sql, "1", "lucy", "1234");

修改

    String sql = "UPDATE jdbcTest\n" +
                "SET name = ?\n" +
                "WHERE id=?";
    jdbcTemplate.update(sql,"cat","1");

删除

    String sql = "DELETE FROM jdbcTest WHERE name=?";
    jdbcTemplate.update(sql,"cat");

查询

JdbcTemplate实现查询,有接口RowMapper, JdbcTemplate针对这个接口美欧提供实现类,等到不同的类型数据需要自己封装

  • 查询一个值
    //查询返回某值
    String sql1="SELECT count(*) FROM jdbcTest";
    int count=template.queryForObject(sql1,Integer.class);
  • 返回对象
    //查询返回对象
    String sql2 = "select * from jdbcTest where name=?";
    //调用jdbcTemplate方法
    User user=template.queryForObject(sql2,new MyRowMapper() , "tom");
    System.out.println(user);

要自己封装这个类 其中querForObject这个方法的第二个值为RowMapper,需要自己进行封装。 MyRowMapper.class

class MyRowMapper implements RowMapper<User> {
    @Override
    public User mapRow(ResultSet resultSet, int i) throws SQLException {
        //从结果集里面把数据得到
        String username = resultSet.getString("name");
        String password = resultSet.getString("password");
        //把数据封装到对象里面
        User user = new User();
        user.setName(username);
        user.setPassword(password);
        return user;
    }
}
  • 返回list集合
        String sql3 = "select * from jdbcTest";
        List<User> list = template.query(sql3, new MyRowMapper());
        System.out.println(list);

Spring配置连接池和dao使用JdbcTemplate

配置c3p0连接池

  1. 导入jar包 c3p0mchange-commons-java
  2. 在Spring的配置文件配置连接池
  3. 在dao中使用

dao使用jdbctemplate

  1. 在Service中注入Dao。
  2. 在Dao中注入jdbc模板。
  3. 在模板中注入连接池。
  4. 在连接池中写配置。

示例代码

UserService.class

package com.c3p0;

/**
 * Created by youngxhui
 * Time is 17-2-19.
 */
public class UserService {

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    public void add(){
        userDao.add();
    }
}

UserDao.class

package com.c3p0;

import org.springframework.jdbc.core.JdbcTemplate;

/**
 * Created by youngxhui
 * Time is 17-2-19.
 */
public class UserDao {
    private JdbcTemplate jdbcTemplate;
    public void add() {

        String sql="INSERT INTO jdbcTest (id, name, password) VALUES (?,?,?)";
        jdbcTemplate.update(sql, 5, "lili", "123456");

    }

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
}

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

    <!--配置c3p0的连接池-->
    <bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/JdbcDemo"/>
        <property name="user" value="root"/>
        <property name="password" value="12qwaszx"/>
    </bean>

    <bean id="userService" class="com.c3p0.UserService">
        <property name="userDao" ref="userDao"/>
    </bean>

    <bean class="com.c3p0.UserDao" id="userDao">
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>

    <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
        <property name="dataSource" ref="comboPooledDataSource"/>
    </bean>
</beans>

Spring事务管理

什么是事务

事务是访问数据库的一个操作序列,数据库应用系统通过事务集来完成对数据库的存取。事务的正确执行使得数据库从一种状态转换成另一种状态。

事务特性

  • 原子性(atomicity)
  • 一致性(consistency
  • 隔离性 (isolation)
  • 持久性(durability)

Sping事务管理api

spring对事务管理的两种方式

  • 编程式事务管理(不用)
  • 声明式事务管理
    • 基于xml配置文件实现
    • 基于注解实现

api介绍

Spring事务管理高层抽象主要包含3个接口

  • PlatformTransactionManager事务管理器
  • TransactionDefinition事务定义信息
  • TransactionStatus事务具体运行状态

PlatformTransactionManager针对不同的dao层,提供了不同的接口实现类

事务 说明
org.springframework.idbc.datasource.DataSourceTransactionManager 使用Spring JDBC或iBatis进行持久化数据时使用
org.springframework.orm.hibernate5.HibernateTransactionManger 使用Hibernate5.0版本进行持久化数据时使用
org.springframework.orm.jpa.JpaTransactionManager 使用JPA进行持久化
org.springframework.jdo.JdoTransactionManager 当持久化机制是Jdo时使用
org.springframework.transaction.ita.JtaTransactionManager 使用一个JTA实现来管理事务,在一个事务跨越多个资源时必须使用