最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

這么優(yōu)雅的Java ORM沒見過吧!

 更新時間:2021年01月14日 11:57:12   作者:白菜園  
這篇文章主要介紹了Java ORM的相關(guān)資料,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下

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

一、ORM示例

1. Insert

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

2. Update

更新單個實體(必須具備主鍵)

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); //更新的同時返回指定字段
  return cmd.execAsync().thenApply(rows -> {
    System.out.println("更新記錄數(shù): " + rows);
    System.out.println("返回的值: " + outs.get(0));
    return "Done.";
  });
}

3. Delete

刪除單個實體(必須具備主鍵)

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 -> { //開始事務(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>
}

分頁查詢

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; //匿名類屬性 = 實體屬性表達式
    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é)果映射至樹狀結(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(一對多成員)
}

EntityRef(一對一引用的實體成員)自動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) //多個可重復(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);
}

二、實現(xiàn)原理

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

1. jdt分析服務(wù)虛擬代碼生成AST抽象語法樹;
2. 遍歷AST樹,將實體對象的讀寫屬性改寫為getXXX(), setXXX();

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

改寫為:

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

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

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ù)模型使用到的實體模型生成相應(yīng)實體的運行時代碼;
5. 最后編譯打包服務(wù)模型的字節(jié)碼。

以上請參考源碼的ServiceCodeGenerator及EntityCodeGenerator類。

三、性能與小結(jié)

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

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

以上就是這么優(yōu)雅的Java ORM沒見過吧!的詳細內(nèi)容,更多關(guān)于java orm的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringBoot整合Redis實現(xiàn)常用功能超詳細過程

    SpringBoot整合Redis實現(xiàn)常用功能超詳細過程

    這篇文章主要介紹了SpringBoot整合Redis實現(xiàn)常用功能,登陸功能是每個項目必備的功能吧,但是想設(shè)計好,卻是很難,下面介紹兩種登陸功能的解決方式,需要的朋友可以參考下
    2022-08-08
  • @valid 無法觸發(fā)BindingResult的解決

    @valid 無法觸發(fā)BindingResult的解決

    這篇文章主要介紹了@valid 無法觸發(fā)BindingResult的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 在Eclipse中部署Spring Boot/Spring Cloud應(yīng)用到阿里云

    在Eclipse中部署Spring Boot/Spring Cloud應(yīng)用到阿里云

    這篇文章主要介紹了在Eclipse中部署Spring Boot/Spring Cloud應(yīng)用到阿里云,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • springboot+vue?若依項目在windows2008R2企業(yè)版部署流程分析

    springboot+vue?若依項目在windows2008R2企業(yè)版部署流程分析

    這篇文章主要介紹了springboot+vue?若依項目在windows2008R2企業(yè)版部署流程,本次使用jar包啟動后端,故而準(zhǔn)備打包后的jar文件,需要的朋友可以參考下
    2022-12-12
  • Java 隨機生成驗證碼(支持大小寫字母、數(shù)字、隨機字體)的實例

    Java 隨機生成驗證碼(支持大小寫字母、數(shù)字、隨機字體)的實例

    java隨機產(chǎn)生驗證碼,可以隨機生成數(shù)字、大寫字母、小寫字母。還可以隨機生成文字字體、及大小。在圖片上面可能字體都不不同、大小不等
    2013-05-05
  • Java檢查字符串是否一致的四種方法

    Java檢查字符串是否一致的四種方法

    字符串比較是常見的操作,包括比較相等、比較大小、比較前綴和后綴串等,在 Java 中,比較字符串的常用方法有四個:equals(),equalsIgnoreCase(),compareTo()和compareToIgnoreCase(),下面詳細介紹這四個方法的使用
    2024-04-04
  • Kafka在客戶端實現(xiàn)消息的發(fā)送與讀取

    Kafka在客戶端實現(xiàn)消息的發(fā)送與讀取

    這篇文章主要介紹了Kafka在客戶端實現(xiàn)消息的發(fā)送與讀取,KafkaProducer是用于發(fā)送消息的類,ProducerRecord類用于封裝Kafka的消息,KafkaProducer的實例化需要指定的參數(shù),Producer的參數(shù)定義在 org.apache.kafka.clients.producer.ProducerConfig類中,需要的朋友可以參考下
    2023-12-12
  • JavaWeb實現(xiàn)簡單用戶發(fā)送郵件

    JavaWeb實現(xiàn)簡單用戶發(fā)送郵件

    這篇文章主要為大家詳細介紹了JavaWeb實現(xiàn)簡單用戶發(fā)送郵件,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 如何使用Guava Cache做緩存

    如何使用Guava Cache做緩存

    Cache在ConcurrentHashMap的基礎(chǔ)上提供了自動加載數(shù)據(jù)、清除數(shù)據(jù)、get-if-absend-compute的功能,本文給大家介紹如何使用Guava Cache做緩存,感興趣的朋友一起看看吧
    2023-11-11
  • Spring MVC Interceptor 實現(xiàn)性能監(jiān)控的功能代碼

    Spring MVC Interceptor 實現(xiàn)性能監(jiān)控的功能代碼

    本篇文章主要介紹了Spring MVC Interceptor 實現(xiàn)性能監(jiān)控的功能代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-09-09

最新評論

蓬莱市| 湟源县| 类乌齐县| 泗阳县| 长葛市| 深泽县| 永福县| 图们市| 张家川| 阳城县| 高淳县| 黄山市| 台安县| 平湖市| 英德市| 三亚市| 久治县| 镶黄旗| 马公市| 阿拉善右旗| 隆昌县| 保靖县| 剑川县| 凤翔县| 息烽县| 万宁市| 金溪县| 淮阳县| 河南省| 卫辉市| 本溪市| 玛沁县| 桓台县| 南郑县| 南投市| 明星| 红安县| 中山市| 侯马市| 周至县| 琼海市|