前言:
在工作中项目提了个动态切换多数据库的需求(具体需求见文章末尾),爬了N多的博客文章总结了大概有以下几种方法:
1、用springboot的AOP进行切面处理配置datasource(service层),然后进行mybaties的配置;(优点:实现难度低。缺点:操作粒度大,难以在一个service的方法中进行数据库切换)
2、同样是使用springboot的AOP进行切面编程,但是是对mapper接口进行切面,这需要对mapper进行包装,接口不能被AOP切面;(优点:实现难度低,同时又可以进行mapper级别细粒度的数据库切换。缺点:每写一个mapper接口,要进行相应的写一个实现类进行静态代理)
3、深入改造mybties的excuctor(写一个myExcutor),在myexcuctor的生成connection的时候进行改变datasouce。实现大概的思路:对mapper接口进行注解,在myexcuctor中获取ms(mapper statement)对象的属性Id(mapper.xml的namespace+id),然后利用反射进行获取对应的mapper接口上的注解值(加上前端传过来的值拼接mysql的url)生成datasource,然后进行数据库操作。(优点:一次编写,以后开发业务可不用再去处理数据库切换问题,实现mapper级别的数据库切换。缺点:技术难度高)
4、开发mybaties插件,对excuctor对象进行拦截处理,和3的方法差不多。
以上实现方法会在该系列文章结束时给出。
重点:也是应为该次的项目需求,才又这一系列的学习探索之路。将这些探索的过程记录下来,分享一下。才疏学浅,班门弄斧,望各位大佬指导指导。
一、 手动配置Mybaties,引进mybaties.jar包
1、idea中建maven工程,在pom中引入mybaties依赖,如下图:
同时引入mysql-jdbc、junit、lombok,全部pom的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http:mybaties//maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>MyBatiesDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
2、从XML中构建SqlSessionFactory
2.1、了解mybaties的基本结构
基于SqlMapConfig.xml (Mybaties配置文件), SqlSessionFactory创建SqlSession(对外提供数据库操作接口),SqlSession操作Executor进行数据库操作,Executor对象中操作数据库的sql语句为Mapped statement 处理(动态代理)mapper.xml转化而来方法,查询后封装数据返回。其底层核心为jdbc中内容,在jdbc之上对SQL进行进行xml化,读取xml中的内容与对应的接口进行动态代理,用代理的方法放到jdbc中,查询的结果进行封装。而这其中增加了缓存等一些配置处理,这就是mybaties的本质。不熟悉后者忘记jdbc的内容可以看以下代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class DbUtil {
public static final String URL = "jdbc:mysql://localhost:3306/imooc";
public static final String USER = "xiong";
public static final String PASSWORD = "123456";
public static void main(String[] args) throws Exception {
//1.加载驱动程序
Class.forName("com.mysql.jdbc.Driver");
//2. 获得数据库连接
Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
//3.操作数据库,实现增删改查
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT user_name, age FROM imooc_goddess");
//如果有数据,rs.next()返回true
while(rs.next()){
System.out.println(rs.getString("user_name")+" 年龄:"+rs.getInt("age"));
}
}
}
2.2、构建SqlSessionFactory
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。
从 XML 文件中构建 SqlSessionFactory 的实例非常简单,建议使用类路径下的资源文件进行配置。 但也可以使用任意的输入流(InputStream)实例,比如用文件路径字符串或 file:// URL 构造的输入流。MyBatis 包含一个名叫 Resources 的工具类,它包含一些实用方法,使得从类路径或其它位置加载资源文件更加容易。
夜深人静,该睡觉了!
------见Mybaties学习之路二
项目需求:编写一个软件级别的平台,要求进行租户数据隔离,而且业务中每个模块的数据也进行隔离。所以有N+M的数据库隔离。
即所谓的SaaS平台,具体概念如下(百度):
SaaS即Software-as-a-Service(软件即服务)是随着互联网技术的发展和应用软件的成熟, 在21世纪开始兴起的一种完全创新的软件应用模式。传统模式下,厂商通过License将软件产品部署到企业内部多个客户终端实现交付。SaaS定义了一种新的交付方式,也使得软件进一步回归服务本质。企业部署信息化软件的本质是为了自身的运营管理服务,软件的表象是一种业务流程的信息化,本质还是第一种服务模式,SaaS改变了传统软件服务的提供方式,减少本地部署所需的大量前期投入,进一步突出信息化软件的服务属性,或成为未来信息化软件市场的主流交付模式。