Commit 2c1d735a authored by trumansdo's avatar trumansdo
Browse files

待完成映射数据结构的结果集处理

parent f62477cf
......@@ -2,17 +2,26 @@ import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ibeetl.admin.ConsoleApplication;
import com.ibeetl.admin.core.conf.handler.DateTypeHandler;
import com.ibeetl.admin.core.conf.handler.ZonedDateTimeTypeHandler;
import com.ibeetl.admin.core.dao.CoreFunctionDao;
import com.ibeetl.admin.core.entity.CoreRoute;
import com.ibeetl.admin.core.entity.CoreRouteMeta;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.mapping.type.JavaSqlTypeHandler;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import resultmap.GridContainer;
import processor.JsonBeanProcessor;
import resultmap.GridHeader;
import resultmap.GridMapping;
import resultmap.GridRow;
......@@ -23,50 +32,72 @@ public class CustomBeanProcessorTest {
@Autowired CoreFunctionDao coreFunctionDao;
static JSONObject resultMap;
@Autowired
@Qualifier("baseDataSourceSqlManagerFactoryBean")
SQLManager sqlManager;
static JSONObject resultMappping;
@BeforeClass
public static void init() {
resultMap = new JSONObject();
resultMap.put("id", "core_route_map");
resultMappping = new JSONObject();
resultMappping.put("id", "core_route_map");
JSONObject routeMapping = new JSONObject();
routeMapping.put("id", "id");
routeMapping.put("parentId", "parent_id");
routeMapping.put("path", "path");
routeMapping.put("name", "name");
routeMapping.put("seq", "seq");
JSONObject mapping = new JSONObject();
mapping.put("id", "id");
mapping.put("parentId", "parent_id");
mapping.put("path", "path");
mapping.put("name", "name");
mapping.put("seq", "seq");
JSONObject metaMapping = new JSONObject();
metaMapping.put("title", "title");
metaMapping.put("icon", "icon");
JSONObject objMap = new JSONObject();
objMap.put("title", "title");
objMap.put("icon", "icon");
JSONArray roles = new JSONArray();
JSONObject roleidMapping = new JSONObject();
roleidMapping.put("id", "role_id");
roles.add(roleidMapping);
JSONArray listMap = new JSONArray();
JSONObject listInnerMap = new JSONObject();
listInnerMap.put("id", "role_id");
listMap.add(listInnerMap);
objMap.put("roles", listMap);
metaMapping.put("roles", roles);
metaMapping.put("resultType", CoreRouteMeta.class.getCanonicalName());
objMap.put("resultType", CoreRouteMeta.class.getCanonicalName());
JSONObject testMapping = new JSONObject();
testMapping.put("id", "test_id");
testMapping.put("name", "name");
testMapping.put("password", "password");
testMapping.put("resultType", entity.Test.class.getCanonicalName());
mapping.put("meta", objMap);
mapping.put("resultType", CoreRoute.class.getCanonicalName());
routeMapping.put("test", testMapping);
routeMapping.put("meta", metaMapping);
routeMapping.put("resultType", CoreRoute.class.getCanonicalName());
resultMappping.put("mapping", routeMapping);
}
resultMap.put("mapping", mapping);
@Before
public void beanProcessor() {
JsonBeanProcessor jsonBeanProcessor = new JsonBeanProcessor(sqlManager);
sqlManager.setDefaultBeanProcessors(jsonBeanProcessor);
Map<Class, JavaSqlTypeHandler> typeHandlerMap =
sqlManager.getDefaultBeanProcessors().getHandlers();
/*Java bean的属性类型处理器,从数据库类型转化到属性Date类型*/
typeHandlerMap.remove(Date.class);
typeHandlerMap.put(Date.class, new DateTypeHandler());
typeHandlerMap.put(ZonedDateTime.class, new ZonedDateTimeTypeHandler());
}
@Test
public void maptest() {
List<CoreRoute> routesList = coreFunctionDao.getAllRoutes();
System.out.println(JSONUtil.toJsonPrettyStr(resultMap));
GridMapping gridMapping = new GridMapping(resultMap);
System.out.println(routesList);
System.out.println(JSONUtil.toJsonPrettyStr(resultMappping));
GridMapping gridMapping = new GridMapping(resultMappping);
GridHeader gridHeader = gridMapping.getHeader();
System.out.println(gridHeader);
GridRow gridRow = new GridRow(gridHeader);
GridRow gridRow = GridRow.generateRowInnerBox(gridHeader);
System.out.println(gridRow);
GridContainer gridContainer = new GridContainer();
gridMapping.setContainer(gridContainer);
}
}
package entity;
import lombok.Data;
@Data
public class Test {
private String id;
private String name;
private String password;
}
package processor;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.mapping.BeanProcessor;
public class JsonBeanProcessor extends BeanProcessor {
public JsonBeanProcessor(SQLManager sm) {
super(sm);
}
}
package resultmap;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
* 网格格子,结果集映射的java类型中的基本类型属性,都应该在一个格子中。<br/>
* 非基本类型的属性字段,应该内嵌一个网格容器
* <br/>
* 包含:值映射map、映射类型、最关键的obj key<br/>
* 网格列,结果集映射的java类型中的基本类型属性,都应该在一个列中。<br>
* 非基本类型的属性字段,应该内嵌多行 <br>
* 包含:值映射map、映射类型、最关键的obj key<br>
* objkey 决定了数据库结果集的多条重复记录会被唯一记录成一个对象。
* */
public class GridBox extends GridContainer {
*/
public class GridColumn {
/** 对应的属性与数据库中值的映射,用于map to Bean 转换 */
Map<String, Object> beanMap;
/** 映射类型*/
/** 映射类型 */
String resultType;
/** 数据库记录对应的唯一key,用 beanMap 中所有非null值的hashcode相加得出*/
String objKey;
/** 数据库记录对应的唯一key,用 beanMap 中所有非null值的hashcode相加得出 */
Integer objKey;
/** 嵌套的网格容器,说明结果集的映射中有个集合属性字段*/
GridContainer nestedContainer;
/** 包含的网格*/
List<GridRow> nestedRows = CollUtil.<GridRow>newArrayList();
/** 归属的网格行 */
GridRow belongRow;
public Map<String, Object> getBeanMap() {
......@@ -41,20 +47,34 @@ public class GridBox extends GridContainer {
this.resultType = resultType;
}
public String getObjKey() {
public Integer getObjKey() {
int hs = 0;
if (CollUtil.isNotEmpty(nestedRows)) {
for (GridRow nestedRow : nestedRows) {
hs = hs + nestedRow.getRowKey();
}
} else {
Set<Entry<String, Object>> entrySet = beanMap.entrySet();
for (Entry<String, Object> entry : entrySet) {
if (ObjectUtil.isNull(entry.getValue())) continue;
hs += entry.getValue().hashCode();
}
}
hs = hs / RandomUtil.randomInt(100);
objKey = hs;
return objKey;
}
public void setObjKey(String objKey) {
public void setObjKey(Integer objKey) {
this.objKey = objKey;
}
public GridContainer getNestedContainer() {
return nestedContainer;
public List<GridRow> getNestedRows() {
return nestedRows;
}
public void setNestedContainer(GridContainer nestedContainer) {
this.nestedContainer = nestedContainer;
public void setNestedRows(List<GridRow> nestedRows) {
this.nestedRows = nestedRows;
}
public GridRow getBelongRow() {
......@@ -64,4 +84,4 @@ public class GridBox extends GridContainer {
public void setBelongRow(GridRow belongRow) {
this.belongRow = belongRow;
}
}
\ No newline at end of file
}
......@@ -4,6 +4,7 @@ import static cn.hutool.core.util.StrUtil.EMPTY;
import static cn.hutool.core.util.StrUtil.isNotBlank;
import static java.util.Optional.ofNullable;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ClassUtil;
import java.util.HashMap;
......@@ -25,7 +26,7 @@ public class GridHeader {
String resultType;
/** 嵌套类型的网格头 */
GridHeader nestedHeader;
List<GridHeader> nestedHeaders = CollUtil.<GridHeader>newArrayList();
/** 嵌套类型的网格头 */
GridHeader parentHeader;
......@@ -60,12 +61,12 @@ public class GridHeader {
this.resultType = resultType;
}
public GridHeader getNestedHeader() {
return nestedHeader;
public List<GridHeader> getNestedHeaders() {
return nestedHeaders;
}
public void setNestedHeader(GridHeader nestedHeader) {
this.nestedHeader = nestedHeader;
public void setNestedHeaders(List<GridHeader> nestedHeaders) {
this.nestedHeaders = nestedHeaders;
}
public GridHeader getParentHeader() {
......@@ -103,6 +104,7 @@ public class GridHeader {
private void processResultMapping(Map<String, Object> resultMapping) {
Set<Entry<String, Object>> entrySet = resultMapping.entrySet();
this.setResultType(ofNullable(resultMapping.get("resultType")).orElse(EMPTY).toString());
resultMapping.remove("resultType");
for (Entry<String, Object> objectEntry : entrySet) {
String key = objectEntry.getKey();
Object value = objectEntry.getValue();
......@@ -115,7 +117,7 @@ public class GridHeader {
nestedHeader.setIsCollection(true);
nestedHeader.setNestedPropName(key);
nestedHeader.setBelongMapping(this.getBelongMapping());
this.setNestedHeader(nestedHeader);
this.getNestedHeaders().add(nestedHeader);
nestedHeader.setParentHeader(this);
} else if (Map.class.isAssignableFrom(valClass)) {
/*生成嵌套网格头,此嵌套网格头的类型对应单个对象字段*/
......@@ -124,7 +126,7 @@ public class GridHeader {
nestedHeader.setIsCollection(false);
nestedHeader.setNestedPropName(key);
nestedHeader.setBelongMapping(this.getBelongMapping());
this.setNestedHeader(nestedHeader);
this.getNestedHeaders().add(nestedHeader);
nestedHeader.setParentHeader(this);
} else if (isNotBlank(key) || (null != value && isNotBlank(String.valueOf(value)))) {
javaToJdbcMap.put(key, String.valueOf(value));
......
......@@ -6,10 +6,11 @@ import static java.util.Optional.ofNullable;
import cn.hutool.core.lang.Assert;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import java.util.List;
import java.util.Map;
/** 网格映射数据结构: 包含一个网格头 {@link GridHeader}和网格容器/体{@link GridContainer} */
public class GridMapping extends GridContainer {
/** 网格映射数据结构: 包含一个网格头 {@link GridHeader} */
public class GridMapping {
/** 映射id */
String mappingId;
......@@ -19,8 +20,7 @@ public class GridMapping extends GridContainer {
/** 网格头 */
GridHeader header;
/** 网格容器 */
GridContainer container;
List<GridRow> nestedRows;
public GridMapping(Map<String, Object> resultMapping) {
JSON parse = JSONUtil.parse(resultMapping);
......@@ -42,15 +42,6 @@ public class GridMapping extends GridContainer {
this.header.setBelongMapping(this);
}
public GridContainer getContainer() {
return container;
}
public void setContainer(GridContainer container) {
this.container = container;
this.container.setParentContainer(this);
}
public String getMappingId() {
return mappingId;
}
......@@ -66,4 +57,12 @@ public class GridMapping extends GridContainer {
public void setResultType(String resultType) {
this.resultType = resultType;
}
public List<GridRow> getNestedRows() {
return nestedRows;
}
public void setNestedRows(List<GridRow> nestedRows) {
this.nestedRows = nestedRows;
}
}
......@@ -3,45 +3,36 @@ package resultmap;
import static java.util.Optional.ofNullable;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import java.util.List;
import java.util.Optional;
import javax.swing.text.html.Option;
/** 网格行,包含一个个格子<br> */
/**
* 网格行,包含一个个网格列<br>
* 一行一个对象,或者java类中的一个对象字段
*/
public class GridRow {
/** 包含的格子 */
List<GridBox> gridBoxes = CollUtil.<GridBox>newArrayList();
/** 包含的 */
List<GridColumn> nestedColumns = CollUtil.<GridColumn>newArrayList();
GridBox rowObjBox;
/** 所属的列 */
GridColumn belongColumn;
/** 映射类型 */
/** 映射对象的类型 */
String resultType;
String rowKey;
GridContainer belongContainer;
Integer rowKey;
public GridRow() {}
public GridRow(GridHeader gridHeader) {
rowObjBox.setResultType(gridHeader.getResultType());
rowObjBox.setBelongRow(this);
generateGridRow(gridHeader);
}
public List<GridBox> getGridBoxes() {
return gridBoxes;
}
public void setGridBoxes(List<GridBox> gridBoxes) {
this.gridBoxes = gridBoxes;
}
public GridBox getRowObjBox() {
return rowObjBox;
public List<GridColumn> getNestedColumns() {
return nestedColumns;
}
public void setRowObjBox(GridBox rowObjBox) {
this.rowObjBox = rowObjBox;
public void setNestedColumns(List<GridColumn> nestedColumns) {
this.nestedColumns = nestedColumns;
}
public String getResultType() {
......@@ -52,19 +43,25 @@ public class GridRow {
this.resultType = resultType;
}
public String getRowKey() {
public Integer getRowKey() {
int hs = 0;
for (GridColumn nestedColumn : nestedColumns) {
hs = hs + nestedColumn.getObjKey();
}
rowKey = hs;
return rowKey;
}
public void setRowKey(String rowKey) {
public void setRowKey(Integer rowKey) {
this.rowKey = rowKey;
}
public GridContainer getBelongContainer() {
return belongContainer;
public GridColumn getBelongColumn() {
return belongColumn;
}
public void setBelongContainer(GridContainer belongContainer) {
this.belongContainer = belongContainer;
public void setBelongColumn(GridColumn belongColumn) {
this.belongColumn = belongColumn;
}
/**
......@@ -72,35 +69,29 @@ public class GridRow {
*
* @return
*/
private GridBox generateGridRow(GridHeader gridHeader) {
ofNullable(gridHeader.getNestedHeader())
.ifPresent(
nestedHeader -> {
generateGridRow(nestedHeader);
});
GridBox gridBox = new GridBox();
if (gridHeader.getIsCollection()) {
GridContainer nestedContainer = new GridContainer();
GridRow nestedRow = new GridRow();
GridBox nestedBox = new GridBox();
nestedContainer.getGridRows().add(nestedRow);
nestedContainer.setParentContainer(gridBox);
public static GridRow generateRowInnerBox(GridHeader gridHeader) {
if (ObjectUtil.isNull(gridHeader)) {
return null;
}
GridRow gridRow = new GridRow();
GridColumn gridColumn = new GridColumn();
gridRow.getNestedColumns().add(gridColumn);
gridColumn.setBelongRow(gridRow);
nestedRow.getGridBoxes().add(nestedBox);
List<GridHeader> headers = gridHeader.getNestedHeaders();
for (GridHeader header : headers) {
GridColumn containerColumn = new GridColumn();
GridRow nestedRow = generateRowInnerBox(header);
nestedBox.setBelongRow(nestedRow);
nestedBox.setResultType(gridHeader.getResultType());
containerColumn.getNestedRows().add(nestedRow);
nestedRow.setBelongColumn(containerColumn);
/*嵌套和非嵌套只能存在一个*/
gridBox.setNestedContainer(nestedContainer);
gridBox.setBeanMap(null);
} else {
gridBox.setResultType(gridHeader.getResultType());
gridRow.getNestedColumns().add(containerColumn);
containerColumn.setBelongRow(gridRow);
}
return gridBox;
gridColumn.setResultType(gridHeader.getResultType());
gridRow.setResultType(gridHeader.getResultType());
return gridRow;
}
}
package com.ibeetl.admin.core.conf;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ibeetl.admin.core.conf.handler.DateTypeHandler;
import com.ibeetl.admin.core.conf.handler.ZonedDateTimeTypeHandler;
import com.ibeetl.admin.core.rbac.DataAccess;
import com.ibeetl.admin.core.rbac.DataAccessFactory;
import com.ibeetl.admin.core.service.CorePlatformService;
......@@ -21,11 +21,6 @@ import com.ibeetl.admin.core.web.query.QueryParser;
import com.ibeetl.starter.BeetlTemplateCustomize;
import com.ibeetl.starter.ObjectMapperJsonUtil;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.List;
......@@ -38,7 +33,6 @@ import org.beetl.ext.simulate.WebSimulate;
import org.beetl.sql.core.InterceptorContext;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.mapping.type.JavaSqlTypeHandler;
import org.beetl.sql.core.mapping.type.TypeParameter;
import org.beetl.sql.ext.DebugInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
......@@ -89,7 +83,8 @@ public class BeetlConf {
@Bean
public SQLManager sqlManager(
@Qualifier("baseDataSourceSqlManagerFactoryBean") SQLManager sqlManager) {
Map<Class, JavaSqlTypeHandler> typeHandlerMap = sqlManager.getDefaultBeanProcessors().getHandlers();
Map<Class, JavaSqlTypeHandler> typeHandlerMap =
sqlManager.getDefaultBeanProcessors().getHandlers();
/*Java bean的属性类型处理器,从数据库类型转化到属性Date类型*/
typeHandlerMap.remove(Date.class);
typeHandlerMap.put(Date.class, new DateTypeHandler());
......@@ -185,43 +180,4 @@ public class BeetlConf {
return;
}
}
class DateTypeHandler extends JavaSqlTypeHandler {
@Override
public Object getValue(TypeParameter typePara) throws SQLException {
if (ObjectUtil.isNull(typePara.getRs().getObject(typePara.getIndex()))) {
return null;
}
int columnType = typePara.getColumnType();
if (Types.TIMESTAMP == columnType || Types.DATE == columnType) {
Timestamp timestamp = typePara.getRs().getTimestamp(typePara.getIndex());
return Date.from(Instant.ofEpochSecond(timestamp.getTime()));
} else if (Types.BIGINT == columnType) {
long timestamp = Convert.toLong(typePara.getRs().getLong(typePara.getIndex()), 0L);
return Date.from(Instant.ofEpochSecond(timestamp));
} else {
return null;
}
}
}
class ZonedDateTimeTypeHandler extends JavaSqlTypeHandler {
@Override
public Object getValue(TypeParameter typePara) throws SQLException {
if (ObjectUtil.isNull(typePara.getRs().getObject(typePara.getIndex()))) {
return null;
}
int columnType = typePara.getColumnType();
if (Types.TIMESTAMP == columnType || Types.DATE == columnType) {
Timestamp timestamp = typePara.getRs().getTimestamp(typePara.getIndex());
return ZonedDateTime
.ofInstant(Instant.ofEpochSecond(timestamp.getTime()), ZoneId.systemDefault());
} else if (Types.BIGINT == columnType) {
long timestamp = Convert.toLong(typePara.getRs().getLong(typePara.getIndex()), 0L);
return ZonedDateTime
.ofInstant(Instant.ofEpochSecond(timestamp), ZoneId.systemDefault());
} else {
return null;
}
}
}
}
}
\ No newline at end of file
package com.ibeetl.admin.core.conf.handler;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant;
import java.util.Date;
import org.beetl.sql.core.mapping.type.JavaSqlTypeHandler;
import org.beetl.sql.core.mapping.type.TypeParameter;
public class DateTypeHandler extends JavaSqlTypeHandler {
@Override
public Object getValue(TypeParameter typePara) throws SQLException {
if (ObjectUtil.isNull(typePara.getRs().getObject(typePara.getIndex()))) {
return null;
}
int columnType = typePara.getColumnType();
if (Types.TIMESTAMP == columnType || Types.DATE == columnType) {
Timestamp timestamp = typePara.getRs().getTimestamp(typePara.getIndex());
return Date.from(Instant.ofEpochSecond(timestamp.getTime()));
} else if (Types.BIGINT == columnType) {
long timestamp = Convert.toLong(typePara.getRs().getLong(typePara.getIndex()), 0L);
return Date.from(Instant.ofEpochSecond(timestamp));
} else {
return null;
}
}
}
\ No newline at end of file
package com.ibeetl.admin.core.conf.handler;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import org.beetl.sql.core.mapping.type.JavaSqlTypeHandler;
import org.beetl.sql.core.mapping.type.TypeParameter;
public class ZonedDateTimeTypeHandler extends JavaSqlTypeHandler {
@Override
public Object getValue(TypeParameter typePara) throws SQLException {
if (ObjectUtil.isNull(typePara.getRs().getObject(typePara.getIndex()))) {
return null;
}
int columnType = typePara.getColumnType();
if (Types.TIMESTAMP == columnType || Types.DATE == columnType) {
Timestamp timestamp = typePara.getRs().getTimestamp(typePara.getIndex());
return ZonedDateTime
.ofInstant(Instant.ofEpochSecond(timestamp.getTime()), ZoneId.systemDefault());
} else if (Types.BIGINT == columnType) {
long timestamp = Convert.toLong(typePara.getRs().getLong(typePara.getIndex()), 0L);
return ZonedDateTime
.ofInstant(Instant.ofEpochSecond(timestamp), ZoneId.systemDefault());
} else {
return null;
}
}
}
Supports Markdown
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