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