JOOQ初入门——Get back in control of your sql

本文介绍了JOOQ作为ORM工具的优势,强调其灵活性和对复杂SQL的良好支持。通过实例展示了如何进行代码生成、使用DSLContext操作数据库、实现事务管理,以及JOOQ的其他进阶用法。适合对ORM工具寻求更多控制的开发者阅读。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引言

最近在实习中,公司用到了Jooq,针对自己的疑问,特地在网上找资料学习

JOOQ是什么?

JOOQ 是基于Java访问关系型数据库的工具包,轻量,简单,并且足够灵活,可以轻松的使用Java面向对象语法来实现各种复杂的sql。对于写Java的码农来说ORMS再也熟悉不过了,不管是Hibernate或者Mybatis,都能简单的使用实体映射来访问数据库。但有时候这些 ‘智能’的对象关系映射又显得笨拙,没有直接使用原生sql来的灵活和简单,而且对于一些如:joins,union, nested selects等复杂的操作支持的不友好。JOOQ 既吸取了传统ORM操作数据的简单性和安全性,又保留了原生sql的灵活性,它更像是介于 ORMS和JDBC的中间层。对于喜欢写sql的码农来说,JOOQ可以完全满足你控制欲,可以是用Java代码写出sql的感觉来。就像官网说的那样 :

get back in control of your sql

相比于流行的Hibernate/Mybatis来说,这货的文档少的可怜,而且大多是英文,但不管这么多,总要先试试,先尝试一下官网的demo
官网地址

开源版——Open Source Edition

<dependency>  
    <groupId>org.jooq</groupId>
    <artifactId>jooq</artifactId> 
    <version>3.11.4</version> 
</dependency> 
<dependency> 
    <groupId>org.jooq</groupId> 
    <artifactId>jooq-meta</artifactId>
    <version>3.11.4</version>
</dependency>
 <dependency> 
    <groupId>org.jooq</groupId>
    <artifactId>jooq-codegen</artifactId>
    <version>3.11.4</version> 
</dependency>  

首先要代码生成

需要使用mysql-connector

	<profiles>
		<profile>
			<id>jooq</id>
			<properties />
			<activation>
				<property>
					<name>jooq</name>
				</property>
			</activation>
			<build>
				<plugins>
					<plugin>
						<groupId>org.jooq</groupId>
						<artifactId>jooq-codegen-maven</artifactId>
						<version>${jooq.version}</version>
						<executions>
							<execution>
								<goals>
									<goal>generate</goal>
								</goals>
							</execution>
						</executions>
						<configuration>
							<jdbc>
								<driver>com.mysql.jdbc.Driver</driver>
								<url>xxxxxxx</url>
								<user>root</user>
								<password>xxxxxx</password>
							</jdbc>
							<generator>
								<database>
									<name>org.jooq.util.mysql.MySQLDatabase</name>
									<includes>.*</includes>
									<excludes />
									<inputSchema>xxxx</inputSchema>
								</database>
								<generate>
									<deprecated>false</deprecated>
								</generate>
								<target>
									<packageName>com.jooq</packageName>
									<directory>src/main/java</directory>
								</target>
								<generate>
									<pojos>false</pojos>
									<daos>false</daos>
								</generate>
							</generator>
						</configuration>
					</plugin>
				</plugins>
			</build>
		</profile>
	</profiles>

配置好相关参数后直接maven安装就好了
安装成功后目录下会显示:
在这里插入图片描述
这里生成了相关JAVA Record,有了这个就可以直接使用JAVA代码与数据库产生映射。

构造DSLContext

我们使用的是数据源是阿里云Druid

阿里云Druid是一个用于实时查询和分析的高容错、高性能开源分布式系统,旨在快速处理大规模的数据,并能够实现快速查询和分析。

新建DataSourceConfig用于配置Druid连接池:

@Configuration
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceConfig {
    @Primary
    @Bean(name = "localhostDatasource")
    public DataSource dataSourceConfig(DataSourceProperties dataSourceProperties){
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setUrl(dataSourceProperties.getUrl());
        druidDataSource.setUsername(dataSourceProperties.getUsername());
        druidDataSource.setPassword(dataSourceProperties.getPassword());
        druidDataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
        return druidDataSource;
    }
}

在Service层中的构造函数进行初始化:

public class Demo{
	private DSLContext dslContext;

    public Demo(@Qualifier("localhostDatasource") DataSource dataSource){
        ConnectionProvider connectionProvider =  new DataSourceConnectionProvider(dataSource);
        org.jooq.Configuration configuration = new DefaultConfiguration()
                .set(connectionProvider)
                .set(SQLDialect.MYSQL);//这里表明了使用的是MYsql数据库
        dslContext = DSL.using(configuration);
    }
}

这样我们就得到了DSLContext进行数据库的操作了

实现普通的增删改查

