<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                啟動數據庫、后臺、前后并準備一些基礎的測試數據后,來查看一個前面單元測試中遺漏的BUG。 ![](https://img.kancloud.cn/a3/3d/a33d768326f4ff5976f2ca21c04248ce_1199x270.gif) 在編輯學生的過程時,可以任意的變更學位的位數,任意的修改學生的姓名。而完全忽略掉了本章第五節新增學生時對學號、姓名的長度做的校驗。相信任何程序員都接受不了當前的現實。 只所以會這樣還要看看歷史上對學號、姓名進行校驗的代碼: entity/Student.java ```java /** * 在實體保存到數據庫以前,執行1次 * 1. 校驗name 字段長度為2-20 * 2. 校驗sno 字段長為為6 */ @PrePersist // ★ public void perPersis() { if (this.name != null ) { if (this.name.length() < 2) { throw new DataIntegrityViolationException("name length less than 2"); } if (this.name.length() > 20) { throw new DataIntegrityViolationException("name length more than 20"); } } if (this.sno != null) { if (this.sno.length() != 6) { throw new DataIntegrityViolationException("sno length must be 6"); } } } ``` * ★ 重點在這。 @PrePersist注解的作用時,在持久化(保存)之前。而非在更新之前。 雖然在代碼層面,保存與更新都是調用了`save`方法。但hibernate還是能自動的區分出當前執行的是保存操作還是更新操作的。 # @PreUpdate `@PrePersist`中`@`代表注解,`Pre`意為在什么之前,`Persist`譯為持久化也就是保存。起到的作用是:在數據保存之前執行此注解下的內容。Hibernate同時還提供了另一個用于更新之前執行某個方法的注解:`@PreUpdate`。測試如下: entity/Student.java ```java @PreUpdate public void perUpdate() { System.out.println("正在執行更新操作: " + this.id.toString()); } ``` 然后臨時將`src/main/resources/application.propertions`中的`spring.jpa.hibernate.ddl-auto=create-drop`改為`spring.jpa.hibernate.ddl-auto=update`。然后重新啟動后臺應用并于前面重新進行測試數據的初始化工作。 > [info] create-drop:啟動應用時創建數據表,停止應用時刪除數據表。update:啟動應用時更新數據表(如有更新內容),停止應用時什么也不做。 測試如下: ![](https://img.kancloud.cn/8b/8a/8b8a1a5f45778d92c333634b41b62bab_1278x395.gif) 接下來,可以將prePersist()方法中的代碼復制到 preUpdate()方法中來達到與新增學生相同的校驗效果。也可以這樣: entity/Student.java ```java @PreUpdate public void perUpdate() { this.perPersis(); } ``` 也可以達到相同的驗證效果。 ![](https://img.kancloud.cn/47/98/47988467be6a5c948520a6be22a831cf_1278x466.gif) # 單元測試 雖然前臺后依賴式開發(前臺的開發依賴于后臺,后臺的開發也依賴于前臺)貌似很簡單,但每次修改完代碼都要用鼠標鍵盤執行相同的操作,這對做為不甘寂寞的程序員而言卻顯得難以接受。相較于這種依賴式的,每次變更代碼后都要復要的操作鼠標鍵盤式的測試,筆者更愿意選擇用代碼來測試代碼的方式。 有了新增學生的測試經驗,編輯的學生的測試也就不難了。測試的思想為:先新增一個學生,然后分別使用不符合要求的姓名、學號來更新此學生,斷言在更新過程中發生異常。最后再用符合要求的姓名、學號來更新此學生,斷言更新成功。 請按上述思路參考新增學生的校驗嘗試自行完成單元測試。**提示:**更新操作校驗失敗時將發生`TransactionSystemException`異常。 <hr> 參考代碼如下: entity/StudentTest.java ```java @Test(expected = TransactionSystemException.class) public void updateNameLengthToLongTest() { // 第一次調用save執行保存操作 this.studentRepository.save(student); this.student.setName("123456789012345678901"); // 第二次調用save執行更新操作 this.studentRepository.save(student); } @Test(expected = TransactionSystemException.class) public void updateNameLengthToShortTest() { this.studentRepository.save(student); this.student.setName("1"); this.studentRepository.save(student); } /** * 先后執行100次隨機學號 * 當學號為6位時,更新成功 * 當學號不是6位時,更新時發生異常 */ @Test public void updateSnoLengthTest() { this.studentRepository.save(student); for (int i = 1; i <= 100; i++) { this.student.setSno(RandomString.make(i)); boolean called = false; try { this.studentRepository.save(student); } catch (TransactionSystemException e) { called = true; } if (i != 6) { Assertions.assertThat(called).isTrue(); } else { Assertions.assertThat(called).isFalse(); } } } ``` 除此以外Spring還提供了功能相似的 `PostLoad`、`PostPersist`、`PostRemove`、`PreRemove`注解,官方文檔說明如下: | Type | Description | | --- | --- | | @PrePersist | Executed before the entity manager persist operation is actually executed or cascaded. This call is synchronous with the persist operation. | | @PreRemove | Executed before the entity manager remove operation is actually executed or cascaded. This call is synchronous with the remove operation. | | @PostPersist | Executed after the entity manager persist operation is actually executed or cascaded. This call is invoked after the database INSERT is executed. | | @PostRemove | Executed after the entity manager remove operation is actually executed or cascaded. This call is synchronous with the remove operation. | | @PreUpdate | Executed before the database UPDATE operation. | | @PostUpdate | Executed after the database UPDATE operation. | | @PostLoad | Executed after an entity has been loaded into the current persistence context or an entity has been refreshed. | 請自行翻譯嘗試。 # 參考文檔 | 名稱 | 鏈接 | 預計學習時長(分) | | --- | --- | --- | | 源碼地址 | [https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step4.7.9](https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step4.7.9) | - | | Hibernate: Entity listeners and Callback methods | [https://docs.jboss.org/hibernate/core/4.0/hem/en-US/html/listeners.html#d0e2985](https://docs.jboss.org/hibernate/core/4.0/hem/en-US/html/listeners.html#d0e2985) | 10 |
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看