1. 程式人生 > >Guice進階之整合mybatis和druid

Guice進階之整合mybatis和druid

上一篇文章中介紹了guice的基本使用配置,關於guice和spring的對比可以自行baidu或者google,我所瞭解的guice只是實現了依賴注入,而且相對於spring來說周邊生態還是比較弱的,所以我把guice定義為一個輕量級依賴注入框架,由於guice非常小且速度快,對於我們快速開發一些小型專案是非常適合的。

接下來隊guice+mybatis簡單整合下,實現對資料的查詢

專案結構如下:

首先pom中新增相關依賴

<!-- https://mvnrepository.com/artifact/com.google.inject/guice -->
        <dependency>
            <groupId>com.google.inject</groupId>
            <artifactId>guice</artifactId>
            <version>4.2.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-guice -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-guice</artifactId>
            <version>3.10</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.45</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.9</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.7.RELEASE</version>
        </dependency>

配置檔案(app.properties)

#dev
#jdbc
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://10.0.2.30:3306/xxx_test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=true&zeroDateTimeBehavior=convertToNull
jdbc.username=test
jdbc.password=test
jdbc.filters=stat,wall
jdbc.maxActive=20
jdbc.initialSize=5
jdbc.maxWait=60000
jdbc.minIdle=10
jdbc.timeBetweenEvictionRunsMillis=60000
jdbc.minEvictableIdleTimeMillis=300000
jdbc.validationQuery=SELECT 1
jdbc.testWhileIdle=true
jdbc.testOnBorrow=false
jdbc.testOnReturn=false
jdbc.maxOpenPreparedStatements=20
jdbc.removeAbandoned=true
jdbc.removeAbandonedTimeout=1800
jdbc.logAbandoned=true

#web redis
redis.database=0
#redis host & port
redis.host=10.0.2.13
redis.port=6379
redis.password=
#連線池最大連線數(使用負值表示沒有限制)
redis.pool.max.active=1000
# 連線池中的最大空閒連線
redis.pool.max.idle=100
#連線池最大阻塞等待時間(使用負值表示沒有限制)
redis.pool.max.wait=-1
# 連線池中的最小空閒連線
redis.pool.min.idle=0
# 連線超時時間(毫秒)
redis.timeout=0

mybatis.environment.id = scheduled-task

新建自定義資料來源provider(當然可以使用guice已註冊好的資料來源)我這裡使用的自定義的alibaba的druid資料來源

package com.yingda.xsignal.scheduled.provider;

import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.name.Named;

import com.alibaba.druid.pool.DruidDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

/**
 * @author xiaofeng
 * @version V1.0
 * @title: DruidDataSourceProvider
 * @package: com.yingda.xsignal.scheduled.provider
 * @description: Provides the Druid DataSource
 * @date 2018/6/26 16:46
 */
public class DruidDataSourceProvider implements Provider<DataSource> {

    Logger logger = LoggerFactory.getLogger(getClass());

    DruidDataSource dataSource = new DruidDataSource();

    @Inject
    public void setDriverClassName(@Named("jdbc.driverClassName") final String driverClassName) {
        dataSource.setDriverClassName(driverClassName);
    }

    @Inject
    public void setUrl(@Named("jdbc.url") final String url) {
        dataSource.setUrl(url);
    }

    @Inject
    public void setUsername(@Named("jdbc.username") final String username) {
        dataSource.setUsername(username);
    }

    @Inject
    public void setPassword(@Named("jdbc.password") final String password) {
        dataSource.setPassword(password);
    }

    @Inject(optional = true)
    public void setDefaultAutoCommit(@Named("jdbc.autoCommit") final boolean defaultAutoCommit) {
        dataSource.setDefaultAutoCommit(defaultAutoCommit);
    }

    @Inject(optional = true)
    public void setDefaultReadOnly(@Named("jdbc.readOnly") final boolean defaultReadOnly) {
        dataSource.setDefaultReadOnly(defaultReadOnly);
    }

    @Inject(optional = true)
    public void setDefaultTransactionIsolation(
            @Named("jdbc.transactionIsolation") final int defaultTransactionIsolation) {
        dataSource.setDefaultTransactionIsolation(defaultTransactionIsolation);
    }

    @Inject(optional = true)
    public void setDefaultCatalog(@Named("jdbc.catalog") final String defaultCatalog) {
        dataSource.setDefaultCatalog(defaultCatalog);
    }

    @Inject(optional = true)
    public void setMaxActive(@Named("jdbc.maxActive") final int maxActive) {
        dataSource.setMaxActive(maxActive);
    }

    @Inject(optional = true)
    public void setMinIdle(@Named("jdbc.minIdle") final int minIdle) {
        dataSource.setMinIdle(minIdle);
    }

    @Inject(optional = true)
    public void setInitialSize(@Named("jdbc.initialSize") final int initialSize) {
        dataSource.setInitialSize(initialSize);
    }

