第九章springboot+mybatis+多数据源(aop实现)

     2022-03-20     636

关键词:

在第八章 springboot + mybatis + 多数据源代码的基础上,做两点修改

1、ShopDao

技术分享
package com.xxx.firstboot.dao;

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

import com.xxx.firstboot.domain.Shop;
import com.xxx.firstboot.mapper.ShopMapper;

@Repository
public class ShopDao {
    @Autowired
    private ShopMapper mapper;

    /**
     * 获取shop
     */
    public Shop getShop(int id) {
        return mapper.getShop(id);
    }
}
View Code

说明:只是去掉了设置数据源key的那一句代码

 

2、DataSourceAspect

技术分享
package com.xxx.firstboot.common.datasource;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import com.xxx.firstboot.dao.ShopDao;

@Aspect
@Component
public class DataSourceAspect {
    
    @Before("execution(* com.xxx.firstboot.dao.*.*(..))")
    public void setDataSourceKey(JoinPoint point){
        //连接点所属的类实例是ShopDao
        if(point.getTarget() instanceof ShopDao){
            DatabaseContextHolder.setDatabaseType(DatabaseType.mytestdb2);
        }else{//连接点所属的类实例是UserDao(当然,这一步也可以不写,因为defaultTargertDataSource就是该类所用的mytestdb)
            DatabaseContextHolder.setDatabaseType(DatabaseType.mytestdb);
        }
    }
    
//    @Around("execution(* com.xxx.firstboot.dao.*.*(..))")
//    public Object setDataSourceKeyByAround(ProceedingJoinPoint point) throws Throwable{
//        if(point.getTarget() instanceof ShopDao){
//            DatabaseContextHolder.setDatabaseType(DatabaseType.mytestdb2);
//        }else{//连接点所属的类实例是UserDao(当然,这一步也可以不写,因为defaultTargertDataSource就是该类所用的mytestdb)
//            DatabaseContextHolder.setDatabaseType(DatabaseType.mytestdb);
//        }
//        return point.proceed();//执行目标方法
//    }
    
}
View Code

说明:列出了两种切面方法,在这里推荐使用前者,原因:

  • @Around:需要写执行目标方法的那一行代码,而这一行代码可能会抛异常,还需要抛出或捕获

对于切点表达式,可以抽取出来,进行重复利用。如上代码可以改为如下:

技术分享
package com.xxx.firstboot.common.datasource;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import com.xxx.firstboot.dao.ShopDao;

@Aspect
@Component
public class DataSourceAspect {

    /**
     * 使用空方法定义切点表达式
     */
    @Pointcut("execution(* com.xxx.firstboot.dao.*.*(..))")
    public void declareJointPointExpression() {
    }

    /**
     * 使用定义切点表达式的方法进行切点表达式的引入
     */
    @Before("declareJointPointExpression()")
    public void setDataSourceKey(JoinPoint point) {
        // 连接点所属的类实例是ShopDao
        if (point.getTarget() instanceof ShopDao) {
            DatabaseContextHolder.setDatabaseType(DatabaseType.mytestdb2);
        } else {// 连接点所属的类实例是UserDao(当然,这一步也可以不写,因为defaultTargertDataSource就是该类所用的mytestdb)
            DatabaseContextHolder.setDatabaseType(DatabaseType.mytestdb);
        }
    }

}
View Code

注意:该切点表达式也可以用在其他切面类中,引入的时候使用"全类名.切点方法名()",例:@Before("com.xxx.firstboot.common.datasource.DataSourceAspect.declareJointPointExpression()")

springboot第九章thymeleaf模板引擎(代码片段)

...ymeleafThymeleaf是另外的一种模板技术,它本身并不属于SpringBoot,SpringBoot只是很好地集成这种模板技术,作为前端页面的数据展示。使用java开发的模板技术,在服务器端运行。把处理后的数据发送给浏览器。模板是... 查看详情

第九章查找

第九章、查找一、查找表:  相同类型的数据组成的集合。查找分为静态查找和动态查找。  1、静态查找:    在查找时,只对数据元素进行查询或检索,称为静态查找。  2、动态查找:    在实施查找的同时... 查看详情

语法》第九章数据类型转换

第二部分 语法 ************第九章数据类型转换*************** JavaScript是一种动态类型语言,变量没有类型限制,可以随时赋予任意值。虽然变量没有类型,但是数据本身和各种运算符对运算子是有类型要求的。如果运算... 查看详情

第九章文档数据库

