Skip to content

paxoscn/mysql-protocol

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LICENSE Language

README in English: README_EN.md

MySQL协议Java实现

改造自https://github.com/mheath/netty-mysql-codec

这个项目适用于:

  • 实现自有数据库时并允许任何MySQL兼容客户端进行连接.
  • 代理任何数据源并将其封装为MySQL服务.
  • 学习MySQL协议.

快速开始

运行单元测试

为了确保代码下载完整, 你可以运行MySqlListenerTest.java 来确认单元测试是否可以正确运行.

这个单元测试会启动一个MySQL服务,对它的任何查询都只会返回'Hello World !'. 随后它会启动一个JDBC访问并发送一句SQL到服务器, 检查查询结果并关闭服务.

创建自己的MySQL服务

首先你需要实现SqlEngine

public class YourSqlEngine implements SqlEngine { }

要对客户端发过来的SQL进行响应,你需要实现query().

@Override public void query(ResultSetWriter resultSetWriter, String database, String userName, byte[] scramble411, byte[] authSeed, String sql) throws IOException { // 在结果集中放入一列,名为'col1' // 该调用必须在任意一次writeRow()之前 resultSetWriter.writeColumns(List.of(new QueryResultColumn("col1", "varchar(255)"))); // 在结果集中放入一行,值为'Hello World !' resultSetWriter.writeRow(List.of("Hello World !")); // 最后需要调用finish()方法结束响应 resultSetWriter.finish(); }

为了保护你的服务不被未授权人员访问, 你还需要实现authenticate().

@Override public void authenticate(String database, String userName, byte[] scramble411, byte[] authSeed) throws IOException { // 只允许用户名'github' String validUser = "github"; if (!userName.equals(validUser)) { throw new IOException(new IllegalAccessException("Authentication failed: User " + userName + " is not allowed to connect")); } // 只允许密码'123456' String validPassword = "123456"; // 对密码进行SHA1及编码 String validPasswordSha1 = SHAUtils.SHA(validPassword, SHAUtils.SHA_1); String validScramble411WithSeed20 = Utils.scramble411(validPasswordSha1, authSeed); // 比较密码编码结果 if (!Utils.compareDigest(validScramble411WithSeed20, Base64.getEncoder().encodeToString(scramble411))) { throw new IOException(new IllegalAccessException("Authentication failed: Validation failed")); } }

实现完毕后, 你可以把实现类传入MySqlListener,当它实例化后会自动监听指定TCP端口.

// 启动并监听端口3307 new MySqlListener(3307, 100, new YourSqlEngine()); // 为了有足够时间来进行客户端连接,可以在这里sleep一段时间. Thread.sleep(1000L * 60 * 10);

启动服务后, 你可以用任何MySQL客户端来进行连接,以下以MySQL命令行客户端为例.

mysql -h127.0.0.1 -P3307 -ugithub -p123456 dummy_db > select * from dummy_table; +---------------+ | col1 | +---------------+ | Hello World ! | +---------------+ 1 row in set (0.006 sec)

开源协议

本项目使用Apache 2.0协议. 详情请见: LICENSE.

告知

  • 感谢 mheath 提供的基础代码.
  • 最小Java版本: JDK11. (JDK8在测试中)
  • 联系方式 - 微信: 95634620 邮件: unrealwalker@126.com

About

A MySQL Protocol Implementation in Java

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages