为什么项目中用了JOOQ后大家都不愿再用Mybatis?

前言

今天给大家介绍一个新的ORM框架->JOOQ,可能很多朋友还没有听说过这个框架,码农哥之前也是一直在使用Mybatis框架作为Java工程中的持久层访问框架,但是最近的一些项目采用JOOQ框架开发后,码农哥表示再也不想用Mybatis了!

为什么这么说呢?因为JOOQ在代码层面要比Mybatis简洁得多,而且性能也非常优异。相信大家都有过这样的体会,我们在项目工程中使用Mybatis进行数据库相关代码的编写时,为了提高工程效率,一般会在数据库模型设计完成后,一次性使用Mybatis代码插件(如:mybatis-generator),来生成Mybatis数据库访问的实体类代码以及XML、Mapper等映射代码,从而尽量以面向对象的方式来操作和访问数据库。而通过这样的方式,虽然在工程效率上提高了很多,但是从代码的简洁和优雅性上来说就会让人感觉特别的啰嗦,因为自动生成的代码并不完全都是你在项目中能够用得到的。

所以,有些对代码有追求的同学就会以比较简洁的方式来手写SQL代码。如在@Mapper接口中编写这样的代码:

@Select("select max(t.balance_id) from balance t where t.country=#{country}\n")
String selectMaxId(Map<String, String> paramMap);

而虽然这种方式可以减少很多无用的代码量,但是在业务逻辑比较复杂的场景下这种方式显然又会大大降低开发的效率,因为通过这样的方式不仅SQL编写的通用层度需要我们花费额外的时间去考虑,而且由于Java面向对象的编程方式,我们还需要花费很多的时间来将数据库查询结果映射成为实体对象,所以使用Mybatis进行持久层开发时有时候真的是让人又爱又恨

那么有没有一种新的ORM框架既能够保持Mybatis的灵活性又不像Hibernate那样重呢?毕竟大家也都是从Hibernate的魔爪中逃离出来后才选择使用Mybatis直到今天的!在软件工程领域就是这样,有痛点的地方就一定会有人提供解决方案,JOOQ就是这样一个产物!

JOOQ简介

JOOQ是基于Java访问关系型数据库的工具包,它具有轻量、简单、并且足够灵活的特点,通过JOOQ我们可以轻松的使用Java面向对象的语法来实现各种复杂的SQL。相比于传统ORM框架,如Hibernate、Mybatis来说,JOOQ汲取了即汲取了它们操作数据的简单性和安全性、同时也保留了原生SQL的灵活性,从某种程度上说JOOQ更像是介于ORM和JDBC的中间层。

JOOQ目前在国内相对来说还比较小众,对于大部分从SSH或者SSM成长起来的码农朋友们来说,心里估计会质疑“这玩意用的这么少,到底靠不靠谱?”。在这里码农哥可以很负责任的说JOOQ是靠谱的!因为码农哥已经在好几个生产项目上实践过了,而且是在比较核心的支付系统上完全使用了JOOQ来替代Mybatis作为持久层框架,并且这个支付系统的并发量也是非常高的,所以JOOQ框架本身是能够经受住真实业务场景的考验的!

SpringBoot项目集成JOOQ

接下来我们就来一起看看,如何在SpringBoot的项目中集成和使用JOOQ吧!首先,我们在项目中引入JOOQ的stater依赖包,如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jooq</artifactId>
</dependency>

因为JOOQ对Spring Boot有很好的支持,所以我们只需要引入相应的starter依赖即可,而具体的版本则是与Spring Boot的版本关联的,这里并不需要我们去指定。

其次,我们需要在项目中配置JOOQ的代码生成插件,这样JOOQ就可以自动在项目编译的时候为我们生成所需要的数据库以来对象了,在项目的pom.xml中配置Maven插件,如下:

<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<executions>
    <execution>
        <id>default</id>
        <phase>generate-sources</phase>
        <goals>
            <goal>generate</goal>
        </goals>
        <configuration>
            <jdbc>
                <driver>com.mysql.jdbc.Driver</driver>
                <url>jdbc:mysql://127.0.0.1:3306</url>
                <user>root</user>
                <password><![CDATA[123456]]></password>
            </jdbc>
            <generator>
                <name>org.jooq.util.DefaultGenerator</name>
                <generate>
                    <instanceFields>true</instanceFields>
                    <pojos>true</pojos>
                    <daos>true</daos>
                </generate>
                <database>
                    <inputSchema>jets</inputSchema>
                    <name>org.jooq.util.mysql.MySQLDatabase</name>
                    <includes>.*</includes>
                    <excludes>schema_version</excludes>
                </database>
                <target>
                    <packageName>${app.package}</packageName>
                    <directory>target/generated-sources/jooq</directory>
                </target>
            </generator>
        </configuration>
    </execution>
