国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

開發效率翻倍!Spring Boot @Formula 注解帶你告別繁瑣 SQL!

數據庫 其他數據庫
?@Formula?? 是 JPA 世界里的一把利刃,它讓我們能在實體層優雅地表達計算邏輯。? 無論是聚合查詢、衍生屬性還是條件標識,都能在不破壞 ORM 結構的情況下完成。

在實際項目中,我們常常需要在實體層中展現一些“計算得來的值”——例如折扣價、總金額、平均值或派生狀態。 若每次都在 Service 層或 Mapper 層手寫 SQL,不僅讓代碼臃腫、可讀性差,還容易在后續維護中引發問題。

其實 Hibernate 早就給出了優雅的答案:@Formula 注解。 它能讓我們直接在實體屬性中嵌入 SQL 表達式,從而在 ORM 層實現復雜計算與查詢邏輯。 這意味著,我們可以在不增加數據庫字段的情況下,讓實體自動攜帶計算結果

@Formula 是什么?

@Formula 是 Hibernate 提供的一個注解,用來聲明一個由 SQL 表達式計算出的只讀字段。 它不會映射到數據庫的實際列,而是在查詢時由 Hibernate 自動計算。

這種機制適用于:

  • 派生值(如全名、折扣價)
  • 聚合計算(如訂單總額、平均值)
  • 條件表達式(如狀態標志)

簡單來說,@Formula 能幫我們把一段 SQL 內聯到實體字段,從而讓計算邏輯與領域模型自然融合。

基礎用法:讓折扣價自動算出來

下面通過一個簡單示例,演示如何讓 Book 實體自動計算折扣價。

示例代碼

package com.icoderoad.formula.entity;


import jakarta.persistence.*;
import org.hibernate.annotations.Formula;
import java.math.BigDecimal;


@Entity
@Table(name = "t_book")
public class Book {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;


    private String title;
    private String isbn;
    private String description;
    private Integer page;
    private BigDecimal price;


    // 利用 @Formula 直接計算 9 折后的價格
    @Formula("price * 0.9")
    private BigDecimal discountedPrice;


    // Getter / Setter ...
}

當 Hibernate 查詢 Book 時,會自動生成如下 SQL:

select
    b.id,
    b.title,
    b.isbn,
    b.description,
    b.page,
    b.price,
    b.price * 0.9 as discountedPrice
from
    t_book b

無需手動計算,折扣價字段在加載實體時就自動帶上,簡潔又安全

高級玩法:在實體中實現聚合查詢

對于涉及多表計算的復雜場景,@Formula 的威力更大。 我們可以使用子查詢來計算關聯表的總和、計數或平均值,完全不需要顯式的 @Join

示例代碼

package com.icoderoad.formula.entity;


import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import org.hibernate.annotations.Formula;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;


@Entity
@Table(name = "x_order")
public class Order {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;


    private String orderNo;
    private LocalDateTime orderDate = LocalDateTime.now();


    // 計算訂單項的總金額
    @Formula("(SELECT COALESCE(SUM(oi.quantity * oi.price), 0) FROM x_order_items oi WHERE oi.order_id = id)")
    private BigDecimal totalAmount;


    // 統計訂單項數量
    @Formula("(SELECT COUNT(*) FROM x_order_items oi WHERE oi.order_id = id)")
    private Integer itemCount;


    // 計算平均單價
    @Formula("(SELECT COALESCE(AVG(oi.price), 0) FROM x_order_items oi WHERE oi.order_id = id)")
    private BigDecimal averageItemPrice;


    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Set<OrderItem> items = new HashSet<>();
}
package com.icoderoad.formula.entity;


import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import java.math.BigDecimal;


@Entity
@Table(name = "x_order_items")
public class OrderItem {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;


    @Column(nullable = false)
    private Integer quantity;


    @Column(nullable = false)
    private BigDecimal price;


    @JsonIgnore
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "order_id", nullable = false)
    private Order order;
}

生成的 SQL 示例:

select
    o.id,
    o.order_no,
    o.order_date,
    (select coalesce(sum(oi.quantity * oi.price),0) from x_order_items oi where oi.order_id=o.id) as totalAmount,
    (select count(*) from x_order_items oi where oi.order_id=o.id) as itemCount,
    (select coalesce(avg(oi.price),0) from x_order_items oi where oi.order_id=o.id) as averageItemPrice
from
    x_order o

這樣我們就能直接在實體中拿到統計值,而不需要額外的 SQL 或 DTO 轉換。

其它實用場景

