加入收藏 | 设为首页 | 会员中心 | 我要投稿 航空爱好网 (https://www.dakongjun.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

Mssq类型转换函数 这么优雅的Java ORM没见过吧!

发布时间:2022-12-02 16:05:00 所属栏目:MsSql教程 来源:
导读:  这篇文章主要介绍了Java ORM的相关资料Mssq类型转换函数,帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下

  Java的ORM框架有很多,但由于Java语言的限制大部分都不够优雅也不够简单,所以作者只能
  这篇文章主要介绍了Java ORM的相关资料Mssq类型转换函数,帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下
 
  Java的ORM框架有很多,但由于Java语言的限制大部分都不够优雅也不够简单,所以作者只能另辟蹊径造轮子了。照旧先看示例代码了解个大概,然后再解释实现原理。
 
  一、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.toListAsync(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() {
    var q = new SqlQuery();
    q.where(e -> e.Parent.Name == "Rick");
    return q.toListAsync(e -> new sys.entities.Demo() { //返回List
      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();
  函数类型函数图像_Mssq类型转换函数_三角与e函数转换
 
 
  }
  子查询
 
  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);
  }
  二、实现原理
 
  其实以上的示例代码并非最终运行的代码,作者利用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();
    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类。
 
  三、性能与小结
 
  作者写了个简单查询的服务,测试配置为MacBook主机(wrk压测 + 数据库)->4核I7虚拟机(服务端),测试结果如下所示qps可达1万,已包括实体映射转换及序列化传输等所有开销。这里顺便提一下,由于框架是全异步的,所以没有使用传统的JDBC驱动,而是使用了jasync-sql(底层为Netty)来驱动数据库。
 
  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
 
 

(编辑:航空爱好网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!