zoukankan      html  css  js  c++  java
  • 【SpringBoot DB 系列】Jooq 初体验

    【SpringBoot DB 系列】Jooq 初体验

    java 环境中,说到数据库的操作,我们通常会想到的是 mybatis 或者 hibernate,今天给大家介绍一个国内可能用得不太多的操作方式 JOOQ,一款基于 Java 访问关系型数据库的工具包,轻量,简单,并且足够灵活的 ORM 框架

    本文将各位小伙伴演示一下 jooq 集成 springboot 的姿势

    I. 项目搭建

    我们这里借助 h2dabase 来搭建演示项目,因此有兴趣的小伙伴在文末可以直接获取项目地址启动即可体验,不需要额外的安装和配置 mysql 了

    本文采用SpringBoot 2.2.1.RELEASE + maven 3.5.3 + IDEA进行开发

    1. pom 依赖

    下面给出核心的依赖配置

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

    2. 配置

    接下来设置一下数据库相关的配置信息,在资源目录resources下,新建配置文件application.properties

    #Database Configuration
    spring.datasource.url=jdbc:h2:~/h2-jooq-db
    spring.datasource.username=test
    spring.datasource.password=
    spring.datasource.driverClassName=org.h2.Driver
    

    3. 数据库初始化

    jooq 有一个特点,是需要我们自己来生成表结构对象,所以我们先初始化一下 h2dabase 的数据结构,详情可以参考博文 【DB 系列 h2databse 集成示例 demo】

    表结构定义文件schema-h2.sql, 请注意表结构与 mysql 的表创建姿势不太一样哦

    DROP TABLE IF EXISTS poet;
    
    CREATE TABLE poet (
      `id` int NOT NULL,
      `name` varchar(20) NOT NULL default '',
      CONSTRAINT pk_t_poet PRIMARY KEY (ID)
    );
    

    数据初始化data-h2.sql

    INSERT INTO `poet` (`id`, `name`)
    VALUES
    	(1, '李白'),
    	(2, '艾可翁'),
    	(3, '敖陶孙'),
    	(4, '安稹'),
    	(5, '艾性夫'),
    	(6, '奥敦周卿'),
    	(7, '安鏖'),
    	(8, '阿鲁威'),
    	(9, '安鸿渐'),
    	(10, '安邑坊女');
    

    我们接下来借助 maven 插件来初始化数据, pom.xml文件中,添加如下配置

    <!-- The H2 test schema is loaded here -->
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>sql-maven-plugin</artifactId>
    
        <executions>
            <execution>
                <id>create-database-h2</id>
                <phase>generate-sources</phase>
                <goals>
                    <goal>execute</goal>
                </goals>
            </execution>
        </executions>
    
        <configuration>
            <driver>org.h2.Driver</driver>
            <url>jdbc:h2:~/h2-jooq-db</url>
            <username>test</username>
            <password></password>
            <autocommit>true</autocommit>
            <srcFiles>
                <srcFile>src/main/resources/schema-h2.sql</srcFile>
                <srcFile>src/main/resources/data-h2.sql</srcFile>
            </srcFiles>
        </configuration>
    
        <dependencies>
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
                <version>1.4.200</version>
            </dependency>
        </dependencies>
    </plugin>
    

    如下图的 case,完成数据的初始化

    II. 体验 case

    在实际开始 jooq 的 curd 之前,需要先生成对应的表结构对象,这里也是借助 maven 插件来完成

    1. 代码自动生成

    同样在pom.xml中添加如下配置

    <plugin>
          <groupId>org.jooq</groupId>
          <artifactId>jooq-codegen-maven</artifactId>
    
          <executions>
              <execution>
                  <id>generate-h2</id>
                  <phase>generate-sources</phase>
                  <goals>
                      <goal>generate</goal>
                  </goals>
              </execution>
          </executions>
          <configuration>
              <jdbc>
                  <!-- 数据库相关配置 -->
                  <driver>org.h2.Driver</driver>
                  <url>jdbc:h2:~/h2-jooq-db</url>
                  <username>test</username>
                  <password></password>
              </jdbc>
              <generator>
                  <database>
                      <!-- 数据库的基本信息 -->
                      <name>org.jooq.meta.h2.H2Database</name>
                      <includes>.*</includes>
                      <excludes></excludes>
                      <inputSchema>PUBLIC</inputSchema>
                  </database>
                  <generate>
                      <deprecated>false</deprecated>
                      <instanceFields>true</instanceFields>
                      <pojos>true</pojos>
                  </generate>
                  <target>
                      <!-- 自动生成的类的包名,以及路径 -->
                      <packageName>com.git.hui.boot.jooq.h2</packageName>
                      <directory>src/main/java</directory>
                  </target>
              </generator>
          </configuration>
      </plugin>
    

    如上图的方式执行完毕之后,会得到生成的代码

    2. CURD

    接下来我们给出 CURD 的基本使用姿势

    import static com.git.hui.boot.jooq.h2.tables.Poet.POET;
    
    @Service
    public class PoetService {
    
        @Autowired
        DSLContext dsl;
    
        public int create(int id, String author) {
            return dsl.insertInto(POET).set(POET.ID, id).set(POET.NAME, author).execute();
        }
    
        public PoetRecord get(int id) {
            return dsl.selectFrom(POET).where(POET.ID.eq(id)).fetchOne();
        }
    
        public int update(int id, String author) {
            return dsl.update(POET).set(POET.NAME, author).where(POET.ID.eq(id)).execute();
        }
    
        public int delete(int id) {
            return dsl.delete(POET).where(POET.ID.eq(id)).execute();
        }
    
        public List<PoetRecord> getAll() {
            return dsl.selectFrom(POET).fetch();
        }
    }
    

    注意上面的使用,很好理解了,基本上能愉快的写 sql,就可以愉快的使用 jooq,上面的这种链式写法,对于 sql 的阅读是非常友好的;这里的重点是DSLContext,它是JooqAutoConfiguration自动加载的,这里直接拿来使用了(关于更多的配置与多数据源的问题,后面介绍)

    3. 测试 case

    在 pom 中引入web依赖,设计一些基本的测试 case

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

    增删改查 case

    @RestController
    public class PoetRest {
        @Autowired
        private PoetService poetService;
    
        @RequestMapping(path = "add")
        public int add(Integer id, String name) {
            return poetService.create(id, name);
        }
    
        @GetMapping(path = "get")
        public String get(Integer id) {
            PoetRecord record = poetService.get(id);
            return r2str(record);
        }
    
        @GetMapping(path = "list")
        public List<String> list() {
            List<PoetRecord> list = poetService.getAll();
            return list.stream().map(this::r2str).collect(Collectors.toList());
        }
    
    
        @GetMapping(path = "update")
        public int update(int id, String author) {
            return poetService.update(id, author);
        }
    
        @GetMapping(path = "del")
        public int delete(int id) {
            return poetService.delete(id);
        }
    
    
        private String r2str(PoetRecord record) {
            return record.getId() + " # " + record.getName();
        }
    }
    

    实测结果如下

    4. 小结

    到此,SpringBoot 集成 jooq 的 demo 已经完成,并提供了基础的 CURD,整体来看,集成比较简单,需要注意的是代码自动生成,我们这里是借助 maven 插件来实现代码自动生成的, 此外也可以通过官方提供的jooq-xx.jar + xml配置文件来自动生成;后面单独捞一篇博文给与介绍

    从 jooq 的使用姿势来看,最大的感官就是类 sql 的链式写法,比较的直观,阅读友好;此外需要注意的是自动生成的实体PoetRecord,不要暴露出去哦,一般推荐使用 jooq 包下面的Poet来代替PoetRecord来作为 BO 对象使用,可以通过RecordMapper来实现转换,如下

    public Poet getById(int id) {
        PoetRecord record = dsl.selectFrom(POET).where(POET.ID.eq(id)).fetchOne();
        RecordMapper<PoetRecord, Poet> mapper =
                dsl.configuration().recordMapperProvider().provide(POET.recordType(), POET.getClass());
        return mapper.map(record);
    }
    

    II. 其他

    0. 项目

    1. 一灰灰 Blog

    尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现 bug 或者有更好的建议,欢迎批评指正,不吝感激

    下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

    一灰灰blog

  • 相关阅读:
    小数据池以及深浅拷贝
    字典的初识,了解
    元组:认识,索引 切片
    列表的认识,嵌套,增删改查
    bool、字符串方法、for循环
    字符串格式化输出、while循环、运算符.
    Python的基础知识与历史应用
    git错误:error: failed to push some refs to 'https://...'
    golang中gin框架使用logrus
    golang中如何监控多个goroute协程是否执行完成
  • 原文地址:https://www.cnblogs.com/yihuihui/p/13677176.html
Copyright © 2011-2022 走看看