生成主键


 /**
* 生成主键(如果检查到存在重复值,则重新计算一个)
* @param $originTableName
* @return null|string
*/
public static function generateNextPrimaryID($originTableName,$withCache=true,$checkKeyExist = false)
{
$key = FwPrimaryKey::generateNextPrimaryIDInternal($originTableName,$withCache);

if ($checkKeyExist) {
$result = FwPrimaryKey::isKeyExist($originTableName, $key);
}
else {
$result = false;
}

if ($result == true) {
return FwPrimaryKey::generateNextPrimaryID($originTableName,$withCache);
} else {
return $key;
}
}

/**
* 生成主键(内部方法)
* @inheritdoc
*/
private static function generateNextPrimaryIDInternal($originTableName,$withCache)
{
if (FwPrimaryKey::tableName() == $originTableName) {
return null;
}
else {
$currentPrimaryID = 1;
$tbName = self::calculateTableName($originTableName);

$cacheKey = "PK_" . $tbName;
$cacheKeyNextPrimaryId = "NextPrimaryId";
$cacheKeyCurrentPrimaryId = "CurrentPrimaryId";
$cacheKeyType = "KeyType";
$cachePaddingCount = "PaddingCount";
$cacheKeyPrefix = "KeyPrefix";

if ($withCache)
$primaryKeyData = Yii::$app->cache->get($cacheKey);
else
$primaryKeyData = false;

//load cache info
if ($primaryKeyData != false)
{
$primaryKeyNextPrimaryId = ArrayHelper::getValue($primaryKeyData,$cacheKeyNextPrimaryId);
$primaryKeyCurrentPrimaryId = ArrayHelper::getValue($primaryKeyData,$cacheKeyCurrentPrimaryId);
$primaryKeyType = ArrayHelper::getValue($primaryKeyData,$cacheKeyType);
$primaryKeyPrefix = ArrayHelper::getValue($primaryKeyData,$cacheKeyPrefix);
$primaryPaddingCount = ArrayHelper::getValue($primaryKeyData,$cachePaddingCount);

if ($primaryKeyType == self::KEY_TYPE_SYSGEN)
{
return null;
}
else if ($primaryKeyType == self::KEY_TYPE_GUID)
{
return self::guid();
}
else if ($primaryKeyCurrentPrimaryId < $primaryKeyNextPrimaryId)
{
$currentPrimaryID = $primaryKeyCurrentPrimaryId;
$primaryKeyCurrentPrimaryId = $primaryKeyCurrentPrimaryId + 1;

$primaryKeyData[$cacheKeyCurrentPrimaryId] = $primaryKeyCurrentPrimaryId;

$primaryKeyModel = new FwPrimaryKey();
$dependencySql = $primaryKeyModel->find(false)
->andFilterWhere(['=','table_name',$tbName])
->select("updated_at")
->createCommand()
->getRawSql();

self::saveToCache($cacheKey, $primaryKeyData,$dependencySql, $withCache);

$currentKey = self::CalculateCurrentKey($primaryKeyPrefix,$currentPrimaryID, $primaryPaddingCount);
return $currentKey;
}

}


$currentDate = time();// date("Y-m-d H:i:s");

if (empty(Yii::$app->user) || Yii::$app->user->getId() == null || Yii::$app->user->isGuest)
$currentUserId = "00000000-0000-0000-0000-000000000000";
else
$currentUserId = strval(Yii::$app->user->getId());

$systemType = "PC";

//load primary key table setting info
$result = static::findOne(['table_name' => $tbName]);
if ($result != null) {
$currentPrimaryID = $result->next_primary_id;
$result->updated_at = $currentDate;
$result->updated_by = $currentUserId;
$result->updated_from = $systemType; } else { $result = new FwPrimaryKey(); $result->table_name = $tbName; $result->key_prefix = ''; $result->created_at = $currentDate; $result->created_by = $currentUserId; $result->created_from = $systemType; $result->padding_count = 0; $result->key_type = self::KEY_TYPE_GUID; //设置默认值为取GUID //FwPrimaryKey表KID,强制为GUID $result->kid = self::guid(); }// $currentKey = "0"; $keyPrefix = ""; if ($result->key_type == self::KEY_TYPE_SYSGEN) { $nextOnePrimaryID = null; $result->next_primary_id = null; $currentKey = null; } else if ($result->key_type == self::KEY_TYPE_GUID) { $nextOnePrimaryID = null; $result->next_primary_id = null; $currentKey = self::guid(); } else { $nextOnePrimaryID = $currentPrimaryID + 1; $nextPrimaryID = $currentPrimaryID + self::KEY_INCREASE_STEP; $result->next_primary_id = strval($nextPrimaryID); $keyPrefix = $result->key_prefix; if ($keyPrefix == null) $keyPrefix = ""; $currentKey = self::CalculateCurrentKey($keyPrefix,$currentPrimaryID, $result->padding_count); } if ($result->save()) { if ($withCache) { //initiate cache value $primaryKeyData = [ $cacheKeyNextPrimaryId => $result->next_primary_id, $cacheKeyCurrentPrimaryId => $nextOnePrimaryID, $cacheKeyType => $result->key_type, $cachePaddingCount => $result->padding_count, $cacheKeyPrefix => $keyPrefix]; if ($result->key_type == self::KEY_TYPE_GUID || $result->key_type == self::KEY_TYPE_SYSGEN) { self::saveToCache($cacheKey, $primaryKeyData, null, self::DURATION_YEAR); } else { $primaryKeyModel = new FwPrimaryKey(); $dependencySql = $primaryKeyModel->find(false) ->andFilterWhere(['=','table_name',$tbName]) ->select("updated_at") ->createCommand() ->getRawSql(); self::saveToCache($cacheKey, $primaryKeyData, $dependencySql, $withCache); } } } return $currentKey; } } /** * 判断Key值是否存在相同的(高并发或使用GUID生成主键时,有一定概率会存在相同值) * @param $tbName * @param $kid * @return bool */ private static function isKeyExist($tableName,$kid) { if ($kid == null) return false; $primaryKeyTableName = self::calculateTableName($tableName); $sql = "SELECT count(1) FROM ". self::getQuoteColumnName($primaryKeyTableName) ." WHERE " . self::getQuoteColumnName("kid") . " = '" . $kid . "'"; $results = eLearningLMS::queryScalar($sql); if (!empty($results) && intval($results) >= 1) return true; return false; }

posted @ 2018-04-04 10:53  大盆底  阅读(166)  评论(0编辑  收藏  举报