All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nbcp.myoql.annotation.FromRedisCache.kt Maven / Gradle / Ivy

The newest version!
package nbcp.myoql.annotation

import nbcp.base.comm.config
import nbcp.base.extend.*
import nbcp.base.extend.*
import nbcp.base.extend.*
import nbcp.base.extend.*
import nbcp.base.utils.Md5Util
import nbcp.base.utils.SpringUtil
import nbcp.myoql.db.cache.CacheKeySpelExecutor
import org.slf4j.LoggerFactory
import org.springframework.data.redis.core.StringRedisTemplate
import java.lang.annotation.Inherited
import java.time.Duration
import java.util.function.Supplier
import kotlin.reflect.KClass

/**
 * Sql Select Cache
 */
@Inherited
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class FromRedisCache constructor(
    /**
     * 如果 table 为空,则使用 table = tableClass.name
     */
    val tableClass: KClass<*> = Void::class,

    /**
     * 缓存关联表
     */
    val joinTableClasses: Array> = arrayOf(),

    /**
     * 缓存表的隔离键或主键, 如:"cityCode"
     */
    val groupKey: String = "",
    /**
     * 缓存表的隔离值,如: "010",如果使用参数变量,使用 # 开头
     */
    val groupValue: String = "",

    /**
     * 唯一值
     */
    val sql: String = "",

    val cacheSeconds: Int = 3600,
    /**
     * 缓存表
     */
    val table: String = "",
    /**
     * 缓存关联表
     */
    val joinTables: Array = arrayOf(),
) {
    companion object {
        internal val logger = LoggerFactory.getLogger(FromRedisCache::class.java)
    }
}


fun FromRedisCache.getTableName(): String {
    if (this.table.HasValue) return this.table;

    if (this.tableClass == Void::class) {
        throw RuntimeException("需要指定 主表!")
    }

    return this.tableClass.java.simpleName;
}

fun FromRedisCache.getJoinTableNames(): Array {
    var joinTables = this.joinTables;
    if (joinTables.any()) {
        return joinTables;
    }

    return this.joinTableClasses.map { it.simpleName!! }.toTypedArray()
}

/**
 * 解析变量
 */
fun FromRedisCache.resolveWithVariable(variableMap: Map, sql: String = ""): FromRedisCache {
    val spelExecutor = CacheKeySpelExecutor(variableMap);
    return FromRedisCache(
        Void::class,
        arrayOf(),
        spelExecutor.getVariableValue(this.groupKey),
        spelExecutor.getVariableValue(this.groupValue),
        spelExecutor.getVariableValue(sql.AsString(this.sql)),
        this.cacheSeconds,
        spelExecutor.getVariableValue(this.getTableName()),
        this.getJoinTableNames()
    )
}


/**
 * 缓存数据源,使用系统固定的数据库,不涉及分组及上下文切换。
 */
private val redisTemplate by lazy {
    return@lazy SpringUtil.getBean()
}

/**
 * sc=sqlcache
 * sc:查询主表/连接表1/连接表2/连接表3/?查询主表隔离键=查询主表隔离键值@md5
 */
fun FromRedisCache.getCacheKey(): String {
    val cache = this;
    val ret = mutableListOf();
    ret.add("sc:")
    ret.add(cache.table);
    ret.add("/")

    if (cache.joinTables.any()) {
        ret.add(
            cache.joinTables.toSortedSet().map { it + "/" }.joinToString("")
        )
    }

    if (cache.groupKey.HasValue && cache.groupValue.HasValue) {
        ret.add("?${cache.groupKey}=${cache.groupValue}")
    }

    ret.add("@")
    ret.add(Md5Util.getBase64Md5(cache.sql))

    return ret.joinToString("")
}


inline fun  FromRedisCache.getJson(consumer: Supplier): T? {
    return this.getJson(T::class.java, consumer);
}

fun  FromRedisCache.getJson(cacheType: Class, consumer: Supplier): T? {
    return usingRedisCache({ it.FromJson(cacheType) }, consumer);
}

fun  FromRedisCache.getList(cacheType: Class, consumer: Supplier?>): List? {
    return usingRedisCache({ it.FromListJson(cacheType) }, consumer)
}

fun  FromRedisCache.onlyGetFromCache(converter: java.util.function.Function): T? {
    if( !config.enableCache){
        return null;
    }

    val cacheKey = this.getCacheKey()

    if (this.cacheSeconds >= 0 && cacheKey.HasValue) {
        val redisTemplate = SpringUtil.getBean();
        val cacheValue = redisTemplate.opsForValue().get(cacheKey).AsString()
        if (cacheValue.HasValue) {
            var ret = converter.apply(cacheValue);
            if (ret != null) {
                FromRedisCache.logger.Important("!查到Redis缓存数据! cacheKey:${cacheKey},sql:${this.sql}")
                return ret;
            }
        }
    }
    return null;
}

fun FromRedisCache.onlySetToCache(ret: Any) {
    if( !config.enableCache){
        return;
    }

    val cacheKey = this.getCacheKey()

    if (cacheSeconds >= 0 && cacheKey.HasValue) {
        var cacheSeconds = this.cacheSeconds
        //默认3分钟
        if (cacheSeconds == 0) {
            cacheSeconds = config.getConfig("app.cache.${this.table}").AsInt(180);
        }

        if (cacheSeconds > 0) {
            redisTemplate.opsForValue()
                .set(cacheKey, ret.ToJson(), Duration.ofSeconds(cacheSeconds.toLong()));
        }
    }
}

private fun  FromRedisCache.usingRedisCache(
    converter: java.util.function.Function,
    consumer: Supplier
): T? {
    onlyGetFromCache(converter).apply {
        if (this != null) {
            return this;
        }
    }

    val ret = consumer.get();
    if (ret == null) return null;

    onlySetToCache(ret)
    return ret;
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy