SpringBoot2.x系列教程46--整合使用jOOQ面向對象查詢

一. jOOQ簡介

1. jOOQ概述

jOOQ(Java Object Oriented Querying): 翻譯成中文是 Java面向對象查詢 的意思。

jOOQ是Data Geekery提供的基於Java的輕量級數據庫訪問庫,通過特定的語法將類以及數據庫模型翻譯成對應的SQL語句實現實體與關係的映射,在數據庫與類之間建立起一一對應關係,也可以讓我們通過它的流式API構建出類型安全的SQL查詢。

jOOQ是一個基於Java編寫SQL的工具包,具有簡單、輕量、函數式編程寫SQL等獨特優勢,非常適合敏捷快速迭代開發。

jOOQ不管是商業版,還是開源版本都能跟Spring Boot一塊使用。

2. jOOQ的特點:

  • 繼承了ORM框架的優點,簡單操作,類型安全等。jOOQ將SQL建模爲內部DSL,使用Java編譯器編譯SQL語法,元數據和數據類型。
  • jOOQ會根據數據庫的元數據來生成對應的實體類,省略了原有開發中不斷修改對應數據庫的類名,屬性名。
  • jOOQ允許運行時配置數據庫模式,且支持行級別的安全。
  • 支持聯合查詢,多表查詢,存儲過程等數據庫高級操作。

二. Spring Boot中整合jOOQ

1.創建Web項目

我們按照之前的經驗,創建一個web程序,並將之改造成Spring Boot項目,具體過程略。

2. 添加依賴和插件

<dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- 阿里巴巴fastjson,解析json視圖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.46</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jooq</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jooq</groupId>
            <artifactId>jooq-meta</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jooq</groupId>
            <artifactId>jooq-codegen</artifactId>
        </dependency>

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

</dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.jooq</groupId>
                <artifactId>jooq-codegen-maven</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>${mysql.version}</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <configurationFile>src/main/resources/JooqConfig.xml</configurationFile>
                </configuration>
        </plugin>
    </plugins>
</build>

3. 創建JooqConfig配置文件

在resource目錄下,創建一個JooqConfig.xml配置文件,用來進行關聯數據庫,根據數據庫進行逆向生成對應的Java代碼。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration>
    <jdbc>
        <driver>com.mysql.jdbc.Driver</driver>
        <url>jdbc:mysql://localhost:3306/db4?serverTimezone=GMT</url>
        <user>root</user>
        <password>syc</password>
    </jdbc>
    <generator>
        <!-- 代碼生成器 -->
        <!--<name>org.jooq.util.JavaGenerator</name>-->
        <name>org.jooq.codegen.JavaGenerator</name>
        <database>
            <!--下面這兩行是爲view也生成代碼的關鍵-->
            <!--force generating id'sfor everything in public schema, that has an 'id' field-->
            <syntheticPrimaryKeys>public\..*\.id</syntheticPrimaryKeys>
            <!--name for fake primary key-->
            <overridePrimaryKeys>override_primmary_key</overridePrimaryKeys>

            <!--<name>org.jooq.util.mysql.MySQLDatabase</name>-->
            <name>org.jooq.meta.mysql.MySQLDatabase</name>

            <!--include和exclude用於控制爲數據庫中哪些表生成代碼-->
            <includes>.*</includes>
            <!--<excludes></excludes>-->

            <!--數據庫名稱-->
            <inputSchema>db4</inputSchema>
        </database>

        <generate>
            <!--生成dao和pojo-->
            <daos>true</daos>
            <pojos>true</pojos>
            <!--把數據庫時間類型映射到java 8時間類型-->
            <javaTimeTypes>true</javaTimeTypes>
            <!--<interfaces>true</interfaces>-->
            <!--不在生成的代碼中添加spring註釋,比如@Repository-->
            <springAnnotations>false</springAnnotations>
        </generate>

        <target>
            <!--生成代碼文件的包名及放置目錄-->
            <packageName>com.yyg.boot.generator</packageName>
            <directory>src/main/java</directory>
        </target>
    </generator>
</configuration>

4. mvn執行逆向工程

在lifecycle中執行compile命令,就可以自動執行逆向工程的命令了。
只要JooqConfig.xml配置文件沒問題,並且依賴包都完整下載,就可以逆向工程執行成功。

逆向工程執行完畢後,我們就可以看到如下效果,發現自動生成了很多的Java代碼,這些Java代碼就是根據我們數據庫中的表,生成的對應的Java代碼。

對應的數據庫表:

