添加缓存基本支持功能

This commit is contained in:
datagear 2021-08-15 22:42:04 +08:00
parent 10487d16f8
commit 0f277f09e9
9 changed files with 304 additions and 74 deletions

View File

@ -46,15 +46,9 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>

View File

@ -187,6 +187,18 @@ public class Schema extends AbstractStringIdEntity
this.dataPermission = dataPermission;
}
@Override
public Schema clone()
{
Schema schema = new Schema(this.getId(), this.title, this.url, this.user, this.password);
schema.setCreateUser(this.createUser);
schema.setCreateTime(this.createTime);
schema.setDriverEntity(this.driverEntity);
schema.setDataPermission(this.dataPermission);
return schema;
}
/**
* 清除密码属性值
* <p>

View File

@ -10,6 +10,7 @@ package org.datagear.management.service.impl;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSessionFactory;
import org.datagear.management.domain.Entity;
import org.datagear.management.service.EntityService;
@ -18,6 +19,7 @@ import org.datagear.persistence.PagingData;
import org.datagear.persistence.PagingQuery;
import org.datagear.persistence.Query;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.cache.Cache;
/**
* 抽象基于Mybatis的{@linkplain EntityService}实现类
@ -28,6 +30,11 @@ import org.mybatis.spring.SqlSessionTemplate;
public abstract class AbstractMybatisEntityService<ID, T extends Entity<ID>> extends AbstractMybatisService<T>
implements EntityService<ID, T>
{
private Cache cache = null;
/** 查询操作时缓存实体数目 */
private int cacheCountForQuery = 50;
public AbstractMybatisEntityService()
{
super();
@ -43,6 +50,26 @@ public abstract class AbstractMybatisEntityService<ID, T extends Entity<ID>> ext
super(sqlSessionTemplate, dialect);
}
public Cache getCache()
{
return cache;
}
public void setCache(Cache cache)
{
this.cache = cache;
}
public int getCacheCountForQuery()
{
return cacheCountForQuery;
}
public void setCacheCountForQuery(int cacheCountForQuery)
{
this.cacheCountForQuery = cacheCountForQuery;
}
@Override
public boolean add(T entity)
{
@ -72,26 +99,24 @@ public abstract class AbstractMybatisEntityService<ID, T extends Entity<ID>> ext
return re;
}
/**
* 删除
*
* @param id
* @param params
* @return
*/
protected boolean deleteById(ID id, Map<String, Object> params)
{
params.put("id", id);
return (deleteMybatis("deleteById", params) > 0);
}
@Override
public T getById(ID id)
{
return getById(id, buildParamMap());
}
@Override
public List<T> query(Query query)
{
return super.query(query);
}
@Override
public PagingData<T> pagingQuery(PagingQuery pagingQuery)
{
return super.pagingQuery(pagingQuery);
}
/**
* 获取
* <p>
@ -118,25 +143,192 @@ public abstract class AbstractMybatisEntityService<ID, T extends Entity<ID>> ext
*/
protected T getById(ID id, Map<String, Object> params, boolean postProcessSelect)
{
params.put("id", id);
T entity = cacheGet(id);
T entity = selectOneMybatis("getById", params);
if (entity == null)
{
params.put("id", id);
entity = selectOneMybatis("getById", params);
if (postProcessSelect)
cachePut(id, entity);
}
if (postProcessSelect && entity != null)
entity = postProcessSelect(entity);
return entity;
}
@Override
public List<T> query(Query query)
protected boolean update(T entity, Map<String, Object> params)
{
return super.query(query);
cacheEvict(entity.getId());
return super.update(entity, params);
}
/**
* 删除
*
* @param id
* @param params
* @return
*/
protected boolean deleteById(ID id, Map<String, Object> params)
{
cacheEvict(id);
params.put("id", id);
return (deleteMybatis("deleteById", params) > 0);
}
@Override
public PagingData<T> pagingQuery(PagingQuery pagingQuery)
protected List<T> query(String statement, Map<String, Object> params, boolean postProcessSelects)
{
return super.pagingQuery(pagingQuery);
List<T> list = super.query(statement, params, false);
cachePut(list);
if (postProcessSelects)
postProcessSelects(list);
return list;
}
@Override
protected List<T> query(String statement, Map<String, Object> params, RowBounds rowBounds,
boolean postProcessSelects)
{
List<T> list = super.query(statement, params, rowBounds, false);
cachePut(list);
if (postProcessSelects)
postProcessSelects(list);
return list;
}
/**
* 是否开启缓存
* <p>
* 子类应注意是否需要重写{@linkplain #cacheCloneValue(Entity)}方法
* </p>
*
* @return
*/
protected boolean cacheEnabled()
{
return (getCache() != null);
}
/**
* 拷贝缓存值
* <p>
* 当从缓存中取出对象时将对象放入缓存时进行拷贝
* </p>
* <p>
* 此方法默认返回原对象子类应根据实际情况对象是否会被修改决定是否需要真正拷贝
* </p>
*
* @param value
* @return
*/
protected T cacheCloneValue(T value)
{
return value;
}
protected void cachePut(ID id, T value)
{
if (!cacheEnabled())
return;
if (value != null)
value = cacheCloneValue(value);
cachePut(getCache(), value.getId(), value);
}
protected void cachePut(List<T> values)
{
if (!cacheEnabled())
return;
int count = Math.min(values.size(), this.getCacheCountForQuery());
for (int i = 0; i < count; i++)
{
T value = values.get(i);
if (value != null)
{
value = cacheCloneValue(value);
cachePut(getCache(), value.getId(), value);
}
}
}
protected T cacheGet(ID key)
{
if (!cacheEnabled())
return null;
T value = cacheGet(getCache(), key);
if (value != null)
value = cacheCloneValue(value);
return value;
}
protected void cacheEvict(ID key)
{
if (!cacheEnabled())
return;
cacheEvict(getCache(), key);
}
protected void cacheInvalidate()
{
if (!cacheEnabled())
return;
cacheInvalidate(getCache());
}
protected void cachePut(Cache cache, Object key, Object value)
{
if (cache == null)
return;
cache.put(key, value);
}
@SuppressWarnings("unchecked")
protected <TT> TT cacheGet(Cache cache, Object key)
{
if (cache == null)
return null;
return (TT) cache.get(key);
}
protected void cacheEvict(Cache cache, Object key)
{
if (cache == null)
return;
cache.evict(key);
}
protected void cacheInvalidate(Cache cache)
{
if (cache == null)
return;
cache.invalidate();
}
}

