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

猜你喜欢

转载自www.cnblogs.com/chaojizhengui/p/jooq_youhua.html