5. 配置application.yml文件

主要是配置關聯我們的數據庫。

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db4?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
    type: com.alibaba.druid.pool.DruidDataSource
    username: root
    password: syc
    driver-class-name: com.mysql.jdbc.Driver #驅動
  jpa:
    hibernate:
      ddl-auto: update #自動更新
    show-sql: true  #日誌中顯示sql語句

6. 創建DataSource配置類

package com.yyg.boot.config;

import com.alibaba.druid.pool.DruidDataSource;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/3/30
 * @Description 第二種配置數據源的方式
 */
@Data
@ComponentScan
@Configuration
@ConfigurationProperties(prefix="spring.datasource")
public class DbConfig {

    private String url;
    private String username;
    private String password;

    @Bean
    public DataSource getDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

}

7.創建Service層代碼

創建UserService接口

package com.yyg.boot.service;

import com.yyg.boot.generator.tables.pojos.User;

import java.util.Iterator;
import java.util.List;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/4/2
 * @Description Description
 */
public interface UserService {

    /**
     * 刪除
     */
    void delete(int id);

    /**
     * 增加
     */
    void insert(User user);

    /**
     * 更新
     */
    int update(User user);

    /**
     * 查詢單個
     */
    User selectById(int id);

    /**
     * 查詢全部列表
     */
    List<User> selectAll(int pageNum, int pageSize);

}

創建UserServiceImpl類

package com.yyg.boot.service.impl;

import com.yyg.boot.generator.tables.User;
import com.yyg.boot.generator.tables.records.UserRecord;
import com.yyg.boot.service.UserService;
import org.jooq.DSLContext;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.UpdateSetMoreStep;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Iterator;
import java.util.List;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/4/2
 * @Description Description
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    DSLContext dsl;

    /**
     * 給User表 重命名 u 。(類似sql語句中的 user as u).
     * 注意一點,這個User類是逆向生成的tables包下的,不是pojos包下的User實體類。
     * (逆向工程它會生成兩個User類。一個在pojos下,一個再tables下)
     */
    com.yyg.boot.generator.tables.User u = User.USER.as("u");

    /**
     * 刪除
     */
    @Override
    public void delete(int id) {
        dsl.delete(u).where(u.ID.eq(id));
    }

    /**
     * 增加
     */
    @Override
    public void insert(com.yyg.boot.generator.tables.pojos.User user) {
        dsl.insertInto(u).
                columns(u.ADDRESS, u.BIRTHDAY, u.SEX, u.USERNAME).
                values(user.getAddress(), user.getBirthday(), user.getSex(), user.getUsername())
                .execute();
    }

    /**
     * 更新
     *
     * @param user
     */
    @Override
    public int update(com.yyg.boot.generator.tables.pojos.User user) {
        dsl.update(u).set((Record) user);
        return 0;
    }

    /**
     * 查詢單個
     */
    @Override
    public com.yyg.boot.generator.tables.pojos.User selectById(int id) {
        List<com.yyg.boot.generator.tables.pojos.User> result =  dsl.select(u.ADDRESS,u.BIRTHDAY,u.ID,u.SEX,u.USERNAME)
                .from(u)
                .where(u.ID.eq(id))
                .fetch()
                .into(com.yyg.boot.generator.tables.pojos.User.class);

        return result.get(0);
    }

    /**
     * 查詢全部列表
     */
    @Override
    public List<com.yyg.boot.generator.tables.pojos.User> selectAll(int pageNum, int pageSize) {
        return dsl.select()
                .from(u)
                //id倒序
                .orderBy(u.ID.desc())
                //分頁
                .limit(0)
                //分頁
                .offset(10)
                .fetch()
                //數據類型格式轉化
                .into(com.yyg.boot.generator.tables.pojos.User.class);
    }

}

8. 創建Controller測試接口

package com.yyg.boot.web;

import com.yyg.boot.generator.tables.pojos.User;
import com.yyg.boot.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/4/2
 * @Description Description
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public User findUserById(@PathVariable("id") Integer id) {
        return userService.selectById(id);
    }

}

9. 創建入口類

package com.yyg.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/4/2
 * @Description Description
 */
@SpringBootApplication
public class JooqApplication {

    public static void main(String[] args){
        SpringApplication.run(JooqApplication.class,args);
    }

}

10.總的項目結構

11.測試接口

我們在瀏覽器中進行測試。

可以看到我們的接口功能已經實現了,其他方法沒有一一測試,感興趣的朋友可以自己試驗一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章