Since the front-end needs user information userInfo, and each module of the back-end, such as reports, also needs user information, and the query frequency is very high, involving many joint tables.
However, the actual system users are small, and the data is basically unchanged, which is convenient for each module to query, so it is decided to use the cache.
Choose to put it in the Redis database, and when accessing user data, the modules are decoupled.
1. Function
Some fields of userInfo may come from functions.
Due to the need, when I get a user, I also need to know which top-level organization he belongs to.
The organization table is as follows:
orgId | orgName | parentOrgId |
---|---|---|
1 | boss | null |
2 | Organization one | 1 |
3 | Organization two | 1 |
First, create a function that orgId
getsrootId
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. View
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. Regular update to Redis
Reflection is used to store attributes and values in 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);
});
}
}