@Formula 的靈活性極高,它能輕松應對各種派生邏輯:

聚合統計

@Formula("(select count(o.id) from orders o where o.customer_id = id)")
private int orderCount;

條件標志

@Formula("(case when status = 'ACTIVE' then true else false end)")
private boolean isActive;

派生屬性

@Formula("concat(first_name, ' ', last_name)")
private String fullName;

跨表計算

@Formula("(select coalesce(sum(p.amount), 0) from payments p where p.customer_id = id)")
private double totalPayments;

業務規則標志

@Formula("(case when balance < 0 then true else false end)")
private boolean isOverdrawn;

性能與最佳實踐

雖然 @Formula 用起來非常方便,但也有一些注意事項:

使用建議

  • 讀多寫少的場景最適合:例如統計類字段或展示性派生屬性;
  • 復雜表達式要謹慎:避免在高并發查詢中使用嵌套聚合;
  • 明確只讀特性@Formula 字段不會參與 INSERT 或 UPDATE
  • 注意 SQL 方言兼容性:部分數據庫的函數或語法差異可能導致問題;
  • 日志調試時打開 SQL 輸出:有助于分析生成語句性能。

不推薦場景

  • 涉及業務邏輯復雜的計算;
  • 需要頻繁更新或寫入字段;
  • 對數據庫移植性要求高的系統。

結語:用 @Formula 打造簡潔的領域模型

@Formula 是 JPA 世界里的一把利刃,它讓我們能在實體層優雅地表達計算邏輯。 無論是聚合查詢、衍生屬性還是條件標識,都能在不破壞 ORM 結構的情況下完成。

如果你希望項目的代碼更干凈、邏輯更集中、查詢更智能, 那么請記得——不要再把 SQL 寫進 Service 層,讓 @Formula 來幫你“做計算”吧!

責任編輯:武曉燕 來源: 路條編程
相關推薦

2025-04-18 04:22:00

2024-09-06 08:02:52

2023-09-13 15:09:35

軟件開發數字化進程

2017-08-02 14:44:06

Spring Boot開發注解

2025-04-27 03:00:00

Spring集成測試

2025-04-08 03:00:00

SpringDocker容器

2025-09-01 01:25:00

SpringMVC注解

2025-08-29 07:36:07

2025-02-27 09:10:00

MarkdownHTML前端

2023-06-02 16:24:46

SpringBootSSM

2025-08-21 09:35:29

2025-05-26 03:55:00

Spring開發Autowired

2025-05-26 10:05:00

Ansible模塊自動化

2025-01-24 07:44:31

LinuxsystemdAnsible

2025-10-28 01:25:00

SQL查詢Spring查詢模式

2020-12-13 17:54:36

開發人員

2023-05-04 12:41:30

ChatGPTSQL數據分析

2025-02-03 23:35:56

API技術.NET

2025-06-30 02:44:00

SpringBoot開發優化
點贊
收藏

51CTO技術棧公眾號

