目录
[一. spring管理数据访问层](#一. spring管理数据访问层)
[1. spring统一管理数据库连接对象](#1. spring统一管理数据库连接对象)
[(1). 添加 数据访问层 jar 依赖](#(1). 添加 数据访问层 jar 依赖)
[(2). 配置数据库连接对象](#(2). 配置数据库连接对象)
[(1). 创建service,dao接口,sql映射文件,mybatis配置文件](#(1). 创建service,dao接口,sql映射文件,mybatis配置文件)
[(2) 导入jar](#(2) 导入jar)
[二. AOP 面向切面编程](#二. AOP 面向切面编程)
[1. 定义:](#1. 定义:)
[2. 核心实现(方法):](#2. 核心实现(方法):)
[(1)下载aop aspects框架](#(1)下载aop aspects框架)
[三. Spring事务管理](#三. Spring事务管理)
[1. 定义:](#1. 定义:)
[2. 实现方式:](#2. 实现方式:)
[3. 配置事务管理](#3. 配置事务管理)
一. spring管理数据访问层
以前使用jdbc和mybatis都是由我们自己创建数据库连接的对象
现在使用spring后,可以由spring框架统一管理数据库连接对象,如果在mybatis中需要链接数据库,只需要将spring生成的数据库链接对象注入mybatis
1. spring统一管理数据库连接对象
(1). 添加 数据访问层 jar 依赖
<dependencies> <!-- spring-context spring最核心功能--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.2.RELEASE</version> </dependency> \<!-- spring-jdbc --\> \<dependency\> \<groupId\>org.springframework\</groupId\> \<artifactId\>spring-jdbc\</artifactId\> \<version\>5.2.2.RELEASE\</version\> \</dependency\> \<!-- 阿里数据源 管理对象--\> \<dependency\> \<groupId\>com.alibaba\</groupId\> \<artifactId\>druid\</artifactId\> \<version\>1.1.10\</version\> \</dependency\> \<!--mysql jar的坐标--\> \<dependency\> \<groupId\>mysql\</groupId\> \<artifactId\>mysql-connector-java\</artifactId\> \<version\>8.0.16\</version\> \</dependency\> </dependencies>
(2). 配置数据库连接对象
在application.xml中
html
<!--配置数据库连接对象
本次使用的是阿里巴巴提供的Druid(德鲁伊)数据库连接管理类-->
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/libdb?serverTimezone=Asia/Shanghai"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
<property name="initialSize" value="10"></property><!--初始化连接数量-->
<property name="maxActive" value="20"></property><!--最大连接数量-->
</bean>
2.spring集成管理mybatis
核心: 将SqlSessionFactory交由Spring管理,并由Spring管理对 dao 接口的代理实现
即不需要在mybatis中添加数据库连接部分,因为spring会数据库连接,如上
(1). 创建service,dao接口,sql映射文件,mybatis配置文件
java
package com.ffyc.spring.service;
import com.ffyc.spring.dao.LoginDao;
import com.ffyc.spring.model.Admin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class LoginService {
@Autowired
private LoginDao loginDao;
public void login(){
Admin admin = new Admin();
admin.setAccount("admin");
admin.setPassword("111");
Admin admin1 = loginDao.login(admin);
System.out.println(admin1);
}
}
java
package com.ffyc.spring.dao;
import com.ffyc.spring.model.Admin;
public interface LoginDao {
Admin login(Admin admin);
}
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>
<!-- xml是一种配置文件,主要用来存储配置文件 -->
<!-- 配置全局设置-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!-- 为类配置别名 -->
<typeAliases>
<!-- <typeAlias type="com.ffyc.mybatispro.model.Admin" alias="Admin"/>-->
<package name="com.ffyc.spring.model"/> <!-- 配置模型类的包地址-->
</typeAliases>
</configuration>
(2) 导入jar
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!--spring管理mybatis的jar-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
(3) 在application.xml中 配置sqlSessionFactory
html
<!--spring管理sqlSessionFactory对象 ref连接-->
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" >
<property name="dataSource" ref="druidDataSource"></property><!--注入数据源-->
<property name="configLocation" value="classpath:mybatis.xml"></property>
<property name="mapperLocations" value="classpath:mappers/*Mapper.xml">
</property>
</bean>
<!--生成mybatis接口代理对象 直接扫描指定的包-->
<bean id="mapperFactory" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.ffyc.spring.dao"></property>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory">
</property>
</bean>
(4)在service层中,注入接口代理对象
java
@Service
public class LoginService {
@Autowired
private LoginDao loginDao;
}
二. AOP 面向切面编程
1. 定义:
AOP是对OOP的补充,利用AOP思想,可以将程序中的业务代码和非业代码进行分离 ,降低代码之间的耦合度 ,在增加新功能(非业务代码)时,可以不用修改原来的业务代码.例如 打印日志 , 权限判断 , 事务管理 , 统一异常处理
AOP 的基本概念
**连接点(Joinpoint):**类中可以被增强的方法,这个方法就被称为连接点
**切入点(pointcut):**类中有很多方法可以被增强,但实际中只有 add 和 update
被增了,那么 add 和 update 方法就被称为切入点(实际实现的连接点)
**通知(Advice):**通知是指一个切面在特定的连接点要做的事情(增强的功能)。通
知分为方法执行前通知,方法执行后通知,环绕通知等.
**目标(Target):**代理的目标对象(连接点,切入点所在类)
**代理(Proxy):**向目标对象应用通知时创建的代理对象
2. 核心实现(方法):
为业务代码提供代理对象,可以动态的调用相关的方法,我们只需要做一些简单的配置(告诉代理对象什么时候调用哪个方法)
注意: AOP不是spring框架特有的功能,只是spring将AOP这一思想引用到了自己的框架中,而spring框架中对AOP的具体实现是使用aspectj(AOP)框架
(1)下载aop aspects框架
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
(2)添加配置,启动AspectJ注解
<aop:aspectj-autoproxy />
(3)创建并配置通知(功能)
前置通知,后置通知,环绕通知,异常通知,返回通知.
@Before 前置通知:方法执行之前
@After 后置通知:方法执行之后,无论是否出现异常
@AfterReturnning 返回通知:方法成功执行之后通知,出现异常不执行
@AfterThrowing 异常通知:抛出异常之后通知
@Around 环绕通知:方法执行前后都有通知
java
package com.ffyc.spring.common;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Component
@Aspect
public class Common {
/*
通知类型: 前置通知:在目标方法调用之前执行
后置通知:在目标方法执行完成后执行,即使方法运行时出现异常也会执行
返回通知:在方法执行完成时执行,方法出现异常就不执行
异常通知:在方法出现异常时执行
环绕通知:
*/
// *是任意返回值 *(..)是在BookService中任意参数的方法 ..为方法参数
@Before("execution(* com.ffyc.spring.service.BookService.*(..))")//@Before 前置通知:方法执行之前
public void savelog(){
System.out.println("保存日志1");
}
// *.*(..)是在service包中任意类的任意参数方法 ..为方法参数
@After("execution(* com.ffyc.spring.service.*.*(..))")//@After 后置通知:方法执行之后 即使出现异常也会执行
public void savelog1(){
System.out.println("保存日志1");
}
// *.*(..)是在service包中任意类的任意参数方法 ..为方法参数
@AfterReturning("execution(* com.ffyc.spring.service.*.*(..))")// @AfterReturning 出现异常不执行,即没有返回值不执行
public void savelog2(){
System.out.println("保存日志2");
}
@AfterThrowing(value = "execution(* com.ffyc.spring.service.BookService.*(..))",throwing = "e")//@AfterThrowing 异常通知:抛出异常之后通知
public void afterthrow(Throwable e){
System.out.println("系统繁忙"+ e.getMessage());
e.printStackTrace();
}
@Around("execution(* com.ffyc.spring.service.*.*(..))")//@Around 环绕通知:方法执行前后都有通知
public Object around(ProceedingJoinPoint joinPoint){//joinPoint相当于代理对象
Object o =null;
try {
System.out.println("前置通知");
//获得目标方法参数
Object[] args = joinPoint.getArgs();
System.out.println(Arrays.toString(args));
o = joinPoint.proceed();//调用自己的目标方法
System.out.println("返回通知");
} catch (Throwable e) {
System.out.println("异常通知");
e.printStackTrace();
}
System.out.println("后置通知");
return o;
}
}
三. Spring事务管理
1. 定义:
事务是数据库提供的一种管理机制,要求在同一事物中执行多条sql,要么都执行成功,要么都不执行,称为事务的原子性特征.例如转账
以前在mybatis中, 我们是手动自己提交事务的(sqlsession.commit)
在spring中, 可以在AOP的基础上,让spring中自动的为我们在方法的执行成功时,自动提交事务
2. 实现方式:
(1).编程式事务实现: 需要自己通过事务管理对象,手动提交事务
(2).声明式事务实现: 在方法或类上添加一个注解标签即可, 这样方法在spring事务管理中进行, 方法执行成功测提交事务, 出现异常则回滚事务
3. 配置事务管理
<!-- 配置 spring 事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="druidDataSource"></property>
</bean>
<!-- 开启注解事务管理 --><tx:annotation-driven transaction-manager="transactionManager"/>
在类或方法上使用@Transactional 标签即可.
4. 声明式事务不生效的场景
@Transactional 应用在非 public 修饰的方法上;
异常被 catch 捕获导致失效;
出现编译期异常;
数据库引擎不支持事务;