日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

使用 Hibernate 和 MySQL 需要知道的五件事

 栲栗 2018-03-28

  使用 JPA 和 Hibernate 的好處之一是它提供了數(shù)據(jù)庫特定方言和功能抽象。 因此,理論上,您可以實(shí)現(xiàn)一個(gè)應(yīng)用程序,將其連接到一個(gè)受支持的數(shù)據(jù)庫,并且它可以在不用更改任何代碼的情況下運(yùn)行。

  Hibernate 真的很好。 但老實(shí)說,您沒有想過您的應(yīng)用程序能與每個(gè)支持的數(shù)據(jù)庫完美運(yùn)行,是嗎?

  Hibernate 處理最重要的事情。 但是,如果您希望應(yīng)用能夠運(yùn)行良好,您仍然需要知道要使用哪種數(shù)據(jù)庫,并相應(yīng)地調(diào)整配置和代碼。

  在之前的一篇文章中,我討論了“如果你想使用 Hibernate 和 PostgreSQL 數(shù)據(jù)庫你需要知道的 6 件事情”。今天我想仔細(xì)看看 MySQL 數(shù)據(jù)庫。

  1、映射:主鍵

  處理和創(chuàng)建主鍵很基礎(chǔ),但也是應(yīng)用程序最重要的一部分。

  JPA 規(guī)范的 **@GeneratedValue** 注解允許您定義用于創(chuàng)建唯一主鍵值的策略。您可以選擇 SEQUENCE、IDENTITY、TABLE 和 AUTO。

  一般來說,我建議使用 SEQUENCE 策略,因?yàn)樗试S Hibernate 使用 JDBC 批處理和其他需要延遲執(zhí)行 SQL INSERT 語句的優(yōu)化策略。

  然而,您不能將此策略與 MySQL 數(shù)據(jù)庫一起使用。因?yàn)樗枰粋€(gè)數(shù)據(jù)庫序列,恰好 MySQL 不支持此功能。

  因此,您需要在 IDENTITY 和 TABLE 之間進(jìn)行選擇??紤]到 TABLE 策略的性能和可擴(kuò)展性問題,這很容易作出決定。

  如果您正在使用 MySQL 數(shù)據(jù)庫,則應(yīng)始終使用 GenerationType.IDENTITY。它使用自動增量(autoincremented )的數(shù)據(jù)庫列,這是最有效的可用方法。您可以通過使用 **@GeneratedValue(strategy = GenerationType.IDENTITY)** 注解主鍵屬性來執(zhí)行此操作。

  @Entity

  public class Author {

  @Id

  @GeneratedValue(strategy = GenerationType.IDENTITY)

  @Column(name = "id", updatable = false, nullable = false)

  private Long id;

  ...

  }

  2、映射:Hibernate 5 中 GenerationType.AUTO 問題

  當(dāng)您使用 GenerationType.AUTO 時(shí),Hibernate 會根據(jù) Hibernate 方言選擇生成策略。如果您需要支持多數(shù)據(jù)庫,以下一種常見的方法。

  @Entity

  public class Author {

  @Id

  @GeneratedValue(strategy = GenerationType.AUTO)

  @Column(name = "id", updatable = false, nullable = false)

  private Long id;

  ...

  }

  在舊版本中,Hibernate 為 MySQL 數(shù)據(jù)庫選擇 GenerationType.IDENTITY。 這是一個(gè)不錯(cuò)的選擇。如之前所述,這是最有效的方法。

  不幸的是此行為在 Hibernate 5 中發(fā)生了改變?,F(xiàn)在是選擇 GenerationType.TABLE,它使用數(shù)據(jù)庫表來生成主鍵。 這種方法需要大量數(shù)據(jù)庫查詢和悲觀鎖來生成唯一值。

  14:35:50,959 DEBUG [org.hibernate.SQL] - select next_val as id_val from hibernate_sequence for update

  14:35:50,976 DEBUG [org.hibernate.SQL] - update hibernate_sequence set next_val= ? where next_val=?

  14:35:51,097 DEBUG [org.hibernate.SQL] - insert into Author (firstName, lastName, version, id) values (?, ?, ?, ?)

  您可以通過定義一個(gè) **@GenericGenerator** 來避免這一點(diǎn),以下代碼告訴 Hibernate 使用本地策略生成主鍵值。

  @Entity

  public class Author {

  @Id

  @GeneratedValue(strategy = GenerationType.AUTO, generator = "native")

  @GenericGenerator(name = "native", strategy = "native")

  @Column(name = "id", updatable = false, nullable = false)

  private Long id;

  ...

  }

  然后,Hibernate 將使用 MySQL 自動增量數(shù)據(jù)庫列生成主鍵值。

  14:41:34,255 DEBUG [org.hibernate.SQL] - insert into Author (firstName, lastName, version) values (?, ?, ?)

  14:41:34,298 DEBUG [org.hibernate.id.IdentifierGeneratorHelper] - Natively generated identity: 1

  3、映射:只讀視圖

  使用 JPA 與 Hibernate,您可以以與任何數(shù)據(jù)庫表相同的方式來映射視圖。 只要遵循 Hibernate 的命名約定,您只需要實(shí)現(xiàn)一個(gè)使用了 **@Entity** 注解的類,該類的屬性為您想要映射的列。成都青羊區(qū)治療早泄費(fèi)用是多少

  如果視圖是只讀的,您應(yīng)該使用 **@Immutable** 注解告訴 Hibernate。 然后它將忽略對該實(shí)體的所有更改。

  @Entity

  @Immutable

  public class BookView {

  @Id

  @Column(name = "id", updatable = false, nullable = false)

  private Long id;

  @Column(name = "version")

  private int version;

  @Column

  private String title;

  @Column

  @Temporal(TemporalType.DATE)

  private Date publishingDate;

  @Column

  private String authors;

  ...

  }

  4、查詢:MySQL特有的函數(shù)與數(shù)據(jù)類型

  作為一個(gè)數(shù)據(jù)庫,MySQL 使用一組自定義函數(shù)和數(shù)據(jù)類型來擴(kuò)展 SQL 標(biāo)準(zhǔn)。 其中的例子是 JSON 數(shù)據(jù)類型和 sysdate 函數(shù)。

  JPA 不支持這些,但由于 Hibernate 的 MySQL 方言,您可以使用它們。

  Query q = em.createQuery("SELECT a, sysdate() FROM Author a ");

  Listresults = q.getResultList();

  如果您發(fā)現(xiàn) Hibernate 的 MySQL 方言不支持的函數(shù)或者數(shù)據(jù)類型,可以使用一個(gè) AttributeConverter 將數(shù)據(jù)類型轉(zhuǎn)換為受支持的數(shù)據(jù)類型和使用 JPQL 函數(shù)來調(diào)用一個(gè) JPQL 查詢中的任意函數(shù)。

  但請記住,使用數(shù)據(jù)庫特有的函數(shù)或數(shù)據(jù)類型,您可以將應(yīng)用程序綁定到特定的數(shù)據(jù)庫。如果需要支持不同的數(shù)據(jù)庫,您將需要更改應(yīng)用程序的這部分代碼。

  5、查詢:存儲過程

  許多數(shù)據(jù)庫管理員喜歡在數(shù)據(jù)庫中使用存儲過程來執(zhí)行數(shù)據(jù)繁重的操作。 大多數(shù)情況下,這種方法比在 Java 代碼中執(zhí)行相同的操作要快得多。

  但是,大多數(shù) Java 開發(fā)人員并不想使用存儲過程。 當(dāng)然,有一個(gè)說法是業(yè)務(wù)邏輯分布在多個(gè)系統(tǒng)上,這使得它更加難測試和理解。 另一個(gè)原因是在 JPA 2.1 之前,該規(guī)范并沒有直接支持存儲過程調(diào)用。 你必須使用原生查詢,總之感覺很復(fù)雜。

  這在 JPA 2.1 引入了 StoredProcedureQuery 和 **@NamedStoredProcedureQuery** 才有所改變。

  @NamedStoredProcedureQuery

  **@NamedStoredProcedureQuery** 注解允許您定義存儲過程調(diào)用一次,且可通過其名稱在業(yè)務(wù)代碼中引用它。 以下代碼片段展示了一個(gè)簡單示例,它定義了存儲過程 calculate 的調(diào)用,附帶了輸入?yún)?shù) x 和 y 以及輸出參數(shù) sum。成都男性一般做包皮手術(shù)費(fèi)用要多少?

  @NamedStoredProcedureQuery(

  name = "calculate",

  procedureName = "calculate",

  parameters = { @StoredProcedureParameter(mode = ParameterMode.IN, type = Double.class, name = "x"),

  @StoredProcedureParameter(mode = ParameterMode.IN, type = Double.class, name = "y"),

  @StoredProcedureParameter(mode = ParameterMode.OUT, type = Double.class, name = "sum") })

  然后,您可以將 **@NamedStoredProcedureQuery** 的名稱提供給 EntityManager 的 createNamedStoredProcedureQuery,以實(shí)例化一個(gè)新的 StoredProcedureQuery。

  StoredProcedureQuery query = em.createNamedStoredProcedureQuery("calculate");

  query.setParameter("x", 1.23d);

  query.setParameter("y", 4d);

  query.execute();

  Double sum = (Double) query.getOutputParameterValue("sum");

  您可以在代碼段中看到,您可以設(shè)置輸入?yún)?shù)的值,方法與設(shè)置 JPQL 查詢的綁定參數(shù)值一樣。 您只需使用輸入?yún)?shù)的名稱和值來調(diào)用StoredProcedureQuery 的 setParameter 方法即可。

  StoredProcedureQuery

  存儲過程調(diào)用的編程定義非常類似于前面示例中給出的基于注解的方法。 您只需使用要執(zhí)行的存儲過程的名稱配合 EntityManager 調(diào)用 createStoredProcedureQuery 即可。有一個(gè) StoredProcedureQuery 接口,您可以使用它來注冊存儲過程的輸入?yún)?shù)和輸出參數(shù)。

  StoredProcedureQuery query = em.createStoredProcedureQuery("calculate");

  query.registerStoredProcedureParameter("x", Double.class, ParameterMode.IN);

  query.registerStoredProcedureParameter("y", Double.class, ParameterMode.IN);

  query.registerStoredProcedureParameter("sum", Double.class, ParameterMode.OUT);

  這就是您定義存儲過程調(diào)用全部需要做的事。 之后,您可以與 **@NamedStoredProcedureQuery** 一樣使用它。 在執(zhí)行存儲過程調(diào)用之前,需要設(shè)置輸入?yún)?shù)值。睪丸炎不治能不能自己好?

  query.setParameter("x", 1.23d);

  query.setParameter("y", 4d);

  query.execute();

  6、總結(jié)

  如您所見,Hibernate 已經(jīng)支持大多數(shù) MySQL 特有的功能。 但是,如果要?jiǎng)?chuàng)建一個(gè)輕便和性能良好的應(yīng)用程序,還需要記住一些事項(xiàng)。

  特別是在 Hibernate 5 中生成唯一主鍵值和 GenerationType.AUTO 的行為的改變,可能會在將應(yīng)用程序部署到生產(chǎn)環(huán)境時(shí)產(chǎn)生意外的可擴(kuò)展性問題。

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多