夜夜爽夜夜爽精品视频| 一区二区三区在线免费视频| 国产精品观看在线亚洲人成网| 草草在线视频| 欧美日韩国产精品一区| 中文久久久久久| 成人听书哪个软件好| 视频一区二区三区在线观看| 午夜精品影院| 成人亚洲激情网| 日韩精品永久网址| 日本久久久久久久久| 亚洲一区二区三区中文字幕在线观看| 亚洲女人天堂网| 免费成人在线电影| 亚洲第一福利网站| a级网站在线播放| 欧美一区二区三区在线观看| av女优在线| 欧美日韩免费视频| 香蒸焦蕉伊在线| 欧美性猛交xxxx偷拍洗澡| 一区二区三区高清在线视频| 偷偷要91色婷婷| 美女毛片在线看| 91福利视频久久久久| av大片在线看| 欧美日韩国产电影| 伊人影院在线视频| 亚洲黄色www网站| 日韩pacopacomama| 日韩中文字幕第一页| 久久视频免费| 欧美一级大胆视频| 亚洲欧美网站在线观看| 91视频免费在线观看| 亚洲午夜久久久久久尤物| 精品国产乱码久久久久久久软件| 99在线|亚洲一区二区| 日韩精品一区二区三区外面| 日本v片在线高清不卡在线观看| 欧美日韩免费精品| 国产宾馆实践打屁股91| 奇米影音第四色| 精品欧美国产一区二区三区| 在线观看av黄网站永久| 精品国产一区二区三区av性色| 素人一区二区三区| 国产成人精品av| 亚洲精品裸体| 国产素人在线观看| 一个色综合av| 99在线播放| 亚洲人成伊人成综合网久久久| 清纯唯美激情亚洲| 国产深夜精品福利| 热久久国产精品| 污版视频在线观看| 欧美挠脚心视频网站| 精品三级在线| 成人精品在线观看| 狠狠色丁香九九婷婷综合五月| av一卡二卡| 欧美日韩视频第一区| 亚洲福利影视| 99r国产精品视频| www.亚洲色图.com| 欧美日韩激情视频一区二区三区| 亚洲欧洲第一视频| 凹凸成人精品亚洲精品密奴| 亚洲国产高清国产精品| 国产精品丝袜在线| 求av网址在线观看| 欧美高清视频免费观看| 亚洲情侣在线| 成人午夜视频在线观看免费| 亚洲午夜国产一区99re久久| heyzo高清中文字幕在线| 2020欧美日韩在线视频| 老鸭窝毛片一区二区三区| 午夜久久久精品| 亚洲成人网在线观看| 成人情趣视频| 国产真实老熟女无套内射| 疯狂做受xxxx欧美肥白少妇 | 国产精品91xxx| 色网址在线观看| 一本色道久久88亚洲综合88| 欧美a级一区| 成人免费在线观看视频网站| 欧美岛国在线观看| 色综合天天综合网中文字幕| 久草资源站在线观看| 日韩欧美一二三区| 日韩欧美字幕| 欧美韩国日本在线| 亚洲成人av在线| 亚洲精品成人| 在线黄色免费观看| 日韩精品在线免费播放| 欧美精品麻豆| 黄页网址大全在线观看| 欧美精品一区三区| 国产精品一区在线| 91精品久久| 精品免费视频123区| 午夜激情久久久| 在线日韩一区| mm131亚洲精品| 久久国产精品影视| 丰满少妇久久久久久久| 欧美日韩色网| 精品视频一区二区三区四区| 精品国产精品自拍| 不卡av一区二区| www.男人的天堂| 欧美激情乱人伦| 99国产精品久久久久| 成人免费网站视频| 亚洲精品在线免费看| 欧美一区二区在线观看| 欧美黄色一区二区| 清纯唯美亚洲色图| 亚洲在线视频观看| 色综合久久88色综合天天6| 999精品在线| 亚洲aⅴ优女av综合久久久| 国产精品美乳在线观看| 亚洲成人777| 一区二区中文字| 成人免费在线观看| 国产精品香蕉视屏| 91成人国产精品| 亚洲国产免费看| 免费看美女视频在线网站| 国产高清精品一区| 欧美日韩精品三区| 久久国产精品久久w女人spa| 一色桃子av在线| 97超碰免费观看| 在线激情影院一区| eeuss国产一区二区三区| 9999在线精品视频| 97操碰视频| 91久久中文字幕| 91精品国产欧美日韩| 紧缚捆绑精品一区二区| 亚洲伦理久久| 亚洲jizzjizz妇女| 国产美女被下药99| 欧美中文一区二区三区| 性欧美长视频| 新版的欧美在线视频| 国产午夜大地久久| 国产福利视频一区| 欧美美女直播网站| 成人污污视频在线观看| 欧美亚洲tv| 日本精品在线| 免费看欧美一级片| 97avcom| 国产精品网址在线| yjizz视频网站在线播放| 粉嫩av四季av绯色av第一区| 5月丁香婷婷综合| 粉嫩在线一区二区三区视频| 爱高潮www亚洲精品| 日韩大胆人体| 久久久久久久久网| 91超碰中文字幕久久精品| 欧美视频一二三| 久久激五月天综合精品| 亚洲成人a级片| 超碰在线12| 影音欧美亚洲| 欧美壮男野外gaytube| 欧美丰满嫩嫩电影| 国产性做久久久久久| 很黄很黄激情成人| 欧美一区久久久| 在线观看免费观看在线91| 午夜精品美女久久久久av福利| www.欧美精品| 色综合久久综合网欧美综合网| 成人综合在线视频| 欧美黄色一区二区| 亚洲码欧美码一区二区三区| 国产一区久久精品| 欧美狂欢多p性派对| 亚洲精品一区二区三区樱花 | 日本aⅴ大伊香蕉精品视频| 51精品秘密在线观看| 久久久不卡影院| 亚洲影视综合| 超碰精品在线| 免费不卡av| 麻豆电影在线| 国产精品无码av在线播放| 国产精品免费在线播放| 久久亚洲影音av资源网 |