Commit 0ba4686a authored by 覃振观's avatar 覃振观 👶

代码位置调整

parent 05fa5b26
/**
* 监听页面动作,维护数据映射及数据集
* 使用该方式,始终保持 java 对象的完整性。
* 最终只返回需要持久化的数据集合, 包含 Object, Array
* 当前主要使用遍历实现。
* 后期优化项目, window.dataSet.newData.backColors.compares 需要向外抛出、并且单独维护。
* @createDate 2019-04-12
......@@ -7,7 +9,7 @@
/**
* 遍历映射配置,构建映射关系
* 构建映射
* @param dataMapping 映射配置
* @param rawData 源数据:    若有此输入,将认为当前是更新动作、  无此输入则认为当前是插入动作
*/
......@@ -24,12 +26,19 @@ function buildMapping(dataMapping, rawData) {
return mapping(rawData);
}
/**
* 刷新映射, 数据非初始化时存在,需要调用此方法刷新映射
* @param dataMapping 映射配置
* @param beanName 需要刷新的 bean 名称
* @param data 该 bean 对应的数据
* @returns {{}}
*/
function refreshMapping(dataMapping, beanName, data) {
let rawData = window.dataSet.original, newData = window.dataSet.newData;
rawData[beanName] = data;
let currentData = newData[beanName];
data.forEach(item => {
currentMapping = window.dataMapping[beanName];
let currentMapping = window.dataMapping[beanName];
if(!currentMapping) {
console.error('找不到该映射,请检查映射配置是否存在该配置: ' + beanName);
return;
......@@ -48,6 +57,11 @@ function refreshMapping(dataMapping, beanName, data) {
return returnData;
}
/**
* 遍历映射配置,构建映射关系
* @param rawData
* @returns {{}}
*/
function mapping(rawData) {
let mapper = {}, returnData = {};
delete dataMapping.mapper;
......@@ -158,6 +172,11 @@ function testTryForEach() {
}
}
/**
* 若期望 forEach 可以直接跳出遍历 使用该方法。
* @param arrayObj
* @param callback
*/
const tryForEach = function(arrayObj, callback) {
try {
arrayObj.forEach(callback);
......@@ -205,20 +224,6 @@ function checkArrayMapper(str) {
return retrunData;
}
function onAfterEdit_(options) {
options.onAfterEdit = function(editParm) {
let gridId = editParm.column.__domid.split('|')[0], colName = editParm.column.columnname, rowNum = editParm.rowindex;
let editId = gridId + '_' + colName + '_' + rowNum;
debugger;
debugger;
// this.options.onBeforeCancelEdit.call(this, editParm)
// window.combox[editId].object.element = null;
// window.combox[editId].object.options = null;
}
}
/**
*     
* Grid 编辑前触发。 这里记录当前编辑框 对应的 Grid 行 rowIndex 和列 property <br> &nbsp;&nbsp;&nbsp;&nbsp;
......@@ -259,6 +264,12 @@ function onBeforeEdit_(options) {
}
}
/**
* 设置 Grid 编辑框栏目的样式
* @param eleId
* @param inputVal
* @param width
*/
function settingEditDomStyle(eleId, inputVal, width) {
let editor = window.dataGrid[eleId].editor;
if(!editor.editing) {
......@@ -340,8 +351,9 @@ function listeningSearchbox(elId, options, gridId) {
}
/**
* &nbsp;&nbsp;&nbsp;&nbsp;
* Gria 中的下拉框 用此方式初始化。此下拉框维护 dataSet, 显示值需要自己处理。
* Gria 中的下拉框 用此方式初始化。 <br> &nbsp;&nbsp;&nbsp;&nbsp;
* 实际值需要在 Grid 初始化配置中 columns 栏目里配置 editor: { type: 'select', fillProperty: 'colorId'} 。<br> &nbsp;&nbsp;&nbsp;&nbsp;
* fillProperty 即为该下拉框期望改变的属性。
* @param propertyName GridId_propertyName,需要以此定位到需要展开下拉框的栏目(临时)
* @param options
*/
......@@ -388,8 +400,7 @@ function listeningGrid(elId, options) {
options.data = data;
// ------------------ 编辑前 记录当前 cell ------------------
onBeforeEdit_(options);
// ------------------ 编辑后 销毁下拉框 ------------------
onAfterEdit_(options);
const toolbar = options.toolbar;
if(toolbar) {
toolbar.items
......@@ -399,7 +410,6 @@ function listeningGrid(elId, options) {
// 使用 gridManager 对象 可以省略 页面监听操作。需要修改。
const originalOnClick = but.click;
but.click = function() {
debugger;
let currentMapper = checkArrayMapper(elId);
let beanName = currentMapper.beanName;
let idProperty = currentMapper.property.id;
......@@ -435,21 +445,20 @@ function listeningGrid(elId, options) {
if(but.id === "menuDelete") {
const originalOnClick = but.click;
but.click = function() {
let selectRow = gridManager.getSelectedRow();
let selectRows = gridManager.getSelectedRows();
selectRows.forEach(row => {
let currentMapper = checkArrayMapper(gridManager.id);
let beanName = currentMapper.beanName;
let currentData = window.dataSet.newData[beanName];
let propertyId = window.dataMapping[beanName].id;
let currentId = selectRow[propertyId] + '';
delete currentData.compares[currentId];
currentData.ids = currentData.ids.filter(x => !currentId.includes(x));
let rowIndex = row.rowIndex + '';
delete currentData.compares[rowIndex];
currentData.ids = currentData.ids.filter(x => !rowIndex.includes(x));
currentMapper.property.columns.forEach(property => {
delete window.dataMapping.mapper['productFaceColorId'][beanName][currentId];
delete window.dataMapping.mapper[property][beanName][rowIndex];
});
gridManager.deleteSelectedRow();
debugger;
originalOnClick.call(this, selectRow, gridManager);
gridManager.deleteRow(row);
})
originalOnClick.call(this, selectRows, gridManager);
}
}
})
......@@ -527,18 +536,6 @@ function listenerContent(event) {
}
}
// function getControlType(beanMapping) {
// let control;
// // 这里根据 grid 与 form 的 mapper 数据结构差异判定。 需要优化
// debugger;
// if(Object.entries(beanMapping)[0][1]['listeningKey']) {
// control = 'grid';
// } else {
// control = 'form';
// }
// return control;
// }
/**
* 添加 DOM 监听
* @param eleId 监听的 root 元素 ID
......@@ -580,15 +577,22 @@ const gridEditor = function(event) {
// console.log('变化属性值 : ' + mutation.target.value);
const mutationConfig = { attributes: true, childList: true, subtree: true}
/**
* 检查页面数据集,返回需要持久化的集合。包含: <br> &nbsp;&nbsp;&nbsp;&nbsp;
* form 中做过修改的栏目,返回该栏目所映射的对象。 <br> &nbsp;&nbsp;&nbsp;&nbsp;
* grid 中做过修改的行,返回映射的对象集合。 <br> &nbsp;&nbsp;&nbsp;&nbsp;
* grid 中新增的行,返回映射的对象集合。 <br> &nbsp;&nbsp;&nbsp;&nbsp;
* grid 中删除的行,返回映射的对象集合。
* @returns {*|{}} { aEntity: {}, bArray: { add: [ bEntity: {} ] }, up: [ bEntity: {} ], del: [ bEntity: {} ] }
*/
function checkUpdata() {
let dataSet = window.dataSet;
let rawData = dataSet.rawData, newData = dataSet.newData;
window.dataSet.upData = {};
let rawEntry = Object.entries(rawData);
debugger;
tryForEach(rawEntry, entry => {
let beanName = entry[0];
console.log(beanName);
// console.log(beanName);
let mapping = window.dataMapping[beanName], raw = rawData[beanName], now = newData[beanName];
if(mapping instanceof Array) {
// Form 时 执行此逻辑
......@@ -605,19 +609,17 @@ function checkUpdata() {
let rawIds = raw.ids, nowIds = now.ids;
dataSet.upData[beanName] = {};
dataSet.upData[beanName].del = [];
debugger;
let delIds = rawIds.filter(x => !nowIds.includes(x));
tryForEach(delIds, id => {
dataSet.upData[beanName].del.push(rawCompares[id]);
delIds.forEach(rowIndex => {
dataSet.upData[beanName].del.push(rawCompares[rowIndex]);
});
dataSet.upData[beanName].add = []
let addIds = nowIds.filter(x => !rawIds.includes(x));
tryForEach(addIds, id => {
dataSet.upData[beanName].add.push(nowCompares[id]);
addIds.forEach(rowIndex => {
dataSet.upData[beanName].add.push(nowCompares[rowIndex]);
});
dataSet.upData[beanName].up = []
let nowEntry = Object.entries(nowCompares);
tryForEach(nowEntry, row => {
Object.entries(nowCompares).forEach(row => {
let key = row[0], rowNow = row[1];
if(rawCompares[key]) {
if(!(getHashCode(JSON.stringify(rawCompares[key])) === getHashCode(JSON.stringify(rowNow)))) {
......@@ -626,7 +628,7 @@ function checkUpdata() {
}
});
}
return ;
return;
}
})
return dataSet.upData;
......@@ -660,6 +662,18 @@ function getHashCode (str, caseSensitive) {
}
}
// function onAfterEdit_(options) {
// options.onAfterEdit = function(editParm) {
// let gridId = editParm.column.__domid.split('|')[0], colName = editParm.column.columnname, rowNum = editParm.rowindex;
// let editId = gridId + '_' + colName + '_' + rowNum;
// debugger;
// this.options.onBeforeCancelEdit.call(this, editParm)
// window.combox[editId].object.element = null;
// window.combox[editId].object.options = null;
// }
// }
//
// function onBeforeEdit_(options) {
// const originalOnBeforeEdit = options.onBeforeEdit;
......@@ -690,3 +704,16 @@ function getHashCode (str, caseSensitive) {
// originalOnBeforeEdit.call(this, editParm, '11');
// }
// }
// function getControlType(beanMapping) {
// let control;
// // 这里根据 grid 与 form 的 mapper 数据结构差异判定。 需要优化
// debugger;
// if(Object.entries(beanMapping)[0][1]['listeningKey']) {
// control = 'grid';
// } else {
// control = 'form';
// }
// return control;
// }
\ No newline at end of file
......@@ -223,9 +223,8 @@ function faceGrid(elId, data) {
});
var gridManager = listeningGrid(elId, {
columns: [
{ display: "颜色名称", name: "colorName", width: 140, minWidth: 60, type: "string", align: "left", editor: {
type: 'select', fillProperty: 'colorId'
}},
{ display: "颜色名称", name: "colorName", width: 140, minWidth: 60, type: "string", align: "left",
editor: { type: 'select', fillProperty: 'colorId'} },
{ display: "油墨覆盖率(%)", name: "coverageRate", width: 120, minWidth: 60, type: "string", align: "left", editor: { type: 'text'} }
],
toolbar: toolbarOptions,
......
......@@ -5,20 +5,16 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.huigou.topsun.product.application.ProductApplication;
import com.huigou.topsun.product.domain.*;
import com.huigou.topsun.product.repository.*;
import com.huigou.topsun.util.Snowflake;
import com.huigou.topsun.util.EntityConvertUtil;
import com.huigou.topsun.util.PersistTool;
import com.huigou.uasp.bmp.common.application.BaseApplication;
import lombok.RequiredArgsConstructor;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
......@@ -35,6 +31,8 @@ public class ProductApplicationImpl extends BaseApplication implements ProductAp
@PersistenceContext(unitName = "system")
private EntityManager entityManager;
private final PersistTool persist;
// private final EntityManagerFactory entityManagerFactory;
private final ObjectMapper objectMapper;
......@@ -100,7 +98,7 @@ public class ProductApplicationImpl extends BaseApplication implements ProductAp
entitys.add(product);
entitys.add(material);
Map<String, Object> assemble = assembleResultOfForm(entitys);
Map<String, Object> assemble = EntityConvertUtil.assembleResultOfForm(entitys);
resultMap.put("rawData", assemble);
assemble.put("productLoss", loss);
......@@ -208,15 +206,15 @@ public class ProductApplicationImpl extends BaseApplication implements ProductAp
entitys.add(productLooked);
entitys.add(productTechnology);
entitys.add(productPublishedConf);
persistEntitys(entitys);
persist.persistEntitys(entitys);
TypedQuery<Product> query = entityManager.createQuery("SELECT s FROM Product s", Product.class);
List<Product> products = query.getResultList();
entityManager.flush();
// String str = null;
// str.length();
String str = null;
str.length();
HashMap<String, Object> map = new HashMap<>(5);
map.put("save", "ok");
......@@ -253,268 +251,6 @@ public class ProductApplicationImpl extends BaseApplication implements ProductAp
return null;
}
/**
* description 持久化数据. <br>&nbsp;&nbsp;&nbsp;&nbsp;
* Entity 时,如果 ID 为空执行 Persist,否则执行 Merge <br>&nbsp;&nbsp;&nbsp;&nbsp;
* List 时,要求数据集格式 : <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
* HashMap {”add“: List< Entity >,”up“: List< Entity >,”del“: List< Entity >}
* @param entitys 持久化数据集合 Set { Entity, HashMap }
* @author qinzhenguan
* @createDate 2023/12/26 16:44
*/
public void persistEntitys(Set<Object> entitys) {
entitys = entitys.stream().filter(Objects::nonNull).collect(Collectors.toSet());
for(Object item : entitys) {
if(item instanceof Map) {
persistList(uncheckedCast(((Map<?, ?>) item).get("add")), "save");
persistList(uncheckedCast(((Map<?, ?>) item).get("up")), "save");
persistList(uncheckedCast(((Map<?, ?>) item).get("del")), "remove");
} else {
persistEntity(item);
}
entityManager.flush();
entityManager.clear();
}
}
/***
* description 持久化 List
* @param list 操作的 List
* @param type 操作类似 save, remove
* @author qinzhenguan
* @createDate 2023/12/26 16:33
*/
public void persistList(List<Class<?>> list, String type) {
if(list == null || list.isEmpty()) {
return;
}
for(int i= 0; i < list.size(); i++) {
if("remove".equals(type)) {
removeEntity(list.get(i));
} else {
persistEntity(list.get(i));
}
if(i % 80 == 0 || i == (list.size() - 1)) {
entityManager.flush();
entityManager.clear();
}
}
}
/***
* description 持久化实体 (无 ID 时执行插入,有 ID 时执行更新)
* @param entity 操作的 Entity
* @author qinzhenguan
* @createDate 2023/12/26 16:32
*/
public void persistEntity(Object entity) {
Class<?> clazz = entity.getClass();
for(Field field : clazz.getDeclaredFields()) {
if("id".equals(field.getName())) {
try {
field.setAccessible(true);
BigDecimal id = (BigDecimal) field.get(entity);
if(id == null){
field.set(entity, String.valueOf(Snowflake.nextId()));
entityManager.persist(entity);
} else {
entityManager.merge(entity);
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
}
/***
* description 移除实体
* @param entity 操作的 Entity
* @author qinzhenguan
* @createDate 2023/12/26 16:31
*/
public void removeEntity(Object entity) {
if(entity == null) { return; }
entityManager.remove(entity);
}
/**
* description 返回页面 Form 所需的数据格式
* @param entitys 所有相关的 实体。 必须为 JavaBean 调用了 .getClass().getSimpleName()
* @return java.util.HashMap<java.lang.String, java.lang.Object>
* @author qinzhenguan
* @createDate 2023/12/5 14:09
*/
public Map<String, Object> assembleResultOfForm(Set<Object> entitys) {
Map<String, Object> map = new HashMap<>(256);
for(Object item : entitys) {
if(item == null) {
continue;
}
if(item instanceof List) {
if(((List<?>) item).size() > 0) {
map.put((((List<?>) item).get(0)).getClass().getSimpleName(), objectMapper.convertValue(item, List.class));
}
} else {
map.put(item.getClass().getSimpleName(), objectMapper.convertValue(item, new TypeReference<Map<? extends String, ?>>() {}) );
}
// 这里要获取所有的属性名, 保存对应关系, 属性: 所属实体类;
//map.putAll(mapper.convertValue(item, new TypeReference<Map<? extends String, ?>>() {}));
}
return map;
}
/**
* description
* @param clazz Bean
* @param displayProperty 需要显示的属性
* @param valueProperty 连接的属性
* @param list 需要转换的 List
* @return java.util.Map<java.lang.Object, java.lang.Object>
* @author qinzhenguan
* @createDate 2023/12/1 16:09
*/
public Map<Object, Object> convertToMap(Class<?> clazz, String displayProperty, String valueProperty,
List<?> list) {
Set<String> set = new HashSet<>();
set.add(displayProperty);
set.add(valueProperty);
if(checkClassesAndProperties(clazz, set, list.size())) {
LinkedList<Map<String, Object>> mapList = objectMapper.convertValue(list, new TypeReference<LinkedList<Map<String, Object>>>() {});
return mapList.stream().collect(Collectors.toMap(map -> map.get(displayProperty), map -> map.get(valueProperty),
(oldV, newV) -> oldV));
}
return null;
}
/**
* description 只检查传入属性是否合法
* @param clazz Bean
* @param set 需要检查的 Propertys
* @param listSize 需要检查的 ListSize
* @return java.lang.Boolean true of false
* @author qinzhenguan
* @createDate 2023/12/1 15:58
*/
public Boolean checkClassesAndProperties(Class<?> clazz, Set<String> set, int listSize) {
if(listSize == 0) {
System.err.println("[checkClassesAndProperties] : List< "+clazz.getName()+" > 需要转换的列表没有元素。请检查~!");
return false;
}
Field[] fields = clazz.getDeclaredFields();
Method[] methods = clazz.getDeclaredMethods();
for(String item : set) {
Field field = Arrays.stream(fields).filter(f -> item.equals(f.getName())).findFirst().orElse(null);
if(field == null) {
System.err.println("[checkClassesAndProperties] : " + clazz.getName() + " 无法找到 : " + item + " " +
"该属性。请检查~!");
return false;
}
Method method = Arrays.stream(methods)
.filter(m -> m.getName().toLowerCase().contains("get" + item.toLowerCase())).findFirst().orElse(null);
if (method == null) {
System.err.println("[checkClassesAndProperties] : " + item + " 该属性无法找到构造方法。请检查~!");
return false;
}
}
return true;
}
/**
* description 转换成 Map 不需要转换为实体
* @param clazz Bean
* @param propertyName 连接的 property
* @param list 需要转换的 List
* @return java.util.Map<java.lang.Object, java.lang.Object>
* @author qinzhenguan
* @createDate 2023/11/29 11:36
*/
public Map<Object, Object> convertToMap(Class<?> clazz, String propertyName, List<?> list) {
return convertToMap(clazz, propertyName, list, false);
}
/**
* description 转换成 Map 保留映射
* @param clazz Bean
* @param propertyName 连接的 property
* @param list 需要转换的 List
* @param isBean 是否需要转换为实体 (当前应用不需要返回实体)
* @return java.util.Map<java.lang.Object, java.lang.Object>
* @author qinzhenguan
* @createDate 2023/11/29 11:34
*/
public Map<Object, Object> convertToMap(Class<?> clazz, String propertyName, List<?> list, boolean isBean) {
Map<String, Object> checkMap = checkClassesAndProperties(clazz, propertyName, list.size());
String ok = "isOk";
if(!(Boolean) checkMap.get(ok)) {
return null;
}
Method method = (Method) checkMap.get("method");
LinkedList<Map<String, Object>> mapList = objectMapper.convertValue(list, new TypeReference<LinkedList<Map<String, Object>>>() {});
Map<Object, Object> resultMap = new HashMap<>(10);
Map<Object, Object> convert = new HashMap<>(1024);
if(isBean) {
// --------------------------------- 实体 ---------------------------------
try {
for (int i = 0; i < mapList.size(); i++) {
Object o = clazz.newInstance();
BeanUtils.populate(o, mapList.get(i));
Object key = method.invoke(o);
convert.put(key, o);
}
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
} else {
// --------------------------------- 非实体 ---------------------------------
convert = mapList.stream().collect(Collectors.toMap(map -> map.get(propertyName), Function.identity(),
(oldV, newV) -> oldV));
//此处仍需处理 Key == null;
}
resultMap.put("map", convert);
resultMap.put("list", list);
return resultMap;
}
/**
* description 检查传入参数是否合法 并返回构造方法
*
* @param clazz javaBean
* @param propertyName property
* @return java.util.HashMap<java.lang.String, java.lang.Object> { "isOk" : 是否通过检查, "method":获取得到的 method }
* @author qinzhenguan
* @createDate 2023/11/29 11:05
*/
public HashMap<String, Object> checkClassesAndProperties(Class<?> clazz, String propertyName, int listSize) {
HashMap<String, Object> map = new HashMap<>(33);
if(listSize == 0) {
System.err.println("[checkClassesAndProperties] : List< "+clazz.getName()+" > 需要转换的列表没有元素。请检查~!");
map.put("isOk", false);
return map;
}
Field[] fields = clazz.getDeclaredFields();
Field field = Arrays.stream(fields).filter(f -> propertyName.equals(f.getName())).findFirst().orElse(null);
if(field == null) {
System.err.println("[checkClassesAndProperties] : " + clazz.getName() + " 无法找到 : " + propertyName + " " +
"该属性。请检查~!");
map.put("isOk", false);
return map;
}
Method[] methods = clazz.getDeclaredMethods();
Method method = Arrays.stream(methods)
.filter(m -> m.getName().toLowerCase().contains("get" + propertyName.toLowerCase())).findFirst().orElse(null);
if (method == null) {
System.err.println("[checkClassesAndProperties] : " + propertyName + " 该属性无法找到构造方法。请检查~!");
map.put("isOk", false);
return map;
}
map.put("isOk", true);
map.put("method", method);
return map;
}
public HashMap<String, Object> convertToFaceColors(Map<String, ArrayList<Map<String, Object>>> map) {
if(map == null) {
return null;
......@@ -569,6 +305,8 @@ public class ProductApplicationImpl extends BaseApplication implements ProductAp
return objectMapper.convertValue(list, new TypeReference<ArrayList<ProductLoss>>() {});
}
}
// resultMap.put("selectedBrand", convertToMap(Brand.class, "brandName", "brandId", brands));
......
package com.huigou.topsun.util;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.beanutils.BeanUtils;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* EntityConvertUtil 数据类型转换工具
*
* @author qinzhenguan
* @createDate 2023/12/30 10:56
**/
public class EntityConvertUtil {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
/**
* description 返回页面 Form 所需的数据格式
* @param entitys 所有相关的 实体。 必须为 JavaBean 调用了 .getClass().getSimpleName()
* @return java.util.HashMap<java.lang.String, java.lang.Object>
* @author qinzhenguan
* @createDate 2023/12/5 14:09
*/
public static Map<String, Object> assembleResultOfForm(Set<Object> entitys) {
Map<String, Object> map = new HashMap<>(256);
for(Object item : entitys) {
if(item == null) {
continue;
}
if(item instanceof List) {
if(((List<?>) item).size() > 0) {
map.put((((List<?>) item).get(0)).getClass().getSimpleName(), OBJECT_MAPPER.convertValue(item, List.class));
}
} else {
map.put(item.getClass().getSimpleName(), OBJECT_MAPPER.convertValue(item, new TypeReference<Map<? extends String, ?>>() {}) );
}
// 这里要获取所有的属性名, 保存对应关系, 属性: 所属实体类;
//map.putAll(mapper.convertValue(item, new TypeReference<Map<? extends String, ?>>() {}));
}
return map;
}
/**
* description
* @param clazz Bean
* @param displayProperty 需要显示的属性
* @param valueProperty 连接的属性
* @param list 需要转换的 List
* @return java.util.Map<java.lang.Object, java.lang.Object>
* @author qinzhenguan
* @createDate 2023/12/1 16:09
*/
public static Map<Object, Object> convertToMap(Class<?> clazz, String displayProperty, String valueProperty,
List<?> list) {
Set<String> set = new HashSet<>();
set.add(displayProperty);
set.add(valueProperty);
if(checkClassesAndProperties(clazz, set, list.size())) {
LinkedList<Map<String, Object>> mapList = OBJECT_MAPPER.convertValue(list, new TypeReference<LinkedList<Map<String, Object>>>() {});
return mapList.stream().collect(Collectors.toMap(map -> map.get(displayProperty), map -> map.get(valueProperty),
(oldV, newV) -> oldV));
}
return null;
}
/**
* description 只检查传入属性是否合法
* @param clazz Bean
* @param set 需要检查的 Propertys
* @param listSize 需要检查的 ListSize
* @return java.lang.Boolean true of false
* @author qinzhenguan
* @createDate 2023/12/1 15:58
*/
public static Boolean checkClassesAndProperties(Class<?> clazz, Set<String> set, int listSize) {
if(listSize == 0) {
System.err.println("[checkClassesAndProperties] : List< "+clazz.getName()+" > 需要转换的列表没有元素。请检查~!");
return false;
}
Field[] fields = clazz.getDeclaredFields();
Method[] methods = clazz.getDeclaredMethods();
for(String item : set) {
Field field = Arrays.stream(fields).filter(f -> item.equals(f.getName())).findFirst().orElse(null);
if(field == null) {
System.err.println("[checkClassesAndProperties] : " + clazz.getName() + " 无法找到 : " + item + " " +
"该属性。请检查~!");
return false;
}
Method method = Arrays.stream(methods)
.filter(m -> m.getName().toLowerCase().contains("get" + item.toLowerCase())).findFirst().orElse(null);
if (method == null) {
System.err.println("[checkClassesAndProperties] : " + item + " 该属性无法找到构造方法。请检查~!");
return false;
}
}
return true;
}
/**
* description 转换成 Map 不需要转换为实体
* @param clazz Bean
* @param propertyName 连接的 property
* @param list 需要转换的 List
* @return java.util.Map<java.lang.Object, java.lang.Object>
* @author qinzhenguan
* @createDate 2023/11/29 11:36
*/
public static Map<Object, Object> convertToMap(Class<?> clazz, String propertyName, List<?> list) {
return convertToMap(clazz, propertyName, list, false);
}
/**
* description 转换成 Map 保留映射
* @param clazz Bean
* @param propertyName 连接的 property
* @param list 需要转换的 List
* @param isBean 是否需要转换为实体 (当前应用不需要返回实体)
* @return java.util.Map<java.lang.Object, java.lang.Object>
* @author qinzhenguan
* @createDate 2023/11/29 11:34
*/
public static Map<Object, Object> convertToMap(Class<?> clazz, String propertyName, List<?> list, boolean isBean) {
Map<String, Object> checkMap = checkClassesAndProperties(clazz, propertyName, list.size());
String ok = "isOk";
if(!(Boolean) checkMap.get(ok)) {
return null;
}
Method method = (Method) checkMap.get("method");
LinkedList<Map<String, Object>> mapList = OBJECT_MAPPER.convertValue(list, new TypeReference<LinkedList<Map<String, Object>>>() {});
Map<Object, Object> resultMap = new HashMap<>(10);
Map<Object, Object> convert = new HashMap<>(1024);
if(isBean) {
// --------------------------------- 实体 ---------------------------------
try {
for (int i = 0; i < mapList.size(); i++) {
Object o = clazz.newInstance();
BeanUtils.populate(o, mapList.get(i));
Object key = method.invoke(o);
convert.put(key, o);
}
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
} else {
// --------------------------------- 非实体 ---------------------------------
convert = mapList.stream().collect(Collectors.toMap(map -> map.get(propertyName), Function.identity(),
(oldV, newV) -> oldV));
//此处仍需处理 Key == null;
}
resultMap.put("map", convert);
resultMap.put("list", list);
return resultMap;
}
/**
* description 检查传入参数是否合法 并返回构造方法
*
* @param clazz javaBean
* @param propertyName property
* @return java.util.HashMap<java.lang.String, java.lang.Object> { "isOk" : 是否通过检查, "method":获取得到的 method }
* @author qinzhenguan
* @createDate 2023/11/29 11:05
*/
public static HashMap<String, Object> checkClassesAndProperties(Class<?> clazz, String propertyName, int listSize) {
HashMap<String, Object> map = new HashMap<>(33);
if(listSize == 0) {
System.err.println("[checkClassesAndProperties] : List< "+clazz.getName()+" > 需要转换的列表没有元素。请检查~!");
map.put("isOk", false);
return map;
}
Field[] fields = clazz.getDeclaredFields();
Field field = Arrays.stream(fields).filter(f -> propertyName.equals(f.getName())).findFirst().orElse(null);
if(field == null) {
System.err.println("[checkClassesAndProperties] : " + clazz.getName() + " 无法找到 : " + propertyName + " " +
"该属性。请检查~!");
map.put("isOk", false);
return map;
}
Method[] methods = clazz.getDeclaredMethods();
Method method = Arrays.stream(methods)
.filter(m -> m.getName().toLowerCase().contains("get" + propertyName.toLowerCase())).findFirst().orElse(null);
if (method == null) {
System.err.println("[checkClassesAndProperties] : " + propertyName + " 该属性无法找到构造方法。请检查~!");
map.put("isOk", false);
return map;
}
map.put("isOk", true);
map.put("method", method);
return map;
}
}
\ No newline at end of file
package com.huigou.topsun.util;
import org.springframework.stereotype.Component;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
* PersistUtil 持久化工具
*
* @author qinzhenguan
* @createDate 2023/12/30 10:49
**/
@Component
public class PersistTool {
@PersistenceContext(unitName = "system")
private EntityManager entityManager;
/**
* description 持久化数据. <br>&nbsp;&nbsp;&nbsp;&nbsp;
* Entity 时,如果 ID 为空执行 Persist,否则执行 Merge <br>&nbsp;&nbsp;&nbsp;&nbsp;
* List 时,要求数据集格式 : <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
* HashMap {”add“: List< Entity >,”up“: List< Entity >,”del“: List< Entity >}
* @param entitys 持久化数据集合 Set { Entity, HashMap }
* @author qinzhenguan
* @createDate 2023/12/26 16:44
*/
public void persistEntitys(Set<Object> entitys) {
entitys = entitys.stream().filter(Objects::nonNull).collect(Collectors.toSet());
for(Object item : entitys) {
if(item instanceof Map) {
persistList(uncheckedCast(((Map<?, ?>) item).get("add")), "save");
persistList(uncheckedCast(((Map<?, ?>) item).get("up")), "save");
persistList(uncheckedCast(((Map<?, ?>) item).get("del")), "remove");
} else {
persistEntity(item);
}
entityManager.flush();
entityManager.clear();
}
}
/***
* description 持久化 List
* @param list 操作的 List
* @param type 操作类似 save, remove
* @author qinzhenguan
* @createDate 2023/12/26 16:33
*/
public void persistList(List<Class<?>> list, String type) {
if(list == null || list.isEmpty()) {
return;
}
for(int i= 0; i < list.size(); i++) {
if("remove".equals(type)) {
removeEntity(list.get(i));
} else {
persistEntity(list.get(i));
}
if(i % 80 == 0 || i == (list.size() - 1)) {
entityManager.flush();
entityManager.clear();
}
}
}
/***
* description 持久化实体 (无 ID 时执行插入,有 ID 时执行更新)
* @param entity 操作的 Entity
* @author qinzhenguan
* @createDate 2023/12/26 16:32
*/
public void persistEntity(Object entity) {
Class<?> clazz = entity.getClass();
for(Field field : clazz.getDeclaredFields()) {
if("id".equals(field.getName())) {
try {
field.setAccessible(true);
BigDecimal id = (BigDecimal) field.get(entity);
if(id == null){
field.set(entity, String.valueOf(Snowflake.nextId()));
entityManager.persist(entity);
} else {
entityManager.merge(entity);
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
}
/***
* description 移除实体
* @param entity 操作的 Entity
* @author qinzhenguan
* @createDate 2023/12/26 16:31
*/
public void removeEntity(Object entity) {
if(entity == null) { return; }
entityManager.remove(entity);
}
@SuppressWarnings("unchecked")
public static <T> T uncheckedCast(Object obj) {
if(obj != null) {
return (T) obj;
}
return null;
}
}
\ No newline at end of file
......@@ -28,6 +28,11 @@ public class TestSnowflake {
}
/**
* description 测试当前生成策略极限。
* @author qinzhenguan
* @createDate 2023/12/30 10:42
*/
public void generateTest()throws InterruptedException {
TreadA t1 = new TreadA();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment