<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      這么優(yōu)雅的Java ORM沒(méi)見(jiàn)過(guò)吧!

      ??Java的ORM框架有很多,但由于Java語(yǔ)言的限制大部分都不夠優(yōu)雅也不夠簡(jiǎn)單,所以作者只能另辟蹊徑造輪子了。照舊先看示例代碼了解個(gè)大概,然后再解釋實(shí)現(xiàn)原理。

      一、ORM示例

      1. Insert

      public CompletableFuture<Void> insert() {
          var obj = new sys.entities.Demo("MyName"); //構(gòu)造參數(shù)為主鍵
          obj.Age = 100; //設(shè)置實(shí)體屬性的值
          return obj.saveAsync();
      }
      

      2. Update

      • 更新單個(gè)實(shí)體(必須具備主鍵)
      public CompletableFuture<Void> update(sys.entities.Demo obj) {
          obj.Age = 200;
          return obj.saveAsync();
      }
      
      • 根據(jù)條件更新(必須指定條件以防誤操作)
      public CompletableFuture<?> update() {
          var cmd = new SqlUpdateCommand<sys.entities.Demo>();
          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);  //更新的同時(shí)返回指定字段
          return cmd.execAsync().thenApply(rows -> {
              System.out.println("更新記錄數(shù): " + rows);
              System.out.println("返回的值: " + outs.get(0));
              return "Done.";
          });
      }
      

      3. Delete

      • 刪除單個(gè)實(shí)體(必須具備主鍵)
      public CompletableFuture<Void> update(sys.entities.Demo obj) {
          obj.markDeleted(); //先標(biāo)記為刪除狀態(tài)
          return obj.saveAsync(); //再調(diào)用保存方法
      }
      
      • 根據(jù)條件刪除(必須指定條件以防誤操作)
      public CompletableFuture<?> delete() {
          var cmd = new SqlDeleteCommand<sys.entities.Demo>();
          cmd.where(e -> e.Age < 0 || e.Age > 200);
          return cmd.execAsync();
      }
      

      4. Transaction

      ??由于作者討厭隱式事務(wù),所以事務(wù)命令必須顯式指定。

      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 -> { //開(kāi)始事務(wù)
              return obj1.saveAsync(txn)                 //事務(wù)保存obj1
                  .thenCompose(r -> obj2.saveAsync(txn)) //事務(wù)保存obj2
                  .thenCompose(r -> txn.commitAsync());  //遞交事務(wù)
          }).thenApply(r -> "Done");
      }
      

      5. Sql查詢

      • Where條件
      public CompletableFuture<?> query(String key) {
          var q = new SqlQuery<sys.entities.Demo>();
          q.where(e -> e.Age > 10 && e.Age < 80);
          if (key != null)
              q.andWhere(e -> e.Name.contains(key)); //拼接條件
          return q.toListAsync(); //返回List<sys.entities.Demo>
      }
      
      • 分頁(yè)查詢
      public CompletableFuture<?> query(int pageSize, int pageIndex) {
          var q = new SqlQuery<sys.entities.Demo>();
          return q.skip(pageSize * pageIndex)
              .take(pageSize)
              .toListAsync();
      }
      
      • 結(jié)果映射至匿名類
      public CompletableFuture<?> query() {
          var q = new SqlQuery<sys.entities.Demo>();
          return q.toListAsync(e -> new Object() { //返回List<匿名類>
              public final String Name = e.Name; //匿名類屬性 = 實(shí)體屬性表達(dá)式
              public final int    Age = e.Age + 10;
              public final String Father = e.Parent.Name;
          }).thenApply(appbox.data.JsonResult::new);
      }
      
      • 結(jié)果映射至繼承的匿名類
      public CompletableFuture<?> query() {
          var q = new SqlQuery<sys.entities.Demo>();
          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;
          });
      }
      
      • 結(jié)果映射至樹(shù)狀結(jié)構(gòu)列表
      public CompletableFuture<?> tree() {
          var q = new SqlQuery<sys.entities.Demo>();
          q.where(t -> t.Name == "Rick");
          return q.toTreeAsync(t -> t.Childs); //參數(shù)指向EntitySet(一對(duì)多成員)
      }
      
      • EntityRef(一對(duì)一引用的實(shí)體成員)自動(dòng)Join
      public CompletableFuture<?> query() {
          var q = new SqlQuery<sys.entities.Customer>();
          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<sys.entities.Customer>();
          var j = new SqlQueryJoin<sys.entities.City>();
      
          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<sys.entities.Demo>();
          sq.where(s -> s.ParentName == "Rick");
          
          var q = new SqlQuery<sys.entities.Demo>();
          q.where(t -> DbFunc.in(t.Name, sq.toSubQuery(s -> s.Name)));
          return q.toListAsync();
      }
      
      • GroupBy
      public CompletableFuture<?> groupBy() {
          var q = new SqlQuery<sys.entities.Demo>();
          q.groupBy(t -> t.ParentName) //多個(gè)可重復(fù)
              .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);
      }
      

      二、實(shí)現(xiàn)原理

      ??其實(shí)以上的示例代碼并非最終運(yùn)行的代碼,作者利用Eclipse jdt將上述代碼在編譯發(fā)布服務(wù)模型時(shí)分析轉(zhuǎn)換為最終的運(yùn)行代碼,具體過(guò)程如下:

      1. jdt分析服務(wù)虛擬代碼生成AST抽象語(yǔ)法樹(shù);

      2. 遍歷AST樹(shù),將實(shí)體對(duì)象的讀寫屬性改寫為getXXX(), setXXX();

      var name = obj.Name; //讀實(shí)體屬性
      obj.Name = "Rick";   //寫實(shí)體屬性
      

      改寫為:

      var name = obj.getName();
      obj.setName("Rick");
      

      3. 遍歷AST樹(shù),將查詢相關(guān)方法的參數(shù)轉(zhuǎn)換為運(yùn)行時(shí)表達(dá)式;

      public CompletableFuture<?> query(String key) {
          var q = new SqlQuery<sys.entities.Employee>();
          q.where(e -> e.Manager.Name + "a" == key + "b");
          return q.toListAsync();
      }
      

      轉(zhuǎn)換為:

      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. 根據(jù)服務(wù)模型使用到的實(shí)體模型生成相應(yīng)實(shí)體的運(yùn)行時(shí)代碼;

      5. 最后編譯打包服務(wù)模型的字節(jié)碼。

      以上請(qǐng)參考源碼的ServiceCodeGenerator及EntityCodeGenerator類。

      三、性能與小結(jié)

      ??作者寫了個(gè)簡(jiǎn)單查詢的服務(wù),測(cè)試配置為MacBook主機(jī)(wrk壓測(cè) + 數(shù)據(jù)庫(kù))->4核I7虛擬機(jī)(服務(wù)端),測(cè)試結(jié)果如下所示qps可達(dá)1萬(wàn),已包括實(shí)體映射轉(zhuǎn)換及序列化傳輸?shù)人虚_(kāi)銷。這里順便提一下,由于框架是全異步的,所以沒(méi)有使用傳統(tǒng)的JDBC驅(qū)動(dòng),而是使用了jasync-sql(底層為Netty)來(lái)驅(qū)動(dòng)數(shù)據(jù)庫(kù)。

      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
      

      邊碼代碼邊碼文實(shí)屬不易,作者需要您的支持請(qǐng)您多多點(diǎn)贊推薦!另歡迎感興趣的小伙伴加入我們!

      posted @ 2021-01-13 16:30  白菜園  閱讀(3820)  評(píng)論(35)    收藏  舉報(bào)
      主站蜘蛛池模板: 日韩精品一区二区在线看| 办公室强奷漂亮少妇视频| 石原莉奈日韩一区二区三区| 无码中文字幕av免费放| 精品久久精品久久精品九九| 日本一区二区三区免费播放视频站| 亚洲AVAV天堂AV在线网阿V| 日韩中文字幕亚洲精品一| 波多野结衣久久一区二区| 97av| 中文字幕精品亚洲无线码二区| 精品无人乱码一区二区三区的优势 | 成人精品区| 午夜成人精品福利网站在线观看| 色综合久久精品亚洲国产| 国产成人一区二区三区视频免费| 成人午夜免费无码视频在线观看| 国产熟女av一区二区三区| 久久96热在精品国产高清| 熟女一区二区中文在线| 亚洲啪啪精品一区二区的| 中文字幕精品无码一区二区| 国产精品无码免费播放| 北岛玲亚洲一区二区三区| 免费视频国产在线观看| 精品视频国产狼友视频| 亚洲中文精品一区二区| 滨海县| 日韩精品一区二区三区激情视频 | 无码国产玉足脚交极品播放| 十八禁午夜福利免费网站| 梁河县| 人人爽亚洲aⅴ人人爽av人人片| 99欧美日本一区二区留学生| 亚洲人成网站18禁止无码| 国产精品中文字幕第一区| 日本边添边摸边做边爱喷水| 国产精品一区二区 尿失禁| 无码一区二区三区av在线播放| 精品无码一区二区三区电影| 中文字幕国产精品二区|