用戶信息緩存策略

因爲前端須要用戶信息userInfo,後端各個模塊,例如報表也須要用戶信息,查詢的頻率很高,涉及到較多的聯表。前端

而實際系統用戶較小,數據基本不變,爲各模塊方便查詢,決定採起緩存。java

選擇將其放到Redis數據庫中,訪問用戶數據時,模塊間獲得解耦。node

1. 函數

userInfo的部分字段可能來自於函數。redis

因爲須要,在我拿到一個用戶的時候,我同時須要得知他是屬於哪一個頂級組織的。sql

組織表以下:數據庫

orgId orgName parentOrgId
1 老闆 null
2 組織一 1
3 組織二 1

首先,建立一個函數,根據orgId獲取rootId後端

CREATE FUNCTION `queryRoot`(org varchar(32))
 RETURNS varchar(32)
BEGIN

# 定義子節點、父節點
DECLARE nodeId VARCHAR(32);
DECLARE parentId VARCHAR(32);
DECLARE rootId VARCHAR(32);

# 賦值
SET nodeId = org;
SET parentId = '$';

WHILE parentId IS NOT NULL DO
	SELECT parentOrgId INTO parentId FROM T_ORG WHERE ORG_ID = nodeId;
	SET rootId = nodeId;
	SET nodeId = parentId;
END WHILE;

RETURN rootId;

END;

2. 視圖

SELECT
	`users`.`USER_ID` AS `userId`,
	`users`.`ORG_ID` AS `orgId`,
	(
		SELECT
			`queryRootByOrgId` (`users`.`ORG_ID`)
	) AS `rootOrgId`,
	`orgs`.`ORG_NAME` AS `orgName`,
	`users`.`USER_NAME` AS `userName`
FROM
	(
		`T_USERS` `users`
		JOIN `T_ORG` `orgs` ON (
			(
				`users`.`ORG_ID` = `orgs`.`ORG_ID`
			)
		)
	)

3. 定時更新到Redis

其中用到了反射,將屬性及值存到Hash裏面。緩存

@EnableScheduling
@Component
public class RedisTask {

    @Autowired
    private StringRedisTemplate redis;

    @Autowired
    private UserInfoRepository userInfoRepository;

    static Field[] fields;
    static {
        fields = UserInfo.class.getDeclaredFields();
        for (Field field : fields)
            field.setAccessible(true);
    }

    /**
     * 定時 3min 查詢數據庫,而後更新到 redis 中
     */
    @Scheduled(fixedRate = 3*60*1000)
    private void userInfo() {

        List<UserInfo> list = userInfoRepository.findAll();

        list.forEach(user -> {
            Map<String, String> map = new HashMap();
            String hashKey, hashValue, hash = user.getUserId();
            for (Field field : fields) {
                try {
                    hashKey = field.getName();
                    if (field.get(user) != null)
                        hashValue = field.get(user).toString();
                    else
                        hashValue = "";
                    map.put(hashKey, hashValue);
                } catch (Exception e) {
                    System.out.println("反射異常");
                    e.printStackTrace();
                }
            }
            redis.opsForHash().putAll(hash, map);
        });

    }

}
相關文章
相關標籤/搜索