各个业务系统,都需要查询各类数据库;
一般查询数据库都是客户端自己连接,根据现在的情况,存在以下几点问题
1.客户端连接很多,连接大小,峰值不可控
2.客户端SQL程序员自己写,参差不齐
3.SQL书写方式不同。
将数据库查询抽成服务端可以解决的问题
1.只有数据传递的网络通信
2.数据库查询由服务端性能决定
3.可以隔离数据库操作,由服务端设置查询峰值
4.统一检查数据库查询的相关问题,便于调试
5.在必要的情况下,剥离SQL语句在服务端,由专门的程序员写SQL,优化SQL,客户端只传入请求的条件。
DBCacehServer服务提供的功能
1.数据库查询,java实现跨越任意部署,支持多SQL数据库;
2.不支持的数据库可以自己扩展,将数据库客户端驱动JDBC包放入drivers目录,服务端启动会动态加载。
3.服务端不大。
4.客户端请求简单,支持服务端配置SQL,以及客户端自己写SQL语句传输。
5.支持单SQL语句或者参数化SQL语句
6.服务端连接池,使用了网络吹嘘的HikariCP数据库连接池,使用配置简单
7.序列化。软件主要支持json格式序列化及二进制序列化
8.动态创建model,按照服务端配置或客户端提供的ID,客户端如果需要返回结果是datafomat,则是返回bean(model),那么
服务端会动态创建类,从无到有。
9.超时执行。分3类:1.客户端提供超时时间;2.服务端默认超时时间;3.一直等待。这样即使数据库有问题,也不会影响数据库使用,客户端返回。至于采用哪一种,也是客户端设置决定。客户端设置超时时间为0,则采用服务端默认设置,超时-1则一直等待,大于0则是客户端设置的超时。
DBCacehServer服务扩展功能,需要满足以下条件及配置
1.中英文转换表
让服务端初始化查询对应关系
2.需要用户资料表,有userid,username
3.可以提供多值字典项,例如你的业务中有多个单位信息,你要建立的关系是dw(ename)-003(zid)-xx中学(zname)这样的关系,ename是与中英文转换关联,zid单位编码(有多个单位),对应的单位名称(zname);
你需要提供这样的一个SQL查询,明确字段,让服务端初始化查询。
4.提供一张数据权限表:明确用户,数据库表名,数据库表的操作:
服务端将数据库表操作分成几类:数据增删改查,创建表,删除表,truncate;类似如图:
userid | tablename | insert | delete | update | select | create | drop | truncate |
1 | Test | TRUE | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE |
配置SQL语句及字段,服务端初始化加载,则形成数据表的操作权限,建立起数据权限
有了以上几点的提供,服务端就建立了完整的一套功能。
(1)中英文转换,标题转换,值转换,两者都转换,都不转换4类,由客户端设置,有对应设置字段,枚举型
(2)查询时转换字典值,类似上面举例单位
(3)用户权限,解决数据控制问题。服务端会分析SQL,判断SQL里面对表的各种操作,查看有没有权限
另外其实还有个隐藏功能,但是我没有提供,它需要数据库表的良好设计及编码格式的解决,但是无法做到统一提供。
当解决了编码问题(客户端编码,服务端编码,数据库编码)。则在客户端查询时,可以写成 用户名称='jason' ,然后在服务端接收到后,转变成username='jason',所以要解决编码问题。这样能够很方便的解决UI查询问题,不用转换。而且可以做到模板化及自动化,UI映射就会很方便,但是由于有编码问题,所以服务端现在无法统一提供该功能。
(4)查询数据缓存。服务端提供了SQL查询的缓存,对于非参数化的查询,服务端对数据缓存,能够提供给多客户端查询提供方便。对于有专门查询的UI是非常好的。但是有个小问题,对于不同业务系统,你要考虑缓存时间及数据的查询及时性,还有就是你服务端内存大小,对于缓存,后面我还会多多说两句。
这样,服务端提供了强大的4大功能,能够为客户端查询简化很多问题。同时利用服务器的性能,充分解决查询问题。服务器就应该有服务器的用法。
其它说明:
1.该软件及版本,我并没有提供集群及负载均衡,这个功能一般是我写服务端的基本功能,但是这里我没有提供,你可以用一些框架实现。也许今后会升级版本添加,但是我感觉该软件没有必要。
一个简单部署方法,你做一个DNS服务器,将其做成域名,然后多台机器部署,让DNS去解析即可。
2.缓存。本软件只实现了具体SQL缓存数据,该缓存有时间设置及缓存大小问题。所以需要自己根据业务设置。另外,参数化参数没有缓存,这个可以设置一个映射关系,将其转换成一个固话key来缓存,我还没有设计,可以自行设计,用于缓存。缓存已经被封装为一个单例,很方便修改。可以修改代码,在缓存查询那里扩展查询,利用redis等缓存扩展,如果你需要充分的缓存数据。
3.数据权限检查。我实现了该功能,但是因为我需求小,所以没有足够SQL测试,更加没有测试所有的数据库。所以算是提供了模板,如果没有写全,你只需要测试添加就行,完善一下统计功能,也很简单。不过你要理解开源组件jsqlparser,也很简单,我就在网上遇到问题搜,几小时解决。
4.功能权限。这里我没有提供,其实也可以放在这里,很简单,客户端需要提供一个ID,设计时以功能路径的方式,来检查该用户有没有该模块即可,然后返回一个结果。或者初始化时,客户端调用一个检查SQL.让服务端加载。比如前一种:学生查询/学生分数查询/学生数学分数查询。这样就有权限了。但是我不需要,所以没有提供该功能。
5.动态创建类model.该功能需要配置好JDK.由于创建方式选择在内存,所以你看不见java文件以及class文件,jdk直接在内存中创建了一个类。当前如果你要以bean(model)返回,客户端必须有类似的类。后期版本升级客户端,会监测客户端有没有model,如果没有就在返回结果时,把服务端的类信息一起返回客户端,然后在客户端动态加载该类,这样就减少了客户端创建该类,你只要定义一个名称就可以了。建议使用时你采用HashMap来使用。当然,这就需要你配置好JDK,让客户端能够动态加载类。
6.软件提供了几类设置
1.客户端设置结果的序列化方式:json格式还是二进制方式。
如果是二进制方式,隐藏了查询数据时返回model(bean),服务端会动态创建类。然后序列化返回
2.查询数据转换。查询的数据按照数据表及数据内容,可以进行中英文及字典转换。一个枚举类型,包括:标题转换,值内容转换,都转换以及都不转换。
如果是二进制转换,则不会再MODEL中转换,但是会返回对应的中英文转换关系hashmap,以及字典值hashmap<string,hashmap<string,string> .但是数据中有的,被筛选了,不是全集。返回客户端后需要自己转换去取。因为创建类
我不习惯用中文做字段名称,还有编码问题。
需要的组件包:
jsqlparser,fastjson,msgpack,dom4j,guava,HikariCP,netty,slf4j,log4j,log4j-slf4j-impl以及各种数据库数据库客户端JDBC驱动包。
可见,都是公共开源的包,性能也是认可的。总共部署大约10多M.我会持续研究升级。同时保障所有包是开源的。
最后的话 :
软件虽然小,但是解决了很多问题,简化了很多开发。功能基本满足。
如果感兴趣的,可以下载使用,完善我没有提供的功能及权限验证功能。能够解决编码问题就解决了很多问题。
如果有兴趣完善,也希望能够提交到git.供大家一起使用,并且完善数据库查询方案。
当前是java版本的。如果客户端是c#,c++.你要实现客户端,很简单,就是1个类及2个枚举。然后自己弄个TCP通信,序列化传输即可。使用自己的序列化组件,jason格式的以及对应版本的msgpack。当然动态加载类就不可以了,你需要自己在客户端建好model的类。简不简单。
已经持续升级,升级内容见git项目说明。扩展redis支持
源码:
https://github.com/jinyuttt/DBCacheServer.git