use of org.sagacity.sqltoy.plugins.IUnifyFieldsHandler in project sagacity-sqltoy by chenrenfei.
the class SqlToyDaoSupport method updateByQuery.
/**
* @TODO 针对单表对象查询进行更新操作(update和delete 操作filters过滤是无效的,必须是精准的条件参数)
* @param entityClass
* @param entityUpdate
* @update 2021-12-23 支持update table set field=field+1等计算模式
* @return
*/
protected Long updateByQuery(Class entityClass, EntityUpdate entityUpdate) {
if (null == entityClass || null == entityUpdate || StringUtil.isBlank(entityUpdate.getInnerModel().where) || StringUtil.isBlank(entityUpdate.getInnerModel().values) || entityUpdate.getInnerModel().updateValues.isEmpty()) {
throw new IllegalArgumentException("updateByQuery: entityClass、where条件、条件值value、变更值setValues不能为空!");
}
EntityUpdateExtend innerModel = entityUpdate.getInnerModel();
boolean isName = SqlConfigParseUtils.hasNamedParam(innerModel.where);
Object[] values = innerModel.values;
String[] paramNames = null;
String where = innerModel.where;
int valueSize = (values == null) ? 0 : values.length;
// 重新通过对象反射获取参数条件的值
if (isName) {
if (values.length > 1) {
throw new IllegalArgumentException("updateByQuery: where条件采用:paramName形式传参,values只能传递单个VO或Map对象!");
}
paramNames = SqlConfigParseUtils.getSqlParamsName(where, false);
values = BeanUtil.reflectBeanToAry(values[0], paramNames);
// 重新设置值数组的长度
valueSize = values.length;
} else {
if (DialectUtils.getParamsCount(where) != valueSize) {
throw new IllegalArgumentException("updateByQuery: where语句中的?数量跟对应values 数组长度不一致,请检查!");
}
}
EntityMeta entityMeta = getEntityMeta(entityClass);
// 处理where 中写的java 字段名称为数据库表字段名称
where = SqlUtil.convertFieldsToColumns(entityMeta, where);
StringBuilder sql = new StringBuilder();
sql.append("update ").append(entityMeta.getSchemaTable(null, null)).append(" set ");
Entry<String, Object> entry;
// 对统一更新字段做处理
IUnifyFieldsHandler unifyHandler = getSqlToyContext().getUnifyFieldsHandler();
if (unifyHandler != null) {
Map<String, Object> updateFields = unifyHandler.updateUnifyFields();
if (updateFields != null && !updateFields.isEmpty()) {
Iterator<Entry<String, Object>> updateIter = updateFields.entrySet().iterator();
while (updateIter.hasNext()) {
entry = updateIter.next();
// 是数据库表的字段
if (entityMeta.getColumnName(entry.getKey()) != null) {
// 是否已经主动update
if (innerModel.updateValues.containsKey(entry.getKey())) {
// 判断是否存在强制更新
if (unifyHandler.forceUpdateFields() != null && unifyHandler.forceUpdateFields().contains(entry.getKey())) {
innerModel.updateValues.put(entry.getKey(), entry.getValue());
}
} else {
innerModel.updateValues.put(entry.getKey(), entry.getValue());
}
}
}
}
}
Object[] realValues = new Object[innerModel.updateValues.size() + valueSize];
if (valueSize > 0) {
System.arraycopy(values, 0, realValues, innerModel.updateValues.size(), valueSize);
}
Integer[] paramsTypes = new Integer[realValues.length];
for (int i = 0; i < paramsTypes.length; i++) {
paramsTypes[i] = java.sql.Types.OTHER;
}
String[] realNames = null;
if (isName) {
realNames = new String[realValues.length];
System.arraycopy(paramNames, 0, realNames, innerModel.updateValues.size(), valueSize);
}
int index = 0;
String columnName;
FieldMeta fieldMeta;
Iterator<Entry<String, Object>> iter = innerModel.updateValues.entrySet().iterator();
String[] fields;
String fieldSetValue;
// 设置一个扩展标志,避免set field=field+? 场景构造成field=field+:fieldExtParam跟where
// field=:field名称冲突
final String extSign = "ExtParam";
while (iter.hasNext()) {
entry = iter.next();
// 考虑 field=filed+? 模式,分割成2部分
fields = entry.getKey().split("=");
fieldMeta = entityMeta.getFieldMeta(fields[0].trim());
// entry.getKey() 直接是数据库字段名称
if (fieldMeta == null) {
// 先通过数据字段名称获得类的属性名称再获取fieldMeta
fieldMeta = entityMeta.getFieldMeta(entityMeta.getColumnFieldMap().get(fields[0].trim().toLowerCase()));
}
columnName = fieldMeta.getColumnName();
// 设置字段类型
if (fields.length == 1) {
paramsTypes[index] = fieldMeta.getType();
}
// 保留字处理
columnName = ReservedWordsUtil.convertWord(columnName, null);
if (isName) {
if (fields.length > 1) {
if (fields[1].contains("?")) {
// 拼接扩展字符,避免where后面有同样的参数名称
realNames[index] = fieldMeta.getFieldName().concat(extSign);
} else {
realNames[index] = SqlConfigParseUtils.getSqlParamsName(fields[1], true)[0];
}
} else {
realNames[index] = fieldMeta.getFieldName();
}
}
realValues[index] = entry.getValue();
if (index > 0) {
sql.append(",");
}
if (fields.length == 1) {
sql.append(columnName).append("=").append(isName ? (":" + fieldMeta.getFieldName()) : "?");
} else {
// field=filed+? 类似模式
fieldSetValue = fields[1];
sql.append(columnName).append("=");
if (isName && fieldSetValue.contains("?")) {
fieldSetValue = fieldSetValue.replace("?", ":" + fieldMeta.getFieldName().concat(extSign));
}
fieldSetValue = SqlUtil.convertFieldsToColumns(entityMeta, fieldSetValue);
sql.append(fieldSetValue);
}
index++;
}
sql.append(" where ").append(where);
String sqlStr = sql.toString();
SqlToyConfig sqlToyConfig = sqlToyContext.getSqlToyConfig(sqlStr, SqlType.update, getDialect(innerModel.dataSource));
QueryExecutor queryExecutor = new QueryExecutor(sqlStr).names(realNames).values(realValues);
setEntitySharding(queryExecutor, entityMeta);
return dialectFactory.executeSql(sqlToyContext, sqlToyConfig, queryExecutor, paramsTypes, null, getDataSource(innerModel.dataSource, sqlToyConfig));
}
use of org.sagacity.sqltoy.plugins.IUnifyFieldsHandler in project sagacity-sqltoy by chenrenfei.
the class SqltoyAutoConfiguration method sqlToyContext.
// 构建sqltoy上下文,并指定初始化方法和销毁方法
@Bean(name = "sqlToyContext", initMethod = "initialize", destroyMethod = "destroy")
@ConditionalOnMissingBean
SqlToyContext sqlToyContext() throws Exception {
// 用辅助配置来校验是否配置错误
if (StringUtil.isBlank(properties.getSqlResourcesDir()) && StringUtil.isNotBlank(sqlResourcesDir)) {
throw new IllegalArgumentException("请检查sqltoy配置,是spring.sqltoy作为前缀,而不是sqltoy!\n正确范例: spring.sqltoy.sqlResourcesDir=classpath:com/sagframe/modules");
}
SqlToyContext sqlToyContext = new SqlToyContext();
// 当发现有重复sqlId时是否抛出异常,终止程序执行
sqlToyContext.setBreakWhenSqlRepeat(properties.isBreakWhenSqlRepeat());
// sql 文件资源路径
sqlToyContext.setSqlResourcesDir(properties.getSqlResourcesDir());
if (properties.getSqlResources() != null && properties.getSqlResources().length > 0) {
List<String> resList = new ArrayList<String>();
for (String prop : properties.getSqlResources()) {
resList.add(prop);
}
sqlToyContext.setSqlResources(resList);
}
// sql文件解析的编码格式,默认utf-8
if (properties.getEncoding() != null) {
sqlToyContext.setEncoding(properties.getEncoding());
}
// pojo 扫描路径,意义不存在
if (properties.getPackagesToScan() != null) {
sqlToyContext.setPackagesToScan(properties.getPackagesToScan());
}
// 特定pojo类加载,意义已经不存在
if (properties.getAnnotatedClasses() != null) {
sqlToyContext.setAnnotatedClasses(properties.getAnnotatedClasses());
}
// 批量操作时(saveAll、updateAll),每批次数量,默认200
if (properties.getBatchSize() != null) {
sqlToyContext.setBatchSize(properties.getBatchSize());
}
// 默认数据库fetchSize
if (properties.getFetchSize() > 0) {
sqlToyContext.setFetchSize(properties.getFetchSize());
}
// 分页查询单页最大记录数量(默认50000)
if (properties.getPageFetchSizeLimit() != null) {
sqlToyContext.setPageFetchSizeLimit(properties.getPageFetchSizeLimit());
}
// sql 检测间隔时长(单位秒)
if (properties.getScriptCheckIntervalSeconds() != null) {
sqlToyContext.setScriptCheckIntervalSeconds(properties.getScriptCheckIntervalSeconds());
}
// 缓存、sql文件在初始化后延时多少秒开始检测
if (properties.getDelayCheckSeconds() != null) {
sqlToyContext.setDelayCheckSeconds(properties.getDelayCheckSeconds());
}
// 是否debug模式
if (properties.getDebug() != null) {
sqlToyContext.setDebug(properties.getDebug());
}
// sql执行超过多长时间则打印提醒(默认30秒)
if (properties.getPrintSqlTimeoutMillis() != null) {
sqlToyContext.setPrintSqlTimeoutMillis(properties.getPrintSqlTimeoutMillis());
}
// sql函数转换器
if (properties.getFunctionConverts() != null) {
sqlToyContext.setFunctionConverts(properties.getFunctionConverts());
}
// 缓存翻译配置
if (properties.getTranslateConfig() != null) {
sqlToyContext.setTranslateConfig(properties.getTranslateConfig());
}
// 数据库保留字
if (properties.getReservedWords() != null) {
sqlToyContext.setReservedWords(properties.getReservedWords());
}
// 分页页号超出总页时转第一页,否则返回空集合
sqlToyContext.setPageOverToFirst(properties.isPageOverToFirst());
// 数据库方言
sqlToyContext.setDialect(properties.getDialect());
// sqltoy内置参数默认值修改
sqlToyContext.setDialectConfig(properties.getDialectConfig());
// update 2021-01-18 设置缓存类别,默认ehcache
sqlToyContext.setCacheType(properties.getCacheType());
sqlToyContext.setSecurePrivateKey(properties.getSecurePrivateKey());
sqlToyContext.setSecurePublicKey(properties.getSecurePublicKey());
// 设置公共统一属性的处理器
String unfiyHandler = properties.getUnifyFieldsHandler();
if (StringUtil.isNotBlank(unfiyHandler)) {
try {
IUnifyFieldsHandler handler = null;
// 类
if (unfiyHandler.contains(".")) {
handler = (IUnifyFieldsHandler) Class.forName(unfiyHandler).getDeclaredConstructor().newInstance();
} else // spring bean名称
if (applicationContext.containsBean(unfiyHandler)) {
handler = (IUnifyFieldsHandler) applicationContext.getBean(unfiyHandler);
if (handler == null) {
throw new ClassNotFoundException("项目中未定义unifyFieldsHandler=" + unfiyHandler + " 对应的bean!");
}
}
if (handler != null) {
sqlToyContext.setUnifyFieldsHandler(handler);
}
} catch (ClassNotFoundException cne) {
err.println("------------------- 错误提示 ------------------------------------------- ");
err.println("spring.sqltoy.unifyFieldsHandler=" + unfiyHandler + " 对应类不存在,错误原因:");
err.println("--1.您可能直接copy了参照项目的配置文件,但没有将具体的类也同步copy过来!");
err.println("--2.如您并不需要此功能,请将配置文件中注释掉spring.sqltoy.unifyFieldsHandler");
err.println("------------------------------------------------");
cne.printStackTrace();
throw cne;
}
}
// 设置elastic连接
Elastic es = properties.getElastic();
if (es != null && es.getEndpoints() != null && !es.getEndpoints().isEmpty()) {
sqlToyContext.setDefaultElastic(es.getDefaultId());
List<ElasticEndpoint> endpoints = new ArrayList<ElasticEndpoint>();
for (ElasticConfig esconfig : es.getEndpoints()) {
ElasticEndpoint ep = new ElasticEndpoint(esconfig.getUrl(), esconfig.getSqlPath());
ep.setId(esconfig.getId());
if (esconfig.getCharset() != null) {
ep.setCharset(esconfig.getCharset());
}
if (esconfig.getRequestTimeout() != null) {
ep.setRequestTimeout(esconfig.getRequestTimeout());
}
if (esconfig.getConnectTimeout() != null) {
ep.setConnectTimeout(esconfig.getConnectTimeout());
}
if (esconfig.getSocketTimeout() != null) {
ep.setSocketTimeout(esconfig.getSocketTimeout());
}
ep.setAuthCaching(esconfig.isAuthCaching());
ep.setUsername(esconfig.getUsername());
ep.setPassword(esconfig.getPassword());
ep.setKeyStore(esconfig.getKeyStore());
ep.setKeyStorePass(esconfig.getKeyStorePass());
ep.setKeyStoreSelfSign(esconfig.isKeyStoreSelfSign());
ep.setKeyStoreType(esconfig.getKeyStoreType());
endpoints.add(ep);
}
// 这里已经完成了当没有设置默认节点时将第一个节点作为默认节点
sqlToyContext.setElasticEndpoints(endpoints);
}
// 设置默认数据库
if (properties.getDefaultDataSource() != null) {
sqlToyContext.setDefaultDataSourceName(properties.getDefaultDataSource());
}
// 自定义缓存实现管理器
String translateCacheManager = properties.getTranslateCacheManager();
if (StringUtil.isNotBlank(translateCacheManager)) {
// 缓存管理器的bean名称
if (applicationContext.containsBean(translateCacheManager)) {
sqlToyContext.setTranslateCacheManager((TranslateCacheManager) applicationContext.getBean(translateCacheManager));
} else // 包名和类名称
if (translateCacheManager.contains(".")) {
sqlToyContext.setTranslateCacheManager((TranslateCacheManager) Class.forName(translateCacheManager).getDeclaredConstructor().newInstance());
}
}
// 自定义typeHandler
String typeHandler = properties.getTypeHandler();
if (StringUtil.isNotBlank(typeHandler)) {
if (applicationContext.containsBean(typeHandler)) {
sqlToyContext.setTypeHandler((TypeHandler) applicationContext.getBean(typeHandler));
} else // 包名和类名称
if (typeHandler.contains(".")) {
sqlToyContext.setTypeHandler((TypeHandler) Class.forName(typeHandler).getDeclaredConstructor().newInstance());
}
}
// 自定义数据源选择器
String dataSourceSelector = properties.getDataSourceSelector();
if (StringUtil.isNotBlank(dataSourceSelector)) {
if (applicationContext.containsBean(dataSourceSelector)) {
sqlToyContext.setDataSourceSelector((DataSourceSelector) applicationContext.getBean(dataSourceSelector));
} else // 包名和类名称
if (dataSourceSelector.contains(".")) {
sqlToyContext.setDataSourceSelector((DataSourceSelector) Class.forName(dataSourceSelector).getDeclaredConstructor().newInstance());
}
}
// 自定义数据库连接获取和释放的接口实现
String connectionFactory = properties.getConnectionFactory();
if (StringUtil.isNotBlank(connectionFactory)) {
if (applicationContext.containsBean(connectionFactory)) {
sqlToyContext.setConnectionFactory((ConnectionFactory) applicationContext.getBean(connectionFactory));
} else // 包名和类名称
if (connectionFactory.contains(".")) {
sqlToyContext.setConnectionFactory((ConnectionFactory) Class.forName(connectionFactory).getDeclaredConstructor().newInstance());
}
}
// 自定义字段安全实现器
String fieldsSecureProvider = properties.getFieldsSecureProvider();
if (StringUtil.isNotBlank(fieldsSecureProvider)) {
if (applicationContext.containsBean(fieldsSecureProvider)) {
sqlToyContext.setFieldsSecureProvider((FieldsSecureProvider) applicationContext.getBean(fieldsSecureProvider));
} else // 包名和类名称
if (fieldsSecureProvider.contains(".")) {
sqlToyContext.setFieldsSecureProvider((FieldsSecureProvider) Class.forName(fieldsSecureProvider).getDeclaredConstructor().newInstance());
}
}
// 自定义字段脱敏处理器
String desensitizeProvider = properties.getDesensitizeProvider();
if (StringUtil.isNotBlank(desensitizeProvider)) {
if (applicationContext.containsBean(desensitizeProvider)) {
sqlToyContext.setDesensitizeProvider((DesensitizeProvider) applicationContext.getBean(desensitizeProvider));
} else // 包名和类名称
if (desensitizeProvider.contains(".")) {
sqlToyContext.setDesensitizeProvider((DesensitizeProvider) Class.forName(desensitizeProvider).getDeclaredConstructor().newInstance());
}
}
return sqlToyContext;
}
Aggregations