Jooq新手在SpringBoot中接入Jooq

参考:https://segmentfault.com/a/1190000006748584?utm_source=tuicool&utm_medium=referral

JOOQ是啥

  JOOQ 是基于Java访问关系型数据库的工具包。JOOQ 既吸取了传统ORM操作数据的简单性和安全性,又保留了原生sql的灵活性,它更像是介于 ORMS和JDBC的中间层。对于喜欢写sql的码农来说,JOOQ可以完全满足你控制欲,可以是用Java代码写出sql的感觉来。就像官网说的那样 :

get back in control of your sql

1.Springboot整合jooq首先加入jar包依赖



    mysql
    mysql-connector-java
    5.1.41


    com.zaxxer
    HikariCP
    2.6.2


    org.jooq
    jooq
    3.9.1
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/modeo?useUnicode=true&characterEncoding=UTF-8&useSSL=false
    username: modeo
    password: 123456

2.在项目根目录下建立一个文件夹generator目录下加入以下jar包以及建立mysql.xml(一会用到)

Jooq新手在SpringBoot中接入Jooq_第1张图片

3.编辑mysql.xml文件

 
  
xml version="1.0" encoding="UTF-8" standalone="yes"?>
xmlns="http://www.jooq.org/xsd/jooq-codegen-3.8.0.xsd">


    com.mysql.jdbc.Driver
    jdbc:mysql://localhost:3306/admin
    root
    123456


    
    org.jooq.util.JavaGenerator
    
        
        org.jooq.util.mysql.MySQLDatabase
        
        admin
        
        .*
        
        
    
    
        
        org.test.jooq.generated
        
        src/main/java/
    


    
        
            
                                    ^(.*)$
                    
                        PASCAL
                        $1
                    
                    
                        PASCAL
                        $1_P_O
                    
                

4.创建MysqlManager数据库操作工具

public class MysqlManager implements Closeable {
    private static final String DB_DRIVER_NAME = "spring.datasource.driver-class-name";
    private static final String DB_URL = "spring.datasource.url";
    private static final String DB_USERNAME = "spring.datasource.username";
    private static final String DB_PASSWORD = "spring.datasource.password";

    /**
     * Singleton
     */
    private static final MysqlManager INSTANCE = new MysqlManager();

    /**
     * database configuration
     */
    private Configuration configuration = null;
    /**
     * database source
     */
    private HikariDataSource dataSource = null;

    /**
     * get DSL context
     *
     * @return DSLContext
     */
    public DSLContext getContext() {
        return DSL.using(this.configuration);
    }

    /**
     * Constructor
     */
    private MysqlManager() {
        this.dataSource = new HikariDataSource();

        this.dataSource.setDriverClassName(Config.getProperty(DB_DRIVER_NAME));
        this.dataSource.setJdbcUrl(Config.getProperty(DB_URL));
        this.dataSource.setUsername(Config.getProperty(DB_USERNAME));
        this.dataSource.setPassword(Config.getProperty(DB_PASSWORD));

        // 设置连接池的最大/最小 size
        this.dataSource.addDataSourceProperty("maxConnectionsPerPartition", "5");
        this.dataSource.addDataSourceProperty("minConnectionsPerPartition", "1");
        this.dataSource.addDataSourceProperty("idleConnectionTestPeriodInMinutes", "10");
        this.dataSource.addDataSourceProperty("maxConnectionAgeInSeconds", "3600");
        this.dataSource.addDataSourceProperty("idleMaxAgeInMinutes", "300");
        this.dataSource.addDataSourceProperty("cachePrepStmts", "true");
        this.dataSource.addDataSourceProperty("prepStmtCacheSize", "250");
        this.dataSource.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
        this.dataSource.addDataSourceProperty("connectionTimeout", "3000");

        TransactionAwareDataSourceProxy proxy = new TransactionAwareDataSourceProxy(this.dataSource);
        DataSourceTransactionManager txMgr = new DataSourceTransactionManager(this.dataSource);
        this.configuration = new DefaultConfiguration().set(new DataSourceConnectionProvider(proxy))
                .set(new SpringTransactionProvider(txMgr)).set(SQLDialect.MYSQL);
    }

    /**
     * Singleton
     *
     * @return instance
     */
    public static MysqlManager getInstance() {
        return INSTANCE;
    }

    /**
     * transaction
     *做事物处理时用
     * @param runnable
     */
    public static void transaction(Runnable runnable) {
        DSLContext context = MysqlManager.getInstance().getContext();
        context.transaction(config -> runnable.run());
    }