格式可以是XML,JSON,BSON等。文档具备自述性,呈现分层的树状结构。9.1何谓文档数据库  各文档的“数据模式”也许不同,但是任然可以放在一个集合中。  可以嵌套文档;9.2特性  9.2.1一致性           ... 查看详情

第九章实验

 1.补全程序t1.asm,完成在屏幕上输出内存单元中的十进制两位数。 2.补全程序t2.asm,完成在屏幕上输出data段定义的5个十进制两位数,数据和数据之间以空格间隔。3.教材实验9 查看详情

第九章数据查询基础

 一.数据查询基础  1.查询所有数据   select*from表名  2.根据限制条件查询数据   select*from表名where限制条件  3.根据特定列进行排序,默认为升序排列   select*from表名orderby... 查看详情

第九章:分页

...自TheFlaskMega-TutorialPartIX:Pagination这是FlaskMega-Tutorial系列的第九部分,我将告诉你如何对数据列表进行分页。在第八章我已经做了几个数据库更改,以支持在社交网络非常流行的“粉丝”机制。有了这个功能,接下来我准备好删除... 查看详情

第九章

第九章------HAL HAL是建立在Linux驱动之上的的程序库,他是一个应用层,它的作用保护内部私有。有一种是位于Android层次的系统运行库层,Linux中只保留与寄存器相互的代码,通过HAL进行数据的传递。为Android加入HAL的主要目的... 查看详情

第九章组合模型在信贷风控中的应用

组合模型在信贷风控中的应用简介:在包括违约预测在内的诸多场景中,越来越多的建模人员将模型集成的方式应用在实际工作中,并且取得了不错的成效。本节课将介绍三种基本的集成方式:Bagging,boosting,stacking。目录:1.... 查看详情

第九章接口

interface接口关键词1.是为了让没有继承关系的类,也有继承行为2.接口是一种引用数据类型数据类型3.属性--只能是公共的静态常量属性,就算不写,public,staticfinal也不能改变这一点a.publicstaticfinalintA;4.构造--接口不能有构造--... 查看详情

第九章语句

语句什么是语句控制流语句if语句if…else语句while循环do循环for循环for语句中变量的作用域初始化和迭代表达式中的多表达式switch语句分支示例switch语句补充分支标签跳转语句break语句continue语句标签语句标签标签语句作用域goto语... 查看详情

第九章集合(代码片段)

Java集合框架集合API中以Abstract开头的类是为类库实现者设计的,扩展这些类比直接实现接口要简单得多集合类的基本接口是Collection,它继承了Iterable接口,方法iterator()返回Iterator接口,它是一个迭代器.注意,当要删除元素时,必须先调... 查看详情

programminginlua第九章

1,2,3,4,5,6,第6点很关键:先是调用消费者,来唤醒一个协同例程producer,协同例程producer读取一个数据x后调用send。send函数中调用yield(x),该函数将自己这个协同例程挂起,并返回给之前调用resume的函数。并且返回值的第... 查看详情

第九章

编写一款支持HAL 的Linux 驱动程序的步骤第1 步编写Linux 驱动“编写Linux 驱动”,从表明上看是废话,但如果要为linux 驱动添加HAL,而且想尽量保护敏感数据。Linux 驱动的代码就要尽量简洁,尽可... 查看详情

数据库系统概论-第九章(代码片段)

统一资源定位符UniformResourceLocatorURLWeb上每个可访问文档在全球唯一的名字HTTP请求无连接,请求完成后立即断开双因素认证two-factorauthentication两个独立的因素用于识别一个用户(两个因素不能具有同样的弱点,比如都是密码)使... 查看详情

第九节:mybatis关联查询之一对多查询(代码片段)

一对多,是最常见的一种设计。就是A表的一条记录,对应B表的多条记录,且A的主键作为B表的外键。这主要看以哪张表为中心,下面的测试数据中,从employee表来看,一个员工对应一个部门,是一对一关系,如果从部门角度来看... 查看详情

慕课网javascript进阶篇第九章编程练习

把平常撸的码来博客上再撸一遍既可以加深理解,又可以理清思维。还是很纯很纯的小白,各位看官老爷们,不要嫌弃。最近都是晚睡,昨晚也不例外,两点多睡的。故,八点起来的人不是很舒服,脑袋有点晕呼呼,鉴于昨晚看... 查看详情

第九章

HAL(硬件抽象层)是建立在驱动之上的一套程序库,是位于内核上的应用层。HAL主要目的是为了保护“私人财产”。Linux内核采用GPL协议,该协议要求所有使用者基于GPL协议的源代码必须开源,这对于某些公司和个人是不利的... 查看详情