在一次學習分佈式跟蹤系統zipkin中,發現了jooq這個組件,當時不知這個組件是幹嗎的,後來抽空學習了一下,感受這個組件還挺用的。它主要有如下做用:java
經過DSL(Domain Specific Language )風格,利用Java代碼寫sql。 支持主流的RDMS和更多的特性,如self-joins,union,存儲過程,複雜的子查詢等。 提供GenerationTool,可以經過表結構自動生成代碼。 Flyway是一款開源的數據庫版本管理工具,它更傾向於規約優於配置的方式。Flyway能夠獨立於應用實現管理並跟蹤數據庫變動,支持數據庫版本自動升級。說直白一點,Flyway就是作數據庫版本控制的,在數據庫版本升級中頗有做用。mysql
下面開始講解整合的過程。web
一、pom.xml文件spring
其實整合的過程,大部分的工做都是在pom文件裏面完成,只要看懂了pom文件,整合過程基本上就明白了。pom文件以下:sql
org.springframework.boot spring-boot-starter-parent 2.0.2.RELEASE 4.0.0 com.swnote.jooq sw-jooq 0.0.1-SNAPSHOT jar sw-jooq maven.apache.org <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> org.springframework.boot spring-boot-starter-web 數據庫
org.springframework.boot spring-boot-starter-jooq org.jooq jooq-meta org.jooq jooq-codegen org.flywaydb flyway-core mysql mysql-connector-java org.apache.maven.plugins maven-compiler-plugin
1.8 1.8 org.springframework.boot spring-boot-maven-plugin repackage it.ozimov yaml-properties-maven-plugin 1.1.3 initialize read-project-properties src/main/resources/application.yml org.flywaydb flyway-maven-plugin generate-sources migrate ${spring.datasource.url} ${spring.datasource.username} ${spring.datasource.password} filesystem:src/main/resources/db/migration org.jooq jooq-codegen-maven jooq generate-sources generate ${spring.datasource.driverClassName} ${spring.datasource.url} ${spring.datasource.username} ${spring.datasource.password} org.jooq.util.mysql.MySQLDatabase .* true jooq false true true com.swnote.jooq.generator src/main/java mysql mysql-connector-java 5.1.46 src/main/java **/*.java src/main/resources 其中須要說明的幾個關鍵點:
yaml-properties-maven-plugin,該插件可使在pom文件中讀取到application.yml文件中的配置,這樣能夠避免一樣的配置有屢次配置的問題。 flyway-maven-plugin,該插件用於配置flyway,指定了創表的sql的位置爲src/main/resources/db/migration jooq-codegen-maven,配置了所鏈接的數據庫信息,模式名,以及自動生成的代碼的配置,好比要生成哪些代碼、將生成的代碼放在哪一個目錄中等。 二、基於Jooq的CURDapache
因爲Jooq支持經過Java代碼來寫sql的邏輯,爲此例子工程中沒有Dao層,sql的邏輯所有在Service層,Service層的代碼以下:架構
用戶信息服務接口:IUserServiceapp
package com.swnote.jooq.service; import java.util.List; import java.util.Map; import com.swnote.jooq.generator.tables.pojos.User; /**maven
用戶信息服務接口
@author lzj
@date [2019-03-10] / public interface IUserService { / *
建立用戶
@param user / void create(User user); / *
根據id刪除用戶
@param user_id / void delete(String user_id); / *
更新用戶
@param user */ void update(User user);
/**
根據id獲取用戶
@param user_id
@return / User retrieve(String user_id); / *
根據條件獲取用戶列表
@param params
@return */ List queryForList(Map<String, Object> params); } 用戶信息服務類:UserService
package com.swnote.jooq.service.impl; import static com.swnote.jooq.generator.tables.User.USER; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.jooq.DSLContext; import org.jooq.UpdateQuery; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.swnote.jooq.generator.tables.pojos.User; import com.swnote.jooq.generator.tables.records.UserRecord; import com.swnote.jooq.service.IUserService; /**
用戶信息服務類
@author lzj
@date [2019-03-10] */ @Transactional @Service public class UserService implements IUserService { @Autowired private DSLContext dsl; @Override public void create(User user) { // 構建insert語句 dsl.insertInto(USER, USER.USER_ID, USER.NAME, USER.INTRO) .values(user.getUserId(), user.getName(), user.getIntro()).execute(); } @Override public void delete(String user_id) { // 構建delete語句 dsl.delete(USER).where(USER.USER_ID.eq(user_id)).execute(); } @Override public void update(User user) { // 構建update語句 UpdateQuery update = dsl.updateQuery(USER); update.addValue(USER.NAME, user.getName()); update.addValue(USER.INTRO, user.getIntro()); update.addConditions(USER.USER_ID.eq(user.getUserId())); update.execute(); } @Transactional(propagation = Propagation.NOT_SUPPORTED) @Override public User retrieve(String user_id) { // 構建select語句 List users = dsl.select(USER.USER_ID, USER.NAME, USER.INTRO).from(USER).where(USER.USER_ID.eq(user_id)) .fetch().into(User.class);
if (users != null && !users.isEmpty()) { return users.get(0); } return null; } @Transactional(propagation = Propagation.NOT_SUPPORTED) @Override public List queryForList(Map<String, Object> params) { // 構建select語句 StringBuilder builder = new StringBuilder(); if (params != null) { for (Entry<String, Object> entry : params.entrySet()) { if (builder.length() == 0) { builder.append(entry.getKey()).append(" = ").append(entry.getValue()); } else { builder.append(" and ").append(entry.getKey()).append(" = ").append(entry.getValue()); } } }
List users = dsl.select(USER.USER_ID, USER.NAME, USER.INTRO).from(USER).where(builder.toString()).fetch().into(User.class); return users; } } 從上面的代碼能夠看到利用Jooq來寫sql的邏輯,也很簡單。
三、測試
Controller層代碼在此就不寫,感興趣的能夠個人GitHub中去看。在此經過PostMan測試Controller中暴露的REST接口。例如新增接口:
執行後,數據庫也就有了記錄,即:
微服務架構 - SpringBoot整合Jooq和Flyway