    /**
     * Closes this stream and releases any system resources associated
     * with it. If the stream is already closed then invoking this
     * method has no effect.
     *
     * 

As noted in {@link AutoCloseable#close()}, cases where the * close may fail require careful attention. It is strongly advised * to relinquish the underlying resources and to internally * mark the {@code Closeable} as closed, prior to throwing * the {@code IOException}. * * @throws IOException if an I/O error occurs */ @Override public void close() throws IOException { if (this.dataSource != null && !this.dataSource.isClosed()) { this.dataSource.close(); this.dataSource = null; } this.configuration = null; } }

5.在linux系统下在创建的generator目录下运行以下命令就会生成数据库表对应的操作对象(在mysql.xml配置的路径下)

cd generator
java -classpath jooq-3.9.1.jar:jooq-meta-3.9.1.jar:jooq-codegen-3.9.1.jar:mysql-connector-java-5.1.41.jar:. org.jooq.util.GenerationTool mysql.xml

6.具体的数据库操作案例:

(1.)使用事物处理

private static boolean removeSubscribedSymbol(String deviceId, List exchangeSymbols) {
    if (exchangeSymbols == null || exchangeSymbols.isEmpty()) {
        return true;
    }

    DSLContext context = MysqlManager.getInstance().getContext();
    GuestSubscribeMarket table = GuestSubscribeMarket.GUEST_SUBSCRIBE_MARKET;
    MysqlManager.transaction(() -> {
        for (MarketSymbolVO item : exchangeSymbols) {
            context.deleteFrom(table).where(table.DEVICE_ID.eq(deviceId), table.TYPE.eq(item.getType()),
                    table.TARGET_ID.eq(item.getId())).execute();
        }
    });

    return true;
}

(2)一般的操作

public static boolean hasSubscribedSymbol(String deviceId) {
    DSLContext context = MysqlManager.getInstance().getContext();
    GuestSubscribeMarket table = GuestSubscribeMarket.GUEST_SUBSCRIBE_MARKET;

    return context.selectFrom(table).where(table.DEVICE_ID.eq(deviceId)).fetchAny() != null;
}

(3)jooq支持纯sql的模式

/**
 * @param period
 * @param coinId
 * @return
 */
public static List listCoinKlineDO(String period, int coinId) {
    DSLContext context = MysqlManager.getInstance().getContext();
    LocalDate localDate = LocalDate.now(ZoneId.of("GMT"));
    Date now = Date.valueOf(localDate);
    String sql =
            "select * from " + DEFAULT_COIN_KLINE_TABLE + period + " where `coin_id` = ? and `date` <= ? order " +
                    "by `date` desc limit 240";
    List records = context.fetch(sql, coinId, now);

    return records.stream().map(record -> {
        CoinKlineDO item = new CoinKlineDO();
        item.setAmount((String) record.getValue("amount"));
        item.setOpen((String) record.getValue("open"));
        item.setHigh((String) record.getValue("high"));
        item.setLow((String) record.getValue("low"));
        item.setClose((String) record.getValue("close"));
        item.setTime(((Date) record.getValue("date")).getTime());
        return item;
    }).collect(Collectors.toList());
}
/**
 * add record
 *
 * @param table
 * @param pairId
 * @param item
 * @return
 */
public static boolean addRecord(String table, int pairId, MarketKlineDO item) {
    DSLContext context = MysqlManager.getInstance().getContext();

    InsertQuery query = context.insertQuery(DSL.table(table));
    query.addValue(DSL.field("`pair_id`", Integer.class), pairId);
    query.addValue(DSL.field("`time`", Timestamp.class), new Timestamp(item.getTime()));
    query.addValue(DSL.field("`open`", String.class), item.getOpen());
    query.addValue(DSL.field("`high`", String.class), item.getHigh());
    query.addValue(DSL.field("`low`", String.class), item.getLow());
    query.addValue(DSL.field("`close`", String.class), item.getClose());
    query.addValue(DSL.field("`amount`", String.class), item.getAmount());
    query.addValue(DSL.field("`create_at`", Timestamp.class), new Timestamp(System.currentTimeMillis()));

    return query.execute() > 0;
}
/**
 * add record
 *
 * @param table
 * @param pairId
 * @param items
 * @return
 */
public static boolean addRecords(String table, int pairId, List items) {
    final boolean[] addRet = {true};
    MysqlManager.transaction(() -> {
        for (MarketKlineDO item : items) {
            boolean ret = addRecord(table, pairId, item);
            if (!ret) {
                addRet[0] = false;
                break;
            }
        }
    });

    return addRet[0];
}

你可能感兴趣的:(java资源,jooq入门新手,springboot)