链接:https://baobeihuijia.com/bbhj/
原始的Mybatis与数据库交互【通过sqlmapconfig来配置和连接】
使用第三方包Spring-Mybatis,将mybatis改为spring的模式,不要再类内new SqlSessionFactory,而是把mybatis当作容器的对象可以用
public class MybatisConfig {
//定义bean,SqlSessionFactoryBean,用于产生SqlSessionFactory对象
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
ssfb.setTypeAliasesPackage("com.itheima.domain");
ssfb.setDataSource(dataSource);
return ssfb;
}
//定义bean,返回MapperScannerConfigurer对象
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("com.itheima.dao");
return msc;
}
}
Junit与spring的整合(在测试类上添加注解,然后在类内直接@Autowired就可以将容器的对象引入测试)
//设置类运行器
@RunWith(SpringJUnit4ClassRunner.class)
//设置Spring环境对应的配置类
@ContextConfiguration(classes = SpringConfig.class)
AOP:面向切面编程,通过调用第三方包AOP,不需要new对象,只需要新建一个component类,并且通过@EnableAspectJAutoProxy和@Aspect保证config知道有AOP并且知道哪个是AOP,从而调度对象代码执行时,切入执行通知
在不惊动原始设计的基础上为其增强功能
在spring-config中添加
@EnableAspectJAutoProxy
@Component
//设置当前类为切面类类
@Aspect
public class MyAdvice {
//设置切入点,要求配置在方法上方
@Pointcut("execution(void com.itheima.dao.BookDao.update())")
private void pt(){}
//设置在切入点pt()的前面运行当前操作(前置通知)
// @Before("pt()")
public void method(){
System.out.println(System.currentTimeMillis());
}
}
AOP工作流程
AOP切入点描述表达式
execution(返回值 方法路径 (参数))
// 采用通配符来为一批方法设置切入点
// 技巧
切入点一般描述到接口
返回值:对于增删改方法用精准类型加速匹配,对于查询类使用*通配快速匹配
AOP通知类型
前置通知Before
后置通知After
环绕Around【ProceedingJoinPoint pjp】
// 拦截后需要return
// 要抛出异常,不然就相当于执行原始代码出现问题,但是在这里将问题吃掉了
@Around("pt2()")
public Object aroundSelect(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("around before advice ...");
//表示对原始操作的调用
Integer ret = (Integer) pjp.proceed();
System.out.println("around after advice ...");
return ret;
}
AfterReturning
AfterThrow
AOP通知拿参数
都可以拿到参数,可被修改
JoinPoint jp
Object[] args = jp.getArgs();
System.out.println(Arrays.toString(args));
public Object around(ProceedingJoinPoint pjp) {
Object[] args = pjp.getArgs();
System.out.println(Arrays.toString(args));
args[0] = 666;
Object ret = null;
try {
ret = pjp.proceed(args);
} catch (Throwable t) {
t.printStackTrace();
}
return ret;
}
返回值
// 接返回值
@AfterReturning(value = "pt()",returning = "ret")
public void afterReturning(JoinPoint jp,String ret) {
System.out.println("afterReturning advice ..."+ret);
}
// 接返回值
@Around("pt2()")
public Object aroundSelect(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("around before advice ...");
//表示对原始操作的调用
Integer ret = (Integer) pjp.proceed();
System.out.println("around after advice ...");
return ret;
}
异常
@Transactional// 接异常
@AfterThrowing(value = "pt()",throwing = "t")
public void afterThrowing(Throwable t) {
System.out.println("afterThrowing advice ..."+t);
}
// 接异常
@Around("pt2()")
public Object aroundSelect(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("around before advice ...");
//表示对原始操作的调用
Integer ret = (Integer) pjp.proceed();
System.out.println("around after advice ...");
return ret;
}
// 在接口上添加@Transactional
// 定义一个事务管理器
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
//第三方需要对象的时候要通过参数
transactionManager.setDataSource(dataSource);
return transactionManager;
}
// 告诉spring要检测注解事务
@EnableTransactionManagement
Spring的事务原理:通过使用共同的datasource来开启mysql事务
有些异常默认不参与回滚:需要@Transactional的时候手动添加
事务传播行为有七种:REQUIRES_NEW是让该事务协调员不加入到事务管理员,而是自己开一个事务,失败了不会跟着回滚
@Transactional(propagation = Propagation.REQUIRES_NEW)
务方
[外链图片转存中…(img-OBMznC6o-1703559380919)]
有些异常默认不参与回滚:需要@Transactional的时候手动添加
事务传播行为有七种:REQUIRES_NEW是让该事务协调员不加入到事务管理员,而是自己开一个事务,失败了不会跟着回滚
@Transactional(propagation = Propagation.REQUIRES_NEW)