    @Inject(optional = true)
    public void setMaxWait(@Named("jdbc.maxWait") final long maxWait) {
        dataSource.setMaxWait(maxWait);
    }

    @Inject(optional = true)
    public void setTestOnBorrow(@Named("jdbc.testOnBorrow") final boolean testOnBorrow) {
        dataSource.setTestOnBorrow(testOnBorrow);
    }

    @Inject(optional = true)
    public void setTestOnReturn(@Named("jdbc.testOnReturn") final boolean testOnReturn) {
        dataSource.setTestOnReturn(testOnReturn);
    }

    @Inject(optional = true)
    public void setTimeBetweenEvictionRunsMillis(
            @Named("jdbc.timeBetweenEvictionRunsMillis") final long timeBetweenEvictionRunsMillis) {
        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
    }

    @Inject(optional = true)
    public void setMinEvictableIdleTimeMillis(
            @Named("jdbc.minEvictableIdleTimeMillis") final long minEvictableIdleTimeMillis) {
        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
    }

    @Inject(optional = true)
    public void setTestWhileIdle(@Named("jdbc.testWhileIdle") final boolean testWhileIdle) {
        dataSource.setTestWhileIdle(testWhileIdle);
    }

    @Inject(optional = true)
    public void setValidationQuery(@Named("jdbc.validationQuery") final String validationQuery) {
        dataSource.setValidationQuery(validationQuery);
    }

    @Inject(optional = true)
    public void setValidationQueryTimeout(@Named("jdbc.validationQueryTimeout") final int validationQueryTimeout) {
        dataSource.setValidationQueryTimeout(validationQueryTimeout);
    }

    @Inject(optional = true)
    public void setAccessToUnderlyingConnectionAllowed(
            @Named("jdbc.accessToUnderlyingConnectionAllowed") final boolean accessToUnderlyingConnectionAllowed) {
        dataSource.setAccessToUnderlyingConnectionAllowed(accessToUnderlyingConnectionAllowed);
    }

    @Inject(optional = true)
    public void setRemoveAbandoned(@Named("jdbc.removeAbandoned") final boolean removeAbandoned) {
        dataSource.setRemoveAbandoned(removeAbandoned);
    }

    @Inject(optional = true)
    public void setRemoveAbandonedTimeout(@Named("jdbc.removeAbandonedTimeout") final int removeAbandonedTimeout) {
        dataSource.setRemoveAbandonedTimeout(removeAbandonedTimeout);
    }

    @Inject(optional = true)
    public void setLogAbandoned(@Named("jdbc.logAbandoned") final boolean logAbandoned) {
        dataSource.setLogAbandoned(logAbandoned);
    }

    @Inject(optional = true)
    public void setPoolPreparedStatements(@Named("jdbc.poolPreparedStatements") final boolean poolPreparedStatements) {
        dataSource.setPoolPreparedStatements(poolPreparedStatements);
    }

    @Inject(optional = true)
    public void setMaxOpenPreparedStatements(
            @Named("jdbc.maxOpenPreparedStatements") final int maxOpenPreparedStatements) {
        dataSource.setMaxOpenPreparedStatements(maxOpenPreparedStatements);
    }

    @Inject(optional = true)
    public void setConnectProperties(@Named("jdbc.connectProperties") final Properties connectionProperties) {
        dataSource.setConnectProperties(connectionProperties);
    }

    @Inject(optional = true)
    public void setConnectionProperties(@Named("jdbc.connectionProperties") final String connectionProperties) {
        dataSource.setConnectionProperties(connectionProperties);
    }

    @Inject(optional = true)
    public void setFilters(@Named("jdbc.filters") final String filters) throws SQLException {
        dataSource.setFilters(filters);
    }

    @Inject(optional = true)
    public void setExceptionSorter(@Named("jdbc.exceptionSorter") final String exceptionSorter) throws SQLException {
        dataSource.setExceptionSorter(exceptionSorter);
    }

    @Inject(optional = true)
    public void setExceptionSorterClassName(@Named("jdbc.exceptionSorterClassName") final String exceptionSorterClassName)
            throws Exception {
        dataSource.setExceptionSorterClassName(exceptionSorterClassName);
    }

    @Override
    public String toString() {
        return "DruidDataSourceProvider{" +
                "jdbc.url=" + dataSource.getUrl() +
                ",username='" + dataSource.getUsername() +
                '}';
    }

    @Override
    public DataSource get() {
        logger.info("dataSource config ---> " + toString());
        return dataSource;
    }

}

新建module用於依賴繫結

package com.yingda.xsignal.scheduled.module;

