Commit 94679e6a authored by zengchao's avatar zengchao
Browse files

Merge branch 'vue' of gitee.com:xiandafu/springboot-plus into vue

parents ee3d08b4 5c0a802f
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil; import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray; import cn.hutool.json.JSONArray;
...@@ -11,10 +16,16 @@ import com.ibeetl.admin.core.dao.CoreFunctionDao; ...@@ -11,10 +16,16 @@ import com.ibeetl.admin.core.dao.CoreFunctionDao;
import com.ibeetl.admin.core.entity.CoreRoute; import com.ibeetl.admin.core.entity.CoreRoute;
import com.ibeetl.admin.core.entity.CoreRouteMeta; import com.ibeetl.admin.core.entity.CoreRouteMeta;
import com.ibeetl.admin.core.util.CacheUtil; import com.ibeetl.admin.core.util.CacheUtil;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import org.beetl.sql.core.SQLManager; import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.mapping.type.JavaSqlTypeHandler; import org.beetl.sql.core.mapping.type.JavaSqlTypeHandler;
import org.junit.Before; import org.junit.Before;
...@@ -29,6 +40,7 @@ import processor.JsonBeanProcessor; ...@@ -29,6 +40,7 @@ import processor.JsonBeanProcessor;
import resultmap.GridHeader; import resultmap.GridHeader;
import resultmap.GridMapping; import resultmap.GridMapping;
import resultmap.GridRow; import resultmap.GridRow;
import sun.swing.StringUIClientPropertyKey;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest(classes = ConsoleApplication.class) @SpringBootTest(classes = ConsoleApplication.class)
...@@ -68,7 +80,7 @@ public class CustomBeanProcessorTest { ...@@ -68,7 +80,7 @@ public class CustomBeanProcessorTest {
JSONObject testMapping = new JSONObject(); JSONObject testMapping = new JSONObject();
testMapping.put("id", "test_id"); testMapping.put("id", "test_id");
testMapping.put("name", "name"); testMapping.put("username", "username");
testMapping.put("password", "password"); testMapping.put("password", "password");
testMapping.put("resultType", entity.Test.class.getCanonicalName()); testMapping.put("resultType", entity.Test.class.getCanonicalName());
......
package processor; package processor;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ibeetl.admin.core.util.CacheUtil; import com.ibeetl.admin.core.util.CacheUtil;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.ResultSetMetaData; import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import org.beetl.sql.core.BeetlSQLException; import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.beetl.sql.core.SQLManager; import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.Tail;
import org.beetl.sql.core.annotatoin.builder.AttributeBuilderHolder;
import org.beetl.sql.core.annotatoin.builder.AttributeSelectBuilder;
import org.beetl.sql.core.db.ClassAnnotation;
import org.beetl.sql.core.db.DBStyle;
import org.beetl.sql.core.kit.BeanKit; import org.beetl.sql.core.kit.BeanKit;
import org.beetl.sql.core.mapping.BeanProcessor; import org.beetl.sql.core.mapping.BeanProcessor;
import org.beetl.sql.core.mapping.type.JavaSqlTypeHandler; import resultmap.GridColumn;
import org.beetl.sql.core.mapping.type.TypeParameter; import resultmap.GridHeader;
import resultmap.GridMapping; import resultmap.GridMapping;
import resultmap.GridRow;
public class JsonBeanProcessor extends BeanProcessor { public class JsonBeanProcessor extends BeanProcessor {
...@@ -25,78 +27,130 @@ public class JsonBeanProcessor extends BeanProcessor { ...@@ -25,78 +27,130 @@ public class JsonBeanProcessor extends BeanProcessor {
super(sm); super(sm);
} }
@Override
public <T> List<T> toBeanList(String sqlId, ResultSet rs, Class<T> type) throws SQLException {
if (!rs.next()) {
return new ArrayList<T>(0);
}
List<T> results = new ArrayList<T>();
PropertyDescriptor[] props = this.propertyDescriptors(type);
ResultSetMetaData rsmd = rs.getMetaData();
int[] columnToProperty = this.mapColumnsToProperties(type, rsmd, props);
results.add(this.createBean(sqlId, rs, type, props, columnToProperty));
return results;
}
/** 创建 一个新的对象,并从ResultSet初始化 */ /** 创建 一个新的对象,并从ResultSet初始化 */
@Override @Override
protected <T> T createBean( protected <T> T createBean(
String sqlId, ResultSet rs, Class<T> type, PropertyDescriptor[] props, int[] columnToProperty) String sqlId, ResultSet rs, Class<T> type, PropertyDescriptor[] props, int[] columnToProperty)
throws SQLException { throws SQLException {
GridMapping gridMapping = (GridMapping) CacheUtil.get("Route_Mapping"); GridMapping gridMapping = (GridMapping) CacheUtil.get("Route_Mapping");
if (null == gridMapping) {
return super.createBean(sqlId, rs, type, props, columnToProperty);
}
T bean = this.newInstance(type); fillMappingRow(rs, gridMapping);
ResultSetMetaData meta = rs.getMetaData(); System.out.println(gridMapping);
TypeParameter tp = new TypeParameter(sqlId, this.dbName, type, rs, meta, 1); return null;
}
for (int i = 1; i < columnToProperty.length; i++) {
// Array.fill数组为-1 ,-1则无对应name
tp.setIndex(i);
if (columnToProperty[i] == PROPERTY_NOT_FOUND) {
String key = rs.getMetaData().getColumnLabel(i);
if ((dbType == DBStyle.DB_ORACLE || dbType == DBStyle.DB_SQLSERVER)
&& key.equalsIgnoreCase("beetl_rn")) {
// sql server 特殊处理,sql'server的翻页使用了额外列作为翻页参数,需要过滤
continue;
}
if (bean instanceof Tail) { public String print(GridColumn column) {
Tail bean2 = (Tail) bean; List<GridRow> nestedRows = column.getNestedRows();
Object value = noMappingValue(tp); String print = "";
key = this.nc.getPropertyName(type, key); for (GridRow nestedRow : nestedRows) {
bean2.set(key, value); List<GridColumn> nestedColumns = nestedRow.getNestedColumns();
} else { GridColumn gridColumn = nestedColumns.get(0);
Method m = BeanKit.getTailMethod(type); print = print.concat(gridColumn.getBeanMap().toString() + "\n\t");
// 使用指定方法赋值 for (int i = 1; i < nestedColumns.size(); i++) {
if (m != null) { GridColumn tempCol = nestedColumns.get(i);
if (tempCol.getBeanMap().isEmpty() && !tempCol.getNestedRows().isEmpty()) {
Object value = noMappingValue(tp); /*是一个容器性质的列*/
key = this.nc.getPropertyName(type, key); print = print.concat(print(tempCol));
try { } else if (!tempCol.getBeanMap().isEmpty() && tempCol.getNestedRows().isEmpty()) {
m.invoke(bean, key, value); /*对象存储性质的列*/
} catch (Exception ex) { print = print.concat(tempCol.getBeanMap().toString() + "\n\t");
throw new BeetlSQLException(BeetlSQLException.TAIL_CALL_ERROR, ex);
}
} else {
// 忽略这个结果集
}
} }
continue;
} }
}
return print;
}
// columnToProperty[i]取出对应的在PropertyDescriptor[]中的下标 protected void fillMappingRow(ResultSet resultSet, GridMapping mapping) throws SQLException {
PropertyDescriptor prop = props[columnToProperty[i]]; GridHeader header = mapping.getHeader();
Class<?> propType = prop.getPropertyType(); GridColumn column = new GridColumn();
tp.setTarget(propType);
ClassAnnotation ca = ClassAnnotation.getClassAnnotation(type); /** flag:用来判断结果集是否应该通过 mapping.nextRow(); 生成新的行 */
Object value = null; Boolean flag = true;
if (!ca.getColHandlers().isEmpty()) { while (resultSet.next()) {
AttributeBuilderHolder holder =
(AttributeBuilderHolder) ca.getColHandlers().get(prop.getName()); List<GridRow> mappingNestedRows = mapping.getNestedRows();
if (holder != null && holder.supportSelectMapping()) { GridRow row = fillRowColumn(resultSet, header, column);
value = if (!mappingNestedRows.contains(row)) {
((AttributeSelectBuilder) holder.getInstance()) mappingNestedRows.add(row);
.toObject(this.sm, holder.getBeanAnnotaton(), sqlId, tp, prop);
this.callSetter(bean, prop, value, propType);
continue;
}
} }
JavaSqlTypeHandler handler = this.handlers.get(propType); }
if (handler == null) { System.out.println(11);
handler = this.defaultHandler; }
/** flag:用来判断结果集是否 next() */
protected GridRow fillRowColumn(ResultSet resultSet, GridHeader header, GridColumn column)
throws SQLException {
/*搜寻已经存在的row,如果没有,则插入一个*/
Map<String, Object> beanMap = extractMapFromRs(resultSet, header);
Integer calculateKey = GridColumn.calculateKey(beanMap);
GridRow row = column.findRowByKey(calculateKey);
/*这里可能出现一个问题,始终第0个行是空白的*/
if (ObjectUtil.isNull(row)) {
/*生成一个新的*/
row = GridRow.generateRowByHeader(header);
column.getNestedRows().add(row);
row.setBelongColumn(column);
}
List<GridHeader> nestedHeaders = header.getNestedHeaders();
for (GridHeader nestedHeader : nestedHeaders) {
GridColumn nestedColumn = row.findColumnByHeader(nestedHeader);
List<GridRow> nestedRows = nestedColumn.getNestedRows();
GridRow nestedRow = fillRowColumn(resultSet, nestedHeader, nestedColumn);
if (!nestedRows.contains(nestedRow)) {
nestedRows.add(nestedRow);
} }
value = handler.getValue(tp); }
this.callSetter(bean, prop, value, propType); row.getNestedColumns().get(0).setBeanMap(beanMap);
return row;
}
private Map<String, Object> extractMapFromRs(ResultSet resultSet, GridHeader header) {
Map<String, Object> tempBeanMap = MapUtil.newHashMap();
/*第一步、先处理当前可以处理的*/
Map<String, String> javaToJdbcMap = header.getJavaToJdbcMap();
Set<Entry<String, String>> entrySet = javaToJdbcMap.entrySet();
for (Entry<String, String> entry : entrySet) {
try {
tempBeanMap.put(entry.getKey(), resultSet.getObject(entry.getValue()));
} catch (SQLException e) {
/*普遍错误时从resultset中获取一个不存在的列,但可以忽视*/
}
} }
return tempBeanMap;
}
/**
* 根据class取得属性描述PropertyDescriptor
*
* @param c
* @return
* @throws SQLException
*/
private PropertyDescriptor[] propertyDescriptors(Class<?> c) throws SQLException {
return bean; try {
return BeanKit.propertyDescriptors(c);
} catch (IntrospectionException e) {
throw new SQLException("Bean introspection failed: " + e.getMessage());
}
} }
} }
package resultmap; package resultmap;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -18,12 +18,12 @@ import java.util.Set; ...@@ -18,12 +18,12 @@ import java.util.Set;
public class GridColumn implements Serializable { public class GridColumn implements Serializable {
/** 对应的属性与数据库中值的映射,用于map to Bean 转换 */ /** 对应的属性与数据库中值的映射,用于map to Bean 转换 */
Map<String, Object> beanMap; Map<String, Object> beanMap = MapUtil.newHashMap();
/** 映射类型 */ /** 映射类型 */
String resultType; String resultType;
/** 数据库记录对应的唯一key,用 beanMap 中所有非null值的hashcode相加得出 */ /** 一个网格列包含一个对象中的所有数据列,通过对这些数据列进行hash得到数据列的唯一性 */
Integer objKey; Integer objKey;
/** 包含的网格行 */ /** 包含的网格行 */
...@@ -32,6 +32,8 @@ public class GridColumn implements Serializable { ...@@ -32,6 +32,8 @@ public class GridColumn implements Serializable {
/** 归属的网格行 */ /** 归属的网格行 */
GridRow belongRow; GridRow belongRow;
GridHeader mappingHeader;
public Map<String, Object> getBeanMap() { public Map<String, Object> getBeanMap() {
return beanMap; return beanMap;
} }
...@@ -49,25 +51,21 @@ public class GridColumn implements Serializable { ...@@ -49,25 +51,21 @@ public class GridColumn implements Serializable {
} }
public Integer getObjKey() { public Integer getObjKey() {
int hs = 0; objKey = calculateKey(beanMap);
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; return objKey;
} }
public void setObjKey(Integer objKey) { public static Integer calculateKey(Map<String, Object> map) {
this.objKey = objKey; if (MapUtil.isEmpty(map)) {
return Integer.MIN_VALUE;
}
int hs = 0;
Set<Entry<String, Object>> entrySet = map.entrySet();
for (Entry<String, Object> entry : entrySet) {
if (ObjectUtil.isNull(entry.getValue())) continue;
hs += entry.getValue().hashCode();
}
return hs / 42;
} }
public List<GridRow> getNestedRows() { public List<GridRow> getNestedRows() {
...@@ -85,4 +83,21 @@ public class GridColumn implements Serializable { ...@@ -85,4 +83,21 @@ public class GridColumn implements Serializable {
public void setBelongRow(GridRow belongRow) { public void setBelongRow(GridRow belongRow) {
this.belongRow = belongRow; this.belongRow = belongRow;
} }
public void setMappingHeader(GridHeader mappingHeader) {
this.mappingHeader = mappingHeader;
}
public GridHeader getMappingHeader() {
return this.mappingHeader;
}
public GridRow findRowByKey(Integer objKey) {
for (GridRow row : this.nestedRows) {
if (ObjectUtil.equal(row.getRowKey(), objKey)) {
return row;
}
}
return null;
}
} }
...@@ -11,12 +11,12 @@ import java.io.Serializable; ...@@ -11,12 +11,12 @@ import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/** 网格映射数据结构: 包含一个网格头 {@link GridHeader} */ /** 网格映射数据结构: 包含一个网格头 {@link GridHeader}和多个网格行{@link GridRow} */
public class GridMapping implements Serializable { public class GridMapping implements Serializable {
/** 映射id */ /** 映射id */
String mappingId; String mappingId;
/** 映射类型 */ /** 当前映射配置对应的class类型 */
String resultType; String resultType;
/** 网格头 */ /** 网格头 */
...@@ -68,8 +68,11 @@ public class GridMapping implements Serializable { ...@@ -68,8 +68,11 @@ public class GridMapping implements Serializable {
this.nestedRows = nestedRows; this.nestedRows = nestedRows;
} }
public GridRow nextRow(){ public GridRow nextRow(GridColumn column){
GridRow row = GridRow.generateRowByHeader(this.header); GridRow row = GridRow.generateRowByHeader(this.header);
/*给最外层的row设置一个空的列,为了后面的算法便利。可以理解成仅仅只是一个容器而已*/
column.getNestedRows().add(row);
row.setBelongColumn(column);
this.nestedRows.add(row); this.nestedRows.add(row);
return row; return row;
} }
......
...@@ -7,11 +7,11 @@ import java.util.List; ...@@ -7,11 +7,11 @@ import java.util.List;
/** /**
* 网格行,包含一个个网格列<br> * 网格行,包含一个个网格列<br>
* 一行一个对象,或者java类中的一个对象字段 * 一个网格行,对应着SQL select查询出的一个Java的逻辑对象
*/ */
public class GridRow implements Serializable { public class GridRow implements Serializable {
/** 包含的列 */ /** 包含的列,第0个列代表的是当前整个类的映射,从0列之后是内部对象字段的映射 */
List<GridColumn> nestedColumns = CollUtil.<GridColumn>newArrayList(); List<GridColumn> nestedColumns = CollUtil.<GridColumn>newArrayList();
/** 所属的列 */ /** 所属的列 */
...@@ -20,6 +20,7 @@ public class GridRow implements Serializable { ...@@ -20,6 +20,7 @@ public class GridRow implements Serializable {
/** 映射对象的类型名 */ /** 映射对象的类型名 */
String resultType; String resultType;
/** 通过每个列的key进行hash得到一个唯一row id */
Integer rowKey; Integer rowKey;
public GridRow() {} public GridRow() {}
...@@ -41,16 +42,7 @@ public class GridRow implements Serializable { ...@@ -41,16 +42,7 @@ public class GridRow implements Serializable {
} }
public Integer getRowKey() { public Integer getRowKey() {
int hs = 0; return this.nestedColumns.get(0).getObjKey();
for (GridColumn nestedColumn : nestedColumns) {
hs = hs + nestedColumn.getObjKey();
}
rowKey = hs;
return rowKey;
}
public void setRowKey(Integer rowKey) {
this.rowKey = rowKey;
} }
public GridColumn getBelongColumn() { public GridColumn getBelongColumn() {
...@@ -62,7 +54,7 @@ public class GridRow implements Serializable { ...@@ -62,7 +54,7 @@ public class GridRow implements Serializable {
} }
/** /**
* 根据网格头,生成对应的网格行结构 * 根据网格头,生成对应的网格行结构。 行套列或者列套行再套列两种。
* *
* @return * @return
*/ */
...@@ -70,13 +62,18 @@ public class GridRow implements Serializable { ...@@ -70,13 +62,18 @@ public class GridRow implements Serializable {
if (ObjectUtil.isNull(gridHeader)) { if (ObjectUtil.isNull(gridHeader)) {
return null; return null;
} }
/*这是外层*/
GridRow gridRow = new GridRow(); GridRow gridRow = new GridRow();
/*这个列才是真正的存储数据值的*/
GridColumn gridColumn = new GridColumn(); GridColumn gridColumn = new GridColumn();
gridRow.getNestedColumns().add(gridColumn); gridRow.getNestedColumns().add(gridColumn);
gridColumn.setBelongRow(gridRow); gridColumn.setBelongRow(gridRow);
List<GridHeader> headers = gridHeader.getNestedHeaders(); List<GridHeader> headers = gridHeader.getNestedHeaders();
for (GridHeader header : headers) { for (GridHeader header : headers) {
/*这只是外部的一个容器性质的列,这个是内层*/
GridColumn containerColumn = new GridColumn(); GridColumn containerColumn = new GridColumn();
GridRow nestedRow = generateRowByHeader(header); GridRow nestedRow = generateRowByHeader(header);
...@@ -85,10 +82,21 @@ public class GridRow implements Serializable { ...@@ -85,10 +82,21 @@ public class GridRow implements Serializable {
gridRow.getNestedColumns().add(containerColumn); gridRow.getNestedColumns().add(containerColumn);
containerColumn.setBelongRow(gridRow); containerColumn.setBelongRow(gridRow);
containerColumn.setMappingHeader(header);
} }
gridColumn.setMappingHeader(gridHeader);
gridColumn.setResultType(gridHeader.getResultType()); gridColumn.setResultType(gridHeader.getResultType());
gridRow.setResultType(gridHeader.getResultType()); gridRow.setResultType(gridHeader.getResultType());
return gridRow; return gridRow;
} }
public GridColumn findColumnByHeader(GridHeader header) {
for (GridColumn column : this.nestedColumns) {
if (ObjectUtil.equal(column.getMappingHeader(), header)) {
return column;
}
}
return null;
}
} }
...@@ -5,11 +5,11 @@ select router.id, ...@@ -5,11 +5,11 @@ select router.id,
router.PARENT_ID, router.PARENT_ID,
ifnull(router.ACCESS_URL, '/error/404') path, ifnull(router.ACCESS_URL, '/error/404') path,
router.NAME, router.NAME,
menu.NAME title, menu.NAME title,
menu.ICON, menu.ICON,
ifnull(menu.SEQ, 999999) seq, ifnull(menu.SEQ, 999999) seq,
crm.ROLE_ID crm.ROLE_ID
from core_function router from core_function router
left join core_menu menu left join core_menu menu on menu.FUNCTION_ID = router.ID
on menu.FUNCTION_ID = router.ID left join core_role_menu crm on crm.MENU_ID = menu.id
left join core_role_menu crm on crm.MENU_ID = menu.id; order by router.ID
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