JOOQ 入門(四)-- DAO層代碼改進


序言

上篇講CRUD例子的時候講到每一次使用JOOQ都需要用到DSLContext的實例。

觀察上面圖片中的getAll()updateUser()方法會發現,每次都用DSLContext的子類DSLusring()方法來實例化DSLContext太麻煩。

能否定義一個DSLContext類型的成員變量,然后Dao中所有的方法都用這同一個DSLContext實例呢 ,答案是肯定的。

解決這個猜想的整個過程

想到這個問題,最開始想到的是既然需要一個DSLContext實例,那么去看看DSL.using()這個方法,打開DSL類的結構可以看到

using()方法有很多種實現,這里主要看需要Connection和DataSource參數的幾個using()方法。

因為想到Springboot中默認提供了Hikari數據庫連接池,和其他數據庫連接池一樣,它也有自己實現的DataSource。

 

想到這里,實例化DSLContext的所需要的參數都具備了,用代碼實現出來:

 1 import org.jooq.Result;
 2 import org.jooq.SQLDialect;
 3 import org.jooq.impl.DSL;
 4 import org.springframework.beans.factory.annotation.Autowired;
 5 import org.springframework.stereotype.Repository;
 6 
 7 /**
 8  * @author chaojizhengui
 9  * @description user DAO
10  * @date 2020/5/15 14:52
11  */
12 @Repository
13 public class UserDao {
14     // 注入Hikari的DataSource,
15     @Autowired
16     HikariDataSource dataSource;
17 
18     // DSL上下文是所有數據庫操作的入口,意思就是要用jooq干任何事都要先實例化這個DSLContext
19     DSLContext create;
20 
21     // 初始化DSLContext
22     public UserDao(){
23         this.create = DSL.using(this.dataSource,SQLDialect.MYSQL);
24     }
25 
26     /**
27      * 查詢
28      * @return
29      */
30     public Result<BkUserRecord> getAll(){
31         Result<BkUserRecord> result = this.create
32                 .selectFrom(BkUser.BK_USER)
33                 .orderBy(1)
34                 .fetch();
35         return result;
36     }

代碼有了,接下來就是測試,驗證自己的想法是否正確,在Springboot 的xxxxApplicationTests類中寫

測試方法:

//將userDao注入進單元測試類
    @Autowired
    UserDao userDao;

    @Test
    void testUser(){
        System.out.println("查詢---");
        System.out.println(userDao.getAll());
        System.out.println("查詢---");

    }

執行結果:失敗

測試不通過,接下來就得去找找不通過的原因,給代碼加斷點跟蹤發現

仔細看上面的調試圖會發現,在UserDao的構造方法執行結束,dataSource都還是null,也就說明

1 @Autowired
2     HikariDataSource dataSource;

dataSource的通過@Autowired實例化的太晚了,需要通過其他的方式來為dataSource實例化。

所以聯想直接將@Autowired注解寫在構造函數上,就是直接在構造函數執行的時候就實例化dataSource。

將代碼改成:

 1 package com.bkn.breakingnews.modules.user.dao;
 2 
 3 import com.bkn.breakingnews.model.tables.BkUser;
 4 import com.bkn.breakingnews.model.tables.records.BkUserRecord;
 5 import com.zaxxer.hikari.HikariDataSource;
 6 import org.jooq.DSLContext;
 7 import org.jooq.Result;
 8 import org.jooq.SQLDialect;
 9 import org.jooq.impl.DSL;
10 import org.springframework.beans.factory.annotation.Autowired;
11 import org.springframework.stereotype.Repository;
12 
13 /**
14  * @author chaojizhengui
15  * @description user DAO
16  * @date 2020/5/15 14:52
17  */
18 @Repository
19 public class UserDao {
20     // DSL上下文是所有數據庫操作的入口,意思就是要用jooq干任何事都要先實例化這個DSLContext
21     DSLContext create;
22     // 初始化DSLContext,這里在構造器中注入Hikari的DataSource
23     @Autowired
24     public UserDao(HikariDataSource dataSource){
25         this.create = DSL.using(dataSource,SQLDialect.MYSQL);
26     }
27 
28     /**
29      * 查詢
30      * @return
31      */
32     public Result<BkUserRecord> getAll(){
33         Result<BkUserRecord> result = this.create
34                 .selectFrom(BkUser.BK_USER)
35                 .orderBy(1)
36                 .fetch();
37         return result;
38     }

測試結果:測試通過

優化之后每次就可以直接在方法中使用this.create直接來做SQL操作,免去每次都初始化DSLContext的麻煩。

這篇算是突然多出來的小插曲,其實和JOOQ的具體使用沒多大關系,記錄一下,猜想-解決問題-實現,的整個過程,希望有所收獲。

總結

a.以前用單元測試用的不多,每次有問題都是整個業務邏輯的代碼都跑一遍然后打斷點測試,這樣的調試方法雖然也可行,

但是沒有用單元測試看的直觀,多用單元測試會大大提高調試效率。

b.Bean的注入問題是Spring的核心之一,仍然需要多去理解。

 

 

 

 

 

 

Hikari


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM