亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在Java項目中使用ORM

發布時間:2021-01-14 16:09:51 來源:億速云 閱讀:226 作者:Leah 欄目:開發技術

今天就跟大家聊聊有關如何在Java項目中使用ORM,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

一、ORM示例

1. Insert

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

2. Update

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

public CompletableFuture<Void> update(sys.entities.Demo obj) {
  obj.Age = 200;
  return obj.saveAsync();
}

根據條件更新(必須指定條件以防誤操作)

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("更新記錄數: " + rows);
    System.out.println("返回的值: " + outs.get(0));
    return "Done.";
  });
}

3. Delete

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

public CompletableFuture<Void> update(sys.entities.Demo obj) {
  obj.markDeleted(); //先標記為刪除狀態
  return obj.saveAsync(); //再調用保存方法
}

根據條件刪除(必須指定條件以防誤操作)

public CompletableFuture<?> delete() {
  var cmd = new SqlDeleteCommand<sys.entities.Demo>();
  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<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();
}

結果映射至匿名類

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

結果映射至繼承的匿名類

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

結果映射至樹狀結構列表

public CompletableFuture<?> tree() {
  var q = new SqlQuery<sys.entities.Demo>();
  q.where(t -> t.Name == "Rick");
  return q.toTreeAsync(t -> t.Childs); //參數指向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) //多個可重復
    .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<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("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

看完上述內容,你們對如何在Java項目中使用ORM有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

米脂县| 敖汉旗| 定陶县| 营口市| 磐石市| 东乡族自治县| 扎赉特旗| 乐安县| 汉阴县| 青浦区| 临湘市| 英德市| 宁波市| 清镇市| 吐鲁番市| 儋州市| 西和县| 清原| 榆社县| 彰化市| 托克逊县| 湖南省| 波密县| 墨脱县| 三穗县| 南召县| 鱼台县| 扬州市| 昌乐县| 化德县| 收藏| 莒南县| 长丰县| 华池县| 佛山市| 建湖县| 沙雅县| 双流县| 宝山区| 东乡县| 涞水县|