View File

@ -184,7 +184,7 @@ public abstract class AbstractMybatisService<T> extends SqlSessionDaoSupport
protected T get(T param)
{
return get(param, buildParamMap());
return get(param, buildParamMap(), true);
}
/**
@ -192,14 +192,17 @@ public abstract class AbstractMybatisService<T> extends SqlSessionDaoSupport
*
* @param id
* @param params
* @param postProcessSelect 是否内部执行{@linkplain #postProcessSelect(Object)}
* @return
*/
protected T get(T param, Map<String, Object> params)
protected T get(T param, Map<String, Object> params, boolean postProcessSelect)
{
params.put("param", param);
T entity = selectOneMybatis("get", params);
entity = postProcessSelect(entity);
if (postProcessSelect && entity != null)
entity = postProcessSelect(entity);
return entity;
}
@ -239,25 +242,7 @@ public abstract class AbstractMybatisService<T> extends SqlSessionDaoSupport
{
addQueryParam(params, query);
List<T> list = selectListMybatis(statement, params);
postProcessSelects(list);
return list;
}
/**
* 查询
*
* @param statement
* @param params
* @return
*/
protected List<T> query(String statement, Map<String, Object> params)
{
List<T> list = selectListMybatis(statement, params);
postProcessSelects(list);
return list;
return query(statement, params, true);
}
/**
@ -313,21 +298,55 @@ public abstract class AbstractMybatisService<T> extends SqlSessionDaoSupport
List<T> list = null;
if (this.dialect.supportsPaging())
{
list = selectListMybatis(statement, params);
}
list = query(statement, params, true);
else
{
list = selectListMybatis(statement, params, new RowBounds(startIndex, pagingData.getPageSize()));
}
postProcessSelects(list);
list = query(statement, params, new RowBounds(startIndex, pagingData.getPageSize()), true);
pagingData.setItems(list);
return pagingData;
}
/**
* 查询
*
* @param statement
* @param params
* @param postProcessSelects
* 是否内部执行{@linkplain #postProcessSelects(List)}
* @return
*/
protected List<T> query(String statement, Map<String, Object> params, boolean postProcessSelects)
{
List<T> list = selectListMybatis(statement, params);
if (postProcessSelects)
postProcessSelects(list);
return list;
}
/**
* 查询
*
* @param statement
* @param params
* @param rowBounds
* @param postProcessSelects
* 是否内部执行{@linkplain #postProcessSelects(List)}
* @return
*/
protected List<T> query(String statement, Map<String, Object> params, RowBounds rowBounds,
boolean postProcessSelects)
{
List<T> list = selectListMybatis(statement, params, rowBounds);
if (postProcessSelects)
postProcessSelects(list);
return list;
}
/**
* 后置处理查询结果列表
* <p>
@ -344,8 +363,12 @@ public abstract class AbstractMybatisService<T> extends SqlSessionDaoSupport
for (int i = 0; i < list.size(); i++)
{
T ele = list.get(i);
ele = postProcessSelect(ele);
list.set(i, ele);
if (ele != null)
{
ele = postProcessSelect(ele);
list.set(i, ele);
}
}
}
@ -355,7 +378,7 @@ public abstract class AbstractMybatisService<T> extends SqlSessionDaoSupport
* 默认为空方法子类可以重写已实现特定的查询结果处理逻辑
* </p>
*
* @param obj
* @param obj 不会为{@code null}
* @return
*/
protected T postProcessSelect(T obj)

