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

网友投稿 254 2022-11-06


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

一、ORM示例

1. Insert

public CompletableFuture insert() {

var obj = new sys.entities.Demo("MyName"); //构造参数为主键

obj.Age = 100; //设置实体属性的值

return obj.saveAsync();

}

2. Update

更新单个实体(必须具备主键)

public CompletableFuture update(sys.entities.Demo obj) {

obj.Age = 200;

return obj.saveAsync();

}

根据条件更新(必须指定条件以防误操作)

public CompletableFuture> update() {

var cmd = new SqlUpdateCommand();

cmd.update(e -> e.City = "Wuxi"); //更新字段

cmd.update(e -> e.Age = e.Age + 1); //更新累加字段

cmd.where(e -> e.Name == "Johne"); //更新的条件

var outs = cmd.output(e -> e.Age); //更新的同时返回指定字段

return cmd.execAsync().thenApply(rows -> {

System.out.println("更新记录数: " + rows);

System.out.println("返回的值: " + outs.get(0));

return "Done.";

});

}

3. Delete

删除单个实体(必须具备主键)

public CompletableFuture update(sys.entities.Demo obj) {

obj.markDeleted(); //先标记为删除状态

return obj.saveAsync(); //再调用保存方法

}

根据条件删除(必须指定条件以防误操作)

public CompletableFuture> delete() {

var cmd = new SqlDeleteCommand();

cmd.where(e -> e.Age < 0 || e.Age > 200);

return cmd.execAsync();

}

4. Transaction

public CompletableFuture> transaction() {

var obj1 = new sys.entities.Demo("Demo1");

obj1.Age = 11;

var obj2 = new sys.entities.Demo("Demo2");

obj2.Age = 22;

return DataStore.DemoDB.beginTransaction().thenCompose(txn -> { //开始事务

return obj1.saveAsync(txn) //事务保存obj1

.thenCompose(r -> obj2.saveAsync(txn)) //事务保存obj2

.thenCompose(r -> txn.commitAsync()); //递交事务

}).thenApply(r -> "Done");

}

5. Sql查询

Where条件

public CompletableFuture> query(String key) {

var q = new SqlQuery();

q.where(e -> e.Age > 10 && e.Age < 80);

if (key != null)

q.andWhere(e -> e.Name.contains(key)); //拼接条件

return q.toListAsync(); //返回List

}

分页查询

public CompletableFuture> query(int pageSize, int pageIndex) {

var q = new SqlQuery();

return q.skip(pageSize * pageIndex)

.take(pageSize)

.toListAsync();

}

结果映射至匿名类

public CompletableFuture> query() {

var q = new SqlQuery();

return q.toListAsyhttp://nc(e -> new Object() { //返回List<匿名类>

public final String Name = e.Name; //匿名类属性 = 实体属性表达式

public final int Age = e.Age + 10;

public final String Father = e.Parent.Name;

}).thenApply(appbox.data.jsonResult::new);

}

结果映射至继承的匿名类

public CompletableFuture> query() {awrPSKbJM

var q = new SqlQuery();

q.where(e -> e.Parent.Name == "Rick");

return q.toListAsync(e -> new sys.entities.Demo() { //返回List extens Demo>

public final String Father = e.Parent.Name;

});

}

结果映射至树状结构列表

public CompletableFuture> tree() {

var q = new SqlQuery();

q.where(t -> t.Name == "Rick");

return q.toTreeAsync(t -> t.Childs); //参数指向EntitySet(一对多成员)

}

EntityRef(一对一引用的实体成员)自动Join

public CompletableFuture> query() {

var q = new SqlQuery();

q.where(cus -> cus.City.Name == "Wuxi");

return q.toListAsync();

}

生成的Sql:

Select t.* From "Customer" t Left Join "City" j1 On j1."Code"=t."CityCode"

手工指定Join

public CompletableFuture> join() {

var q = new SqlQuery();

var j = new SqlQueryJoin();

q.leftJoin(j, (cus, city) -> cus.CityCode == city.Code);

q.where(j, (cus, city) -> city.Name == "Wuxi");

return q.toListAsync();

}

子查询

public CompletableFuture> subQuery() {

var sq = new SqlQuery();

sq.where(s -> s.ParentName == "Rick");

var q = new SqlQuery();

q.where(t -> DbFunc.in(t.Name, sq.toSubQuery(s -> s.Name)));

return q.toListAsync();

}

GroupBy

public CompletableFuture> groupBy() {

var q = new SqlQuery();

q.groupBy(t -> t.ParentName) //多个可重复

.having(t -> DbFunc.sum(t.Age) > 10);

return q.toListAsync(t -> new Object() {

public final String group = t.ParentName == null ? "可怜的孩子" : t.ParentName;

public final int totals = DbFunc.sum(t.Age);

}).thenApply(appbox.data.JsonResult::new);

}

二、实现原理

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();

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("Manager").m("Name").plus("a").eq(key + "b"));

return q.toListAsync();

}

4. 根据服务模型使用到的实体模型生成相应实体的运行时代码;

5. 最后编译打包服务模型的字节码。

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

三、性能与小结

wrk -c200 -t2 -d20s -s post_bin.lua http://10.211.55.8:8000/api

Running 20s test @ http://10.211.55.8: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

以上就是这么优雅的Java ORM没见过吧!的详细内容,更多关于java orm的资料请关注我们其它相关文章!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:有两个样本点,第一个点为正样本,它的特征向量是(0,-1);
下一篇:SVM核函数
相关文章

 发表评论

暂时没有评论,来抢沙发吧~