import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
import com.google.inject.name.Names;
import com.yingda.xsignal.scheduled.dao.ExtraScoreInfoMapper;
import com.yingda.xsignal.scheduled.provider.DruidDataSourceProvider;
import com.yingda.xsignal.scheduled.provider.MasterRedisClientProvider;
import com.yingda.xsignal.scheduled.provider.RedisExtendClientProvider;
import com.yingda.xsignal.scheduled.redis.MasterRedisExtendClient;
import com.yingda.xsignal.scheduled.service.DbQueryService;
import com.yingda.xsignal.scheduled.service.DispathResourceService;
import com.yingda.xsignal.scheduled.service.impl.DbQueryServiceImpl;
import com.yingda.xsignal.scheduled.service.impl.DispathResourceServiceImpl;
import com.yingda.xsignal.scheduled.util.PropertyUtil;
import com.yingda.xsignal2.util.redis.RedisExtendClient;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.mybatis.guice.MyBatisModule;

/**
 * @author xiaofeng
 * @version V1.0
 * @title: MybatisModule
 * @package: com.yingda.xsignal.scheduled.module
 * @description: TODO
 * @date 2018/6/26 18:24
 */
public class ScheduledModule extends AbstractModule {
    private String file = "config/app.properties";

    @Override
    protected void configure() {
        Names.bindProperties(binder(), PropertyUtil.loadFile(file, getClass()));
        bind(DbQueryService.class).to(DbQueryServiceImpl.class);
        this.install(new MyBatisModule() {
            @Override
            protected void initialize() {
                //繫結我們自定義的資料來源provider,也可以使用guice已經編寫好的
                bindDataSourceProviderType(DruidDataSourceProvider.class);
                bindTransactionFactoryType(JdbcTransactionFactory.class);
                //新增我們的mapper介面,可以按類注入(即通過類名注入),也可以指定整個包的路徑
//                addMapperClass(ExtraScoreInfoMapper.class);
                addMapperClasses("com.yingda.xsignal.scheduled.dao");
            }
        });
    }
}

新建mapper(dao),用於查詢資料庫表

package com.yingda.xsignal.scheduled.dao;


import com.yingda.xsignal.scheduled.model.ScoreInfo;
import org.apache.ibatis.annotations.Select;

import java.util.List;
import java.util.Map;
/**
  * @author xiaofeng
  * @version V1.0
  * @title: ExtraScoreInfoMapper
  * @package: com.yingda.xsignal.scheduled.dao
  * @description: 使用者積分mapper
  * @date 2018/6/27 15:59
  */
public interface ExtraScoreInfoMapper {
    /**
     * 根據更新時間查詢積分資訊
     *
     * @param params
     * @return
     */
    @Select("<script> " +
            "SELECT id, user_id, company_id, current_point, recharge_point, present_point, profit_point, " +
            "    invite_point, share_point, blocking_point, recharge_deposit, present_deposit, profit_deposit, " +
            "    invite_deposit, share_deposit, update_time, create_time, create_by, update_by, remark " +
            "FROM tb_score_info " +
            "WHERE 1=1 " +
            "<if test='date!=null'> " +
            "AND UNIX_TIMESTAMP(update_time) &gt; UNIX_TIMESTAMP(#{date}) " +
            "</if> " +
            "</script>")
    List<ScoreInfo> selectListByUpdateTime(Map<String, Object> params);

}

service實現

package com.yingda.xsignal.scheduled.service.impl;

import com.google.inject.Inject;
import com.yingda.xsignal.scheduled.dao.ExtraScoreInfoMapper;
import com.yingda.xsignal.scheduled.model.ScoreInfo;
import com.yingda.xsignal.scheduled.service.DbQueryService;

import java.util.List;
/**
  * @author xiaofeng
  * @version V1.0
  * @title: DbQueryServiceImpl
  * @package: com.yingda.xsignal.scheduled.service.impl
  * @description: TODO
  * @date 2018/6/28 11:16
  */
public class DbQueryServiceImpl implements DbQueryService {

    @Inject
    ExtraScoreInfoMapper extraScoreInfoMapper;

    @Override
    public List<ScoreInfo> queryList() {
        return extraScoreInfoMapper.selectListByUpdateTime(null);
    }
}

主函式入口

package com.yingda.xsignal.scheduled;

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.yingda.xsignal.scheduled.model.ScoreInfo;
import com.yingda.xsignal.scheduled.module.ScheduledModule;
import com.yingda.xsignal.scheduled.service.DbQueryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * @author xiaofeng
 * @version V1.0
 * @title: TaskWorkerApplication
 * @package: com.yingda.xsignal.task
 * @description: scheduled task
 * @date 2018/6/26 14:54
 */
public class TaskWorkerApplication {

    private Logger logger = LoggerFactory.getLogger(getClass());
    private Injector injector;
    private DbQueryService queryService;

    private TaskWorkerApplication() {
        logger.info("init something......");
        injector = Guice.createInjector(new ScheduledModule());
        queryService = injector.getInstance(DbQueryService.class);
    }

    private void run() {
        logger.info("doing something......");
        queryService.queryList()

    }

    public static void main(String[] args) {
        TaskWorkerApplication taskWorkerApplication = new TaskWorkerApplication();
        try {
            taskWorkerApplication.run();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

右鍵執行即可!至此,我們已成整合了guice + mybatis 包括redis,已滿足專案的基本開發!