MySQL,用了好多年了吧,在你印象里是不是一直都是四平八稳,做为一个基础组件,也不期待啥了。
如果说想线下调度,集成测试,想用一个内存数据库,你可能会说那H2, Derby吧,不都可以嘛。
但差别是你在自己线下时跑了多少不说,但不同的数据库,不同的特性,可能有些地方无法真正还原线上。为什么不安装一个?费事,哈哈。
今天咱们介绍的这位,可以理解为嵌入MySQL,免安装。不同的测试时还可以切换不同的版本,Cool。
使用起来也不费劲,加个 Maven 依赖就行,分分钟的事儿。
就是它:
<dependency> <groupId>com.wixgroupId> <artifactId>wix-embedded-mysqlartifactId> <version>x.y.zversion> <scope>testscope>dependency>
代码也简单,直接定义你需要的版本,数据库信息,把要初始化的SQL 给它,走起。
MysqldConfig config = aMysqldConfig(v5_6_23) //这里是版本 .withCharset(UTF8) .withPort(2215) .withUser("user1", "pwd2") .withTimeZone("Europe/Vilnius") .withTimeout(2, TimeUnit.MINUTES) .withServerVariable("max_connect_errors", 666) .build();EmbeddedMysql mysqld = anEmbeddedMysql(config) .addSchema("aschema", ScriptResolver.classPathScript("db/001_init.sql")) .start();//do workmysqld.stop(); //optional, as there is a shutdown hook
这有啥优势:
测试可以跑在和生产环境基本一致的环境,同样的版本,同样的编码和配置,database/schema/user settings 等等
比安装一个更容易,想切换版本,改配置也更轻松;
本地每个项目可以使用不同的版本,不同的配置,啥都不用担心;
对于MySQL的多个版本支持 - 5.5, 5.6, 5.7, 8.0;
多种平台和环境都支持。
原理
这背后是怎么实现的呢?
咱们是「刨根究底」公众号,一起来看看。
上面代码配置之后的 start ,到底 start 了啥?
咱们看下面这几小段代码:
protected EmbeddedMysql( final MysqldConfig mysqldConfig, final DownloadConfig downloadConfig) { this.config = mysqldConfig; IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder().defaults(mysqldConfig, downloadConfig).build(); MysqldStarter mysqldStarter = new MysqldStarter(runtimeConfig); localRepository.lock(); try { this.executable = mysqldStarter.prepare(mysqldConfig); } finally { localRepository.unlock(); } try { executable.start(); getClient(SCHEMA, mysqldConfig.getCharset()).executeCommands( format("CREATE USER '%s'@'%%' IDENTIFIED BY '%s';", mysqldConfig.getUsername(), mysqldConfig.getPassword())); } catch (IOException e) { throw new RuntimeException(e); } }
protected MysqldProcess start( final Distribution distribution, final MysqldConfig config, final IRuntimeConfig runtime) throws IOException { logger.info("Preparing mysqld for startup"); Setup.apply(config, executable, runtime); logger.info("Starting MysqldProcess"); return new MysqldProcess(distribution, config, runtime, this); }
其实这背后依赖了一个叫embed.process的开源项目,
public AbstractProcess(Distribution distribution, T config, IRuntimeConfig runtimeConfig, E executable) throws IOException { this.config = config; this.runtimeConfig = runtimeConfig; this.executable = executable; this.distribution = distribution; // pid file needs to be set before ProcessBuilder is called this.pidFile = pidFile(this.executable.getFile().executable()); ProcessOutput outputConfig = runtimeConfig.getProcessOutput(); // Refactor me - to much things done in this try/catch String nextCall=""; try { nextCall="onBeforeProcess()"; onBeforeProcess(runtimeConfig); nextCall="newProcessBuilder()"; ProcessBuilder processBuilder = ProcessControl.newProcessBuilder( runtimeConfig.getCommandLinePostProcessor().process(distribution, getCommandLine(distribution, config, this.executable.getFile())), getEnvironment(distribution, config, this.executable.getFile()), true); nextCall="onBeforeProcessStart()"; onBeforeProcessStart(processBuilder, config, runtimeConfig); nextCall="start()"; process = ProcessControl.start(config.supportConfig(), processBuilder); nextCall="writePidFile()"; if (process.getPid() != null) { writePidFile(pidFile, process.getPid()); } nextCall="addShutdownHook()"; if (runtimeConfig.isDaemonProcess() && !executable.isRegisteredJobKiller()) { ProcessControl.addShutdownHook(new JobKiller()); registeredJobKiller = true; } nextCall="onAfterProcessStart()"; onAfterProcessStart(process, runtimeConfig); } catch (IOException iox) { stop(); throw iox; } }
它又操作了什么呢?从名字你也猜到了,它是直接操作进程的,实际在运行时,会下载一个MySQL,然后通过脚本启停。
初次启动的时候,会直接下载
有了这些,在测试的时候就可以和生产环境一样,启动时加载初始化SQL脚本,开始你的工作了。
github地址:https://github.com/wix/wix-embedded-mysql
相关阅读
MySQL: 喂,别走,听我解释一下好吗?
多表查询用什么联接?别信感觉,用数据说话
一个数据库SQL查询的数次轮回
数据库是咋工作的?(一)
凭什么让日志先写?
Java七武器系列长生剑 -- Java虚拟机的显微镜 Serviceability Agent
Java七武器系列霸王枪 -- 线程状态分析 jstack
Java七武器系列孔雀翎-- 问题诊断神器BTrace
嵌套事务、挂起事务,Spring 是怎样给事务又实现传播特性的?
怎样阅读源代码?
如果有所帮助,给个在看或转发吧,多谢!
![70c4dd776106a62b07fde86f53c38eeb.png](https://i-blog.csdnimg.cn/blog_migrate/7c972f26bb33914ece2e02ca6e508da7.jpeg)
源码|实战|成长|职场
这里是「Tomcat那些事儿」
请留下你的足迹
我们一起「终身成长」
![d5a60462eb12fb46be4a0ea0095fca47.png](https://i-blog.csdnimg.cn/blog_migrate/36fa9f9d40684ba2fba2d25c16e47756.jpeg)