@Test
  public void insert() {
    MyStore store = new MyStore();
    store.setName("foo");
    store.setAddress("mars No. 1989");
    StoreRecord storeRecord = dslContext.newRecord(Tables.STORE, store);
    storeRecord.insert();

    dslContext.insertInto(Tables.STORE)
      .set(Store.STORE.NAME, "bar")
      .set(Store.STORE.ADDRESS, "eclipse No.1891")
      .execute();
  }
  @Test
  public void find() {
    dslContext.selectFrom(Tables.STORE)
      .where(Store.STORE.NAME.eq("foo"))
      .fetchInto(MyStore.class)
      .stream()
      .forEach(myStore -> System.out.println(myStore.getName()));
  }

  @Test
  public void update() {
    dslContext.update(Tables.STORE)
      .set(Store.STORE.ADDRESS, "sun No.1988")
      .where(Store.STORE.ID.eq(UInteger.valueOf(1)))
      .execute();
  }

进阶用法

  • 事务

JOOQ 官方提供了 TransactionProvider 对事务的支持,只需要在创建DSLContext的时候设置一下。代码如下:

ConnectionProvider connectionProvider =  new DataSourceConnectionProvider(dataSource)
TransactionProvider transactionProvider = new DefaultTransactionProvider(connectionProvider, false);
Configuration configuration = new DefaultConfiguration()
      .set(connectionProvider)
      .set(transactionProvider)
      .set(SQLDialect.MYSQL);
return DSL.using(configuration);

具体例子

 @Test
  public void transaction() {
    dslContext.transaction(configuration -> {
      DSL.using(configuration).update(Tables.STORE)
        .set(Store.STORE.ADDRESS, "transaction test1")
        .where(Store.STORE.ID.eq(UInteger.valueOf(1)))
        .execute();
      DSL.using(configuration).update(Tables.STORE)
        .set(Store.STORE.ADDRESS, "transaction test1")
        .where(Store.STORE.ID.eq(UInteger.valueOf(2)))
        .execute();
      int i = 1/0;
    });
  }

没错就这么简单,只需要把需要用事务的代码包在transaction里面,假如有异常发生,业务会自动回滚。需要注意一点的是必须使用configuration 重新构建context,要不然不会生效,这也是我为什么没有使用官方提供的事务管理器。正常的项目中一个业务需要组合若干个service 方法来完成,而官方提供的默认事务管理器就需要把所有业务写在一个方法中,这在实际应用中显然是不合理的。幸好JOOQ抽象了事务管理,这样我们就可以集成第三方的事务管理器。

  • 其他特性
    JOOQ还有很多其他有意思的特性 如对其他语言的支持,数据导出,存储过程,JPA支持等等,感兴趣的可以参阅一下文档。说到文档,不得不说开发者对JOOQ的用心,简单、详细、美观是最直接的感受,并且还有丰富的demo示例,对于编程新手来说上手使用也是手到擒来。

  • SelectJoinStep

public Collection<BalanceModel> getTopBalance(boolean user, boolean bank, int fromRank, int toRank, boolean showHidden)
{
    SelectJoinStep<Record4<String, String, String, Long>> from = db.getDSL()
            .select(TABLE_BALANCE.ACCOUNT_ID, TABLE_BALANCE.CURRENCY, TABLE_BALANCE.CONTEXT, TABLE_BALANCE.BALANCE)
            .from(TABLE_BALANCE.join(TABLE_ACCOUNT).on(TABLE_BALANCE.ACCOUNT_ID.eq(TABLE_ACCOUNT.ID)));
    Condition userCond = TABLE_ACCOUNT.IS_UUID.eq(true);
    Condition bankCond = TABLE_ACCOUNT.IS_UUID.eq(false);
    SelectConditionStep<Record4<String, String, String, Long>> where;
    if (!user && !bank)
    {
        throw new IllegalArgumentException();
    }
    if (user)
    {
        where = from.where(userCond);
    }
    else if (bank)
    {
        where = from.where(bankCond);
    }
    else
    {
        where = from.where(DSL.condition(true));
    }

    if (!showHidden)
    {
        where = where.and(TABLE_ACCOUNT.HIDDEN.eq(false));
    }
    return where.orderBy(TABLE_BALANCE.BALANCE.desc()).limit(fromRank - 1, toRank - fromRank + 1).fetchInto(BalanceModel.class);
}

写在最后

对于在国内占了大半边天的Hibernate/Mybatis,JOOQ还是一个小清新,很多人对它都还陌生。通过上面的简单介绍,也许对你有一点帮助。无论是强大的数据转换能力还是处理业务的灵活性,简洁性,都会带来一些不一样的体验。如果你已经厌倦了ORMS的开发模式,正好又接手一个新的项目,JOOQ也许是一个不错的选择。

参考博客:https://blog.maxleap.cn/archives/1108

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值