mybatis-redisプロジェクト分析

4953 ワード

[オリジナル文章、転載は元の文章の住所を明記してください、ありがとうございます!]
redisは現在最も優れたkey-valueデータベースとして、プロジェクトのキャッシュサービスを提供するのに適しています.redisをmybatisのクエリーキャッシュとして使用するのも一般的です.ネット上でNの多くの人が自分で作ったCacheであることを発見して、実はmybatisのgitの下で1つのサブプロジェクトmybatis-redisがあります;このプロジェクトはmybatisクエリーキャッシュの実装としてredisを提供しています.次に、このプロジェクトの実装原理を分析し、いくつかのプロジェクトの問題を提出します.

コード実装##


このプロジェクトは、Mybatisを実装する一般的なキャッシュスキームと大きく異なり、Cacheインタフェースを実装し、jedisを使用してキャッシュを操作することにほかならない.しかし、このプロジェクトは設計の細部にいくつかの違いがあります.次に、ソースコードを簡単に分析します.
public final class RedisCache implements Cache {  
public RedisCache(final String id) {
  if (id == null) {
  throw new IllegalArgumentException("Cache instances require an ID");
}
this.id = id;
RedisConfig redisConfig = RedisConfigurationBuilder.getInstance().parseConfiguration();
pool = new JedisPool(redisConfig, redisConfig.getHost(), redisConfig.getPort(),
        redisConfig.getConnectionTimeout(), redisConfig.getSoTimeout(), redisConfig.getPassword(),
        redisConfig.getDatabase(), redisConfig.getClientName());
}  

RedisCacheはmybatisが起動したとき、MyBatisのCacheBuilderによって作成され、作成方法は簡単で、RedisCacheを呼び出すStringパラメータ付きの構造方法、すなわちRedisCache(String id)である.一方、RedisCacheの構築方法では、RedisConfigurationBuilderを呼び出してRedisConfigオブジェクトを作成し、RedisConfigを使用してJedisPoolを作成します.RedisConfigクラスはJedisPoolConfigを継承し、host、portなどのプロパティのパッケージを提供しています.RedisConfigのプロパティを簡単に見てください.
public class RedisConfig extends JedisPoolConfig {

private String host = Protocol.DEFAULT_HOST;
private int port = Protocol.DEFAULT_PORT;
private int connectionTimeout = Protocol.DEFAULT_TIMEOUT;
private int soTimeout = Protocol.DEFAULT_TIMEOUT;
private String password;
private int database = Protocol.DEFAULT_DATABASE;
private String clientName;
}

RedisConfigオブジェクトはRedisConfigurationBuilderによって作成されます.このクラスの主な方法を簡単に見てください.
public RedisConfig parseConfiguration(ClassLoader classLoader) {
    Properties config = new Properties();

    InputStream input = classLoader.getResourceAsStream(redisPropertiesFilename);
    if (input != null) {
        try {
            config.load(input);
        } catch (IOException e) {
            throw new RuntimeException(
                    "An error occurred while reading classpath property '"
                            + redisPropertiesFilename
                            + "', see nested exceptions", e);
        } finally {
            try {
                input.close();
            } catch (IOException e) {
                // close quietly
            }
        }
    }

    RedisConfig jedisConfig = new RedisConfig();
    setConfigProperties(config, jedisConfig);
    return jedisConfig;
}

コアメソッドは、classpathからredisを読み出すparseConfigurationメソッドである.propertiesファイル:
host=localhost
port=6379
connectionTimeout=5000
soTimeout=5000
password=
database=0
clientName=

プロファイルの内容をRedisConfigオブジェクトに設定し、返します.次に、RedisCacheがRedisConfigクラスを使用してJedisPoolの作成を完了します.RedisCacheでは、Redisを操作するための簡単なテンプレート方法が実装されています.
private Object execute(RedisCallback callback) {
Jedis jedis = pool.getResource();
try {
  return callback.doWithRedis(jedis);
} finally {
  jedis.close();
}
}

テンプレートインタフェースはRedisCallbackであり、このインタフェースではdoWithRedisメソッドを実装する必要があります.
public interface RedisCallback {
    Object doWithRedis(Jedis jedis);
}

次にCacheで最も重要な2つの方法:putObjectとgetObjectを見て、mybatis-redisがデータを格納するフォーマットを表示します.
@Override
public void putObject(final Object key, final Object value) {
execute(new RedisCallback() {
  @Override
  public Object doWithRedis(Jedis jedis) {
    jedis.hset(id.toString().getBytes(), key.toString().getBytes(), SerializeUtil.serialize(value));
    return null;
  }
});
}

@Override
public Object getObject(final Object key) {
return execute(new RedisCallback() {
  @Override
  public Object doWithRedis(Jedis jedis) {
    return SerializeUtil.unserialize(jedis.hget(id.toString().getBytes(), key.toString().getBytes()));
  }
});
}

mybatis-redisはデータを格納する際に用いられるhash構造であり、cacheのidをこのhashのkey(cacheのidはmybatisではmapperのnamespace)とする.このmapperのクエリーキャッシュデータはhashのfieldとして、キャッシュする必要がある内容は直接SerializeUtilストレージを使用し、SerializeUtilとその他のシーケンス化クラスの差は多くなく、オブジェクトのシーケンス化と逆シーケンス化を担当する.

使用方法##


mybatis-redis全体のキーコードはこれだけで、コードの分析を通じて、mybatis-redisの使用方法を簡単に得ることができます:1、プロジェクトにredisを追加します.properties構成;2、直接mapperで使えばいい.

解析##


コードを使用すると、実際のアプリケーションで発生する可能性のあるいくつかの問題を見ることができます.
  • のデフォルトでは、mybatisはmapperごとにRedisCacheを作成します.JedisPoolはRedisCacheの構造方法で作成されます.これは、mapperごとにJedisPoolを作成し、使用意図とオーバーヘッドに問題があることを意味します.
  • 多くの場合、私たちのアプリケーションでも独立してredisを使用します.これにより、RedisCacheが私たちのプロジェクトに存在する可能性のあるJedisPoolを直接使用することはできません.2つのプロファイルが作成されます(redis.propertiesも使用しない限り).
  • RedisCacheはhashを使用してMapperのクエリーをキャッシュするので、mybatisのcache構成でオブジェクトの生存時間、空き時間などの属性を制御するしかありません.各キャッシュ領域(すなわち、各hash)を独立して構成することはできない.