</executions>
</plugin>

配置完成这个Maven插件后,基本上JOOQ就算差不多与SpringBoot集成完成了,如果此时编译项目JOOQ代码插件就会在target/generated-sources/jooq目录下根据数据库中的表结构生成相应的数据库操作对象,而这个过程则完成对开发人员透明,我们并不需要做额外的事情。

而在具体的业务逻辑中,需要操作数据库时我们就可以很方便的使用这些自动生成的代码来进行操作,例如,我们需要在业务代码中执行insert操作,代码如下:

@Slf4j
@Service
public class OpenServiceImpl implements OpenService {

    @Autowired
    protected DSLContext dslContext;

    @Override
    public BalanceChargeTradeResVo balanceChargeTrade(BalanceChargeTradeReqVo balanceChargeTradeReqVo)
            throws VerifyDataException, BalanceCreateOrderException {
        BalanceChargeTradeResVo balanceChargeTradeResVo;
        try {
            WalletUserBalanceOrderRecord walletUserBalanceOrderRecord = createBalanceChargeOrder(
                    balanceChargeTradeReqVo);
            dslContext.executeInsert(walletUserBalanceOrderRecord);
            balanceChargeTradeResVo = BalanceChargeTradeResVo.builder().userId(balanceChargeTradeReqVo.getUserId())
                    .amount(balanceChargeTradeReqVo.getAmount()).currency(balanceChargeTradeReqVo.getCurrency())
                    .orderId(walletUserBalanceOrderRecord.getOrderId()).businessType(BusinessType.TOP_UP.getCode())
                    .build();
            return balanceChargeTradeResVo;
        } catch (Exception e) {
            throw new BalanceCreateOrderException(ErrorCode.BALANCE_CHARGE_ORDER_ERROR.getCode(),
                    ErrorCode.BALANCE_CHARGE_ORDER_ERROR.getDesc());
        }
    }

在以上代码中,我们只需要在service业务类中注入DSLContext对象,并在组装完自动生成的数据库类的对象后执行executeInsert方法就可以完成insert操作了。而如果我们要完成查询操作,也可以很简单的实现,代码如下:

@Slf4j
@Service
public class OpenServiceImpl implements OpenService {

    @Autowired
    protected DSLContext dslContext;

    @Override
    public BalanceQueryResVo balanceQuery(long userId) throws AccountNoExistException {
        List<WalletUserBalanceRecord> walletUserBalanceRecordList = dslContext
                .selectFrom(WalletUserBalance.WALLET_USER_BALANCE)
                .where(WalletUserBalance.WALLET_USER_BALANCE.USER_ID
                        .eq(String.valueOf(userId))).fetchInto(WalletUserBalanceRecord.class);
        if (walletUserBalanceRecordList == null || walletUserBalanceRecordList.size() <= 0) {
            throw new AccountNoExistException(ErrorCode.ACCOUNT_NO_EXIST_ERROR.getCode(),
                    ErrorCode.ACCOUNT_NO_EXIST_ERROR.getDesc());
        }
        Optional<WalletUserBalanceRecord> walletUserBalanceRecord = walletUserBalanceRecordList.stream()
                .filter(o -> o.getAccType().equals(String.valueOf(AccType.CASH_ACCOUNT.getCode()))).findFirst();
        BalanceQueryResVo balanceQueryResVo = BalanceQueryResVo.builder().userId(userId)
                .balance(walletUserBalanceRecordList.stream().mapToInt(o -> o.getBalance().intValue()).sum())
                .currency(walletUserBalanceRecord.get().getCurrency()).build();
        return balanceQueryResVo;
    }

在如👆代码中,我们需要通过自动代码生成的类指定表名,并以面向对象的语法方式组装查询条件后就可以完成查询操作了!这里只是简单介绍了两种通过JOOQ实现常见数据库操作的方法,更多的细节,大家可以参考JOOQ用户手册!

这样你会发现操作数据库更加方便快捷了,而且因为自动代码生成对开发者是透明的,所以整个工程的代码整洁度也提高了!PS:大家可以在自己的项目中试试JOOQ,相信你一定不会后悔!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容

  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,474评论 0 4
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,094评论 1 32
  • 使用Jooq和flywayDB改善代码质量 @(个人博客)[数据库, mysql, 改进, jooq, kotli...
    asiazhang2002阅读 3,880评论 0 4
  • mybatis中的sqlSession是线程安全的吗? 链接:https://blog.csdn.net/qq_3...
    刘小刀tina阅读 2,069评论 0 3
  • 油菜花谢了 剩绿油油的叶 香樟树开花 小小的白色的 湖面柳絮飘 忽惊扰了路人 风带来夏意 天蓝回忆好长
    苏叶凉阅读 249评论 2 6