这么优雅的Java ORM没见过吧! (2)

  其实以上的示例代码并非最终运行的代码,作者利用Eclipse jdt将上述代码在编译发布服务模型时分析转换为最终的运行代码,具体过程如下:

1. jdt分析服务虚拟代码生成AST抽象语法树; 2. 遍历AST树,将实体对象的读写属性改写为getXXX(), setXXX(); var name = obj.Name; //读实体属性 obj.Name = "Rick"; //写实体属性

改写为:

var name = obj.getName(); obj.setName("Rick"); 3. 遍历AST树,将查询相关方法的参数转换为运行时表达式; public CompletableFuture<?> query(String key) { var q = new SqlQuery<sys.entities.Employee>(); q.where(e -> e.Manager.Name + "a" == key + "b"); return q.toListAsync(); }

转换为:

public CompletableFuture<?> query(String key) { var q = new appbox.store.query.SqlQuery<>(-7018111290459553788L, SYS_Employee.class); q.where(e -> e.m("Name").plus(obj.getName()).plus("c").eq("Rick")); return q.toListAsync(); } 4. 根据服务模型使用到的实体模型生成相应实体的运行时代码; 5. 最后编译打包服务模型的字节码。

以上请参考源码的ServiceCodeGenerator及EntityCodeGenerator类。

三、性能与小结

  作者写了个简单查询的服务,测试配置为MacBook主机(wrk压测 + 数据库)->4核I7虚拟机(服务端),测试结果如下所示qps可达1万,已包括实体映射转换及序列化传输等所有开销。这里顺便提一下,由于框架是全异步的,所以没有使用传统的JDBC驱动,而是使用了jasync-sql(底层为Netty)来驱动数据库。

wrk -c200 -t2 -d20s -s post_bin.lua :8000/api Running 20s test @ :8000/api 2 threads and 200 connections Thread Stats Avg Stdev Max +/- Stdev Latency 18.97ms 5.84ms 89.15ms 81.55% Req/Sec 5.32k 581.92 6.48k 65.00% 211812 requests in 20.02s, 36.76MB read Requests/sec: 10578.90 Transfer/sec: 1.84MB

边码代码边码文实属不易,作者需要您的支持请您多多点赞推荐!另欢迎感兴趣的小伙伴加入我们!

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wppwjd.html