View File

@ -409,9 +409,6 @@ public class DataSetEntityServiceImpl extends AbstractMybatisDataPermissionEntit
@Override
protected DataSetEntity postProcessSelect(DataSetEntity obj)
{
if (obj == null)
return null;
DataSetEntity initObj = obj;
if (DataSetEntity.DATA_SET_TYPE_SQL.equals(obj.getDataSetType()))

View File

@ -230,9 +230,6 @@ public class HtmlChartWidgetEntityServiceImpl
@Override
protected HtmlChartWidgetEntity postProcessSelect(HtmlChartWidgetEntity obj)
{
if (obj == null)
return null;
setHtmlChartPlugin(obj, false);
setChartDataSets(obj, false);

View File

@ -53,7 +53,7 @@ public class RoleServiceImpl extends AbstractMybatisEntityService<String, Role>
Map<String, Object> params = buildParamMap();
params.put("userId", userId);
List<Role> roles = query("findByUserId", params);
List<Role> roles = query("findByUserId", params, true);
set.addAll(roles);

View File

@ -122,7 +122,12 @@ public class SchemaServiceImpl extends AbstractMybatisDataPermissionEntityServic
params.put("oldUserId", oldUserId);
params.put("newUserId", newUserId);
return updateMybatis("updateCreateUserId", params);
int count = updateMybatis("updateCreateUserId", params);
if (count > 0)
cacheInvalidate();
return count;
}
@Override
@ -131,13 +136,18 @@ public class SchemaServiceImpl extends AbstractMybatisDataPermissionEntityServic
Map<String, Object> params = buildParamMap();
params.put("userIds", userIds);
return updateMybatis("deleteByUserId", params);
int count = updateMybatis("deleteByUserId", params);
if (count > 0)
cacheInvalidate();
return count;
}
@Override
protected Schema postProcessSelect(Schema schema)
{
if (schema != null && schema.hasDriverEntity())
if (schema.hasDriverEntity())
{
DriverEntity driverEntity = this.driverEntityManager.get(schema.getDriverEntity().getId());
schema.setDriverEntity(driverEntity);
@ -177,4 +187,10 @@ public class SchemaServiceImpl extends AbstractMybatisDataPermissionEntityServic
{
return SQL_NAMESPACE;
}
@Override
protected Schema cacheCloneValue(Schema value)
{
return value.clone();
}
}

View File

@ -145,7 +145,9 @@ public class UserServiceImpl extends AbstractMybatisEntityService<String, User>
params.put("name", name);
User user = selectOneMybatis("getByName", params);
postProcessSelect(user);
if (user != null)
postProcessSelect(user);
return user;
}
@ -177,9 +179,6 @@ public class UserServiceImpl extends AbstractMybatisEntityService<String, User>
@Override
protected User postProcessSelect(User obj)
{
if (obj == null)
return obj;
Set<Role> roles = this.roleService.findByUserId(obj.getId());
obj.setRoles(roles);