@@ -56,6 +56,7 @@ public abstract class AbstractCache<T extends Serializable> implements ISwCache< | |||
如资金科目明细项,需按资金科目缓存List。key=sc,value=class_id | |||
*/ | |||
protected Map<String, IGetBeanKey<T>> mapListReg = new HashMap<>(); | |||
protected Map<String, IGetBeanKeys<T>> mapListRegEx = new HashMap<>(); | |||
protected Map<String, IGetBeanKey<T>> mapMapReg = new HashMap<>(); | |||
public AbstractCache() { | |||
@@ -128,6 +129,10 @@ public abstract class AbstractCache<T extends Serializable> implements ISwCache< | |||
mapListReg.put(key, iGetBeanKey); | |||
} | |||
protected void regListEx(String key, IGetBeanKeys<T> iGetBeanKey) { | |||
mapListRegEx.put(key, iGetBeanKey); | |||
} | |||
/** | |||
* 注册其他key的Map缓存,如按code缓存 | |||
* | |||
@@ -253,6 +258,13 @@ public abstract class AbstractCache<T extends Serializable> implements ISwCache< | |||
doRemoveList(entry.getKey(), getBeanKey(entry.getValue(), oldbean), bean); | |||
} | |||
for (Map.Entry<String, IGetBeanKeys<T>> entry : mapListRegEx.entrySet()) { | |||
String[] keys = entry.getValue().getKey(oldbean); | |||
for (String k: keys) { | |||
doRemoveList(entry.getKey(), k, bean); | |||
} | |||
} | |||
for (Map.Entry<String, IGetBeanKey<T>> entry : mapMapReg.entrySet()) { | |||
doRemoveMap(entry.getKey(), getBeanKey(entry.getValue(), oldbean)); | |||
} | |||
@@ -273,6 +285,13 @@ public abstract class AbstractCache<T extends Serializable> implements ISwCache< | |||
doUpdateList(entry.getKey(), getBeanKey(entry.getValue(), value), value); | |||
} | |||
for (Map.Entry<String, IGetBeanKeys<T>> entry : mapListRegEx.entrySet()) { | |||
String[] keys = entry.getValue().getKey(value); | |||
for (String k: keys) { | |||
doUpdateList(entry.getKey(), k, value); | |||
} | |||
} | |||
for (Map.Entry<String, IGetBeanKey<T>> entry : mapMapReg.entrySet()) { | |||
doUpdateMap(entry.getKey(), getBeanKey(entry.getValue(), value), value); | |||
} | |||
@@ -489,4 +508,8 @@ public abstract class AbstractCache<T extends Serializable> implements ISwCache< | |||
public interface IGetBeanKey<T> { | |||
String getKey(T bean); | |||
} | |||
public interface IGetBeanKeys<T> { | |||
String[] getKey(T bean); | |||
} | |||
} |
@@ -15,4 +15,5 @@ public interface SwConsts { | |||
String PARAM_PAGE = "page"; | |||
String PARAM_ROWS = "rows"; | |||
String TOTAL_KEY = "total_count"; | |||
String DEF_DB_NAME = "sys"; | |||
} |
@@ -2,8 +2,10 @@ package cc.smtweb.framework.core.db; | |||
import cc.smtweb.framework.core.cache.AbstractCache; | |||
import cc.smtweb.framework.core.cache.CacheManager; | |||
import cc.smtweb.framework.core.common.SwException; | |||
import cc.smtweb.framework.core.common.SwMap; | |||
import cc.smtweb.framework.core.db.cache.ModelTableCache; | |||
import cc.smtweb.framework.core.db.vo.ModelField; | |||
import cc.smtweb.framework.core.db.vo.ModelLinkName; | |||
import cc.smtweb.framework.core.db.vo.ModelTable; | |||
import org.apache.commons.lang3.StringUtils; | |||
@@ -149,4 +151,35 @@ public class EntityHelper { | |||
} | |||
} | |||
} | |||
//检查表记录是否被引用 | |||
public static void checkExists(long tableId, long id) { | |||
ModelTable fkTable = ModelTableCache.getInstance().get(tableId); | |||
if (fkTable == null) throw new SwException("待检查表(" + tableId + ")为空!"); | |||
checkExists(fkTable, id); | |||
} | |||
public static void checkExists(String tableName, long id) { | |||
ModelTable fkTable = ModelTableCache.getInstance().getByName(tableName); | |||
if (fkTable == null) throw new SwException("待检查表(" + tableName + ")为空!"); | |||
checkExists(fkTable, id); | |||
} | |||
public static void checkExists(ModelTable fkTable, long id) { | |||
Set<ModelTable> list = ModelTableCache.getInstance().getByLink(fkTable.getId()); | |||
if (list == null || list.isEmpty()) return; | |||
for (ModelTable table: list) { | |||
StringBuilder sql = new StringBuilder(256); | |||
List<Object> args = new ArrayList<>(); | |||
for (ModelField field: table.getFields()) { | |||
if (field.getLink() == fkTable.getId()) { | |||
sql.append(" or ").append(field.getName()).append("=?"); | |||
args.add(id); | |||
} | |||
} | |||
if (sql.length() == 0) continue; | |||
if (DbEngine.getInstance().isExists("select 1 from " + table.getSchemaTableName() + " where " + sql.substring(4), args.toArray())) { | |||
throw new SwException("该记录被表【" + table.getTitle() + "(" + table.getName() + ")】引用,不能删除!"); | |||
} | |||
} | |||
} | |||
} |
@@ -4,16 +4,14 @@ import cc.smtweb.framework.core.annotation.SwCache; | |||
import cc.smtweb.framework.core.cache.AbstractCache; | |||
import cc.smtweb.framework.core.cache.CacheManager; | |||
import cc.smtweb.framework.core.db.DbEngine; | |||
import cc.smtweb.framework.core.db.vo.ModelField; | |||
import cc.smtweb.framework.core.db.vo.ModelTable; | |||
import org.springframework.dao.DataAccessException; | |||
import org.springframework.jdbc.core.ResultSetExtractor; | |||
import java.sql.ResultSet; | |||
import java.sql.SQLException; | |||
import java.util.ArrayList; | |||
import java.util.Comparator; | |||
import java.util.List; | |||
import java.util.Set; | |||
import java.util.*; | |||
/** | |||
* Created by Akmm at 2022/1/12 18:34 | |||
@@ -23,6 +21,7 @@ public class ModelTableCache extends AbstractCache<ModelTable> { | |||
private final static String mk = "k"; | |||
private final static String md = "d"; | |||
private final static String mc = "c"; | |||
private final static String mk_link = "l"; | |||
public static ModelTableCache getInstance() { | |||
return CacheManager.getIntance().getCache(ModelTableCache.class); | |||
@@ -32,6 +31,13 @@ public class ModelTableCache extends AbstractCache<ModelTable> { | |||
regMap(mk, k-> k.getName().toUpperCase()); | |||
regList(md, k-> String.valueOf(k.getDbId())); | |||
regList(mc, k-> String.valueOf(k.getMcId())); | |||
regListEx(mk_link, k-> { | |||
Set<String> list = new HashSet<>(); | |||
for (ModelField field: k.getFields()) { | |||
if (field.getLink() > 0) list.add(String.valueOf(field.getLink())); | |||
} | |||
return list.toArray(new String[list.size()]); | |||
}); | |||
// regList(mf, k-> k.get); | |||
} | |||
@@ -109,4 +115,9 @@ public class ModelTableCache extends AbstractCache<ModelTable> { | |||
ModelTable bean = get(id); | |||
return bean == null ? String.valueOf(id) : bean.getTitle(); | |||
} | |||
//根据外键 | |||
public final Set<ModelTable> getByLink(long tableId) { | |||
return getListByKey(mk_link, String.valueOf(tableId)); | |||
} | |||
} |
@@ -1,5 +1,6 @@ | |||
package cc.smtweb.framework.core.db.impl; | |||
import cc.smtweb.framework.core.common.SwConsts; | |||
import cc.smtweb.framework.core.db.DbEngine; | |||
import cc.smtweb.framework.core.db.cache.ModelDatabaseCache; | |||
import cc.smtweb.framework.core.db.vo.ModelDatabase; | |||
@@ -215,12 +216,13 @@ public class DefaultDatabaseInfoImpl implements IDatabaseInfo { | |||
Collection<ModelDatabase> list = ModelDatabaseCache.getInstance().getAll(); | |||
if (list != null && !list.isEmpty()) { | |||
for (ModelDatabase db : list) { | |||
getColumnInfo(dbData, dbName + "_" + db.getName(), needsUpperCase, lookupSchemaName); | |||
String dn = SwConsts.DEF_DB_NAME.equals(db.getName()) ? "" : ("_" + db.getName()); | |||
getColumnInfo(dbData, dbName + dn, needsUpperCase, lookupSchemaName); | |||
} | |||
} | |||
} | |||
getColumnInfo(dbData, null, needsUpperCase, lookupSchemaName); | |||
// getColumnInfo(dbData, null, needsUpperCase, lookupSchemaName); | |||
} catch (SQLException e) { | |||
log.error(e.getMessage(), e); | |||
} | |||
@@ -6,6 +6,8 @@ import cc.smtweb.framework.core.db.impl.BaseBean; | |||
import cc.smtweb.framework.core.exception.DbException; | |||
import cc.smtweb.framework.core.util.JsonUtil; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.springframework.dao.DataAccessException; | |||
import org.springframework.dao.EmptyResultDataAccessException; | |||
import org.springframework.jdbc.core.BeanPropertyRowMapper; | |||
import org.springframework.jdbc.core.JdbcTemplate; | |||
import org.springframework.jdbc.core.ResultSetExtractor; | |||
@@ -467,7 +469,12 @@ public class JdbcEngine { | |||
} | |||
/*=================以上为具名参数方法==================================================*/ | |||
public boolean isExists(String sql, Object... params) { | |||
return jdbcTemplate.queryForObject(sql + " LIMIT 0, 1", int.class, params) > 0; | |||
try { | |||
Object v = jdbcTemplate.queryForObject(sql + " LIMIT 0, 1", Object.class, params); | |||
return (v != null); | |||
} catch (EmptyResultDataAccessException e) { | |||
return false; | |||
} | |||
} | |||
private <T> RowMapper<T> createRowMapper(Class<T> type) { | |||
@@ -1,6 +1,7 @@ | |||
package cc.smtweb.framework.core.db.vo; | |||
import cc.smtweb.framework.core.annotation.SwTable; | |||
import cc.smtweb.framework.core.common.SwConsts; | |||
import cc.smtweb.framework.core.common.SwEnum; | |||
import cc.smtweb.framework.core.db.DbEngine; | |||
import cc.smtweb.framework.core.db.cache.ModelDatabaseCache; | |||
@@ -14,7 +15,6 @@ import java.util.List; | |||
@SwTable(value = "ASP_MODEL_TABLE") | |||
public class ModelTable extends DefaultEntity { | |||
public final static String DEF_DB_NAME = "sys"; | |||
public final static String ENTITY_NAME = "ASP_MODEL_TABLE"; | |||
/*冗余*/ | |||
@@ -276,7 +276,7 @@ public class ModelTable extends DefaultEntity { | |||
public String getSchemaTableName() { | |||
String dbName = getDbName(); | |||
if (StringUtils.isEmpty(dbName) || dbName.equals(DEF_DB_NAME)) return getName(); | |||
if (StringUtils.isEmpty(dbName) || dbName.equals(SwConsts.DEF_DB_NAME)) return getName(); | |||
return DbEngine.getInstance().getDbSchema() + "_" + dbName + "." + getName(); | |||
} | |||
} |
@@ -4,6 +4,7 @@ import cc.smtweb.framework.core.cache.AbstractCache; | |||
import cc.smtweb.framework.core.cache.CacheManager; | |||
import cc.smtweb.framework.core.db.DbEngine; | |||
import cc.smtweb.framework.core.db.EntityDao; | |||
import cc.smtweb.framework.core.db.EntityHelper; | |||
import cc.smtweb.framework.core.db.cache.ModelTableCache; | |||
import cc.smtweb.framework.core.db.impl.DefaultEntity; | |||
import cc.smtweb.framework.core.db.vo.ModelTable; | |||
@@ -21,7 +22,8 @@ public class DefaultDelHandler<T extends DefaultEntity> extends AbstractDelHandl | |||
@Override | |||
protected void checkValid() { | |||
ModelTable table = ModelTableCache.getInstance().getByName(tableName); | |||
EntityHelper.checkExists(tableName, id); | |||
// ModelTable table = ModelTableCache.getInstance().getByName(tableName); | |||
//todo 检查外键引用的使用情况 | |||
} | |||
@@ -1,9 +1,6 @@ | |||
package cc.smtweb.system.bpm.web.design.form; | |||
import cc.smtweb.framework.core.common.R; | |||
import cc.smtweb.framework.core.common.SwEnum; | |||
import cc.smtweb.framework.core.common.SwException; | |||
import cc.smtweb.framework.core.common.SwMap; | |||
import cc.smtweb.framework.core.common.*; | |||
import cc.smtweb.framework.core.db.cache.ModelTableCache; | |||
import cc.smtweb.framework.core.db.vo.ModelCache; | |||
import cc.smtweb.framework.core.db.vo.ModelField; | |||
@@ -71,7 +68,7 @@ public class CodeBuildHandler extends AbstractHandler { | |||
if (form == null) throw new SwException("未找到指定的页面定义!"); | |||
String moduleName = ModelProjectCache.getInstance().getModule(form.getPrjId()); | |||
if (StringUtils.isEmpty(moduleName) || moduleName.equals("sys") || moduleName.equals("bpm")) { | |||
if (StringUtils.isEmpty(moduleName) || SwConsts.DEF_DB_NAME.equals(moduleName) || moduleName.equals("bpm")) { | |||
moduleName = "sw-system-bpm"; | |||
packageName = "cc.smtweb.system.bpm.web"; | |||
} else { | |||
@@ -7,6 +7,7 @@ import cc.smtweb.framework.core.common.SwEnum; | |||
import cc.smtweb.framework.core.common.SwException; | |||
import cc.smtweb.framework.core.db.DbEngine; | |||
import cc.smtweb.framework.core.db.EntityDao; | |||
import cc.smtweb.framework.core.db.EntityHelper; | |||
import cc.smtweb.framework.core.db.cache.ModelTableCache; | |||
import cc.smtweb.framework.core.db.impl.DefaultEntity; | |||
import cc.smtweb.framework.core.db.jdbc.AbsDbWorker; | |||
@@ -131,6 +132,7 @@ public class DynPageDelHandler extends AbstractDynPageHandler { | |||
*/ | |||
protected void checkBean(PageDataset pageDataSet, long id) { | |||
//校验外键引用关系 | |||
EntityHelper.checkExists(pageDataSet.masterTable, id); | |||
} | |||
/** | |||