Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jinli gu
Springboot Plus
Commits
c95491fc
"...src/main/java/git@ustchcs.com:gujinli1118/eladmin.git" did not exist on "931ecb3ba769fe2dbfb8fec15b51efe263331157"
Commit
c95491fc
authored
Sep 29, 2019
by
zengchao
Browse files
将复杂结果集映射移入正式使用中,进行逐渐完善
parent
a94f992a
Changes
8
Hide whitespace changes
Inline
Side-by-side
plus-admin/admin-console/src/main/resources/btsql-ext.properties
View file @
c95491fc
...
@@ -5,4 +5,4 @@ DELIMITER_STATEMENT_END=
...
@@ -5,4 +5,4 @@ DELIMITER_STATEMENT_END=
#\u51FD\u6570\u6CE8\u518C
#\u51FD\u6570\u6CE8\u518C
FN.isEmpty
=
org.beetl.ext.fn.EmptyExpressionFunction
FN.isEmpty
=
org.beetl.ext.fn.EmptyExpressionFunction
FN.isNotEmpty
=
org.beetl.ext.fn.IsNotEmptyExpressionFunction
FN.isNotEmpty
=
org.beetl.ext.fn.IsNotEmptyExpressionFunction
FN.mapping
=
com.ibeetl.admin.core.
util.beetl
.MappingFunction
FN.mapping
=
com.ibeetl.admin.core.
conf.handler
.MappingFunction
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/conf/BeetlConf.java
View file @
c95491fc
package
com.ibeetl.admin.core.conf
;
package
com.ibeetl.admin.core.conf
;
import
cn.hutool.core.util.CharsetUtil
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.ibeetl.admin.core.conf.handler.DateTypeHandler
;
import
com.ibeetl.admin.core.conf.handler.DateTypeHandler
;
import
com.ibeetl.admin.core.conf.handler.ZonedDateTimeTypeHandler
;
import
com.ibeetl.admin.core.conf.handler.ZonedDateTimeTypeHandler
;
import
com.ibeetl.admin.core.conf.processor.JsonBeanProcessor
;
import
com.ibeetl.admin.core.rbac.DataAccess
;
import
com.ibeetl.admin.core.rbac.DataAccess
;
import
com.ibeetl.admin.core.rbac.DataAccessFactory
;
import
com.ibeetl.admin.core.rbac.DataAccessFactory
;
import
com.ibeetl.admin.core.service.CorePlatformService
;
import
com.ibeetl.admin.core.service.CorePlatformService
;
...
@@ -10,7 +12,6 @@ import com.ibeetl.admin.core.util.beetl.DictQueryFunction;
...
@@ -10,7 +12,6 @@ import com.ibeetl.admin.core.util.beetl.DictQueryFunction;
import
com.ibeetl.admin.core.util.beetl.FileFunction
;
import
com.ibeetl.admin.core.util.beetl.FileFunction
;
import
com.ibeetl.admin.core.util.beetl.FunAccessUrlFunction
;
import
com.ibeetl.admin.core.util.beetl.FunAccessUrlFunction
;
import
com.ibeetl.admin.core.util.beetl.FunFunction
;
import
com.ibeetl.admin.core.util.beetl.FunFunction
;
import
com.ibeetl.admin.core.util.beetl.MappingFunction
;
import
com.ibeetl.admin.core.util.beetl.MenuFunction
;
import
com.ibeetl.admin.core.util.beetl.MenuFunction
;
import
com.ibeetl.admin.core.util.beetl.OrgFunction
;
import
com.ibeetl.admin.core.util.beetl.OrgFunction
;
import
com.ibeetl.admin.core.util.beetl.RoleFunction
;
import
com.ibeetl.admin.core.util.beetl.RoleFunction
;
...
@@ -28,22 +29,17 @@ import java.util.Date;
...
@@ -28,22 +29,17 @@ import java.util.Date;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletRequest
;
import
org.apache.commons.jexl2.internal.MapGetExecutor
;
import
org.beetl.core.Context
;
import
org.beetl.core.Context
;
import
org.beetl.core.Function
;
import
org.beetl.core.Function
;
import
org.beetl.core.GroupTemplate
;
import
org.beetl.core.GroupTemplate
;
import
org.beetl.ext.simulate.WebSimulate
;
import
org.beetl.ext.simulate.WebSimulate
;
import
org.beetl.sql.core.Interceptor
;
import
org.beetl.sql.core.Interceptor
;
import
org.beetl.sql.core.InterceptorContext
;
import
org.beetl.sql.core.SQLManager
;
import
org.beetl.sql.core.engine.SQLPlaceholderST
;
import
org.beetl.sql.core.engine.SQLPlaceholderST
;
import
org.beetl.sql.core.mapping.type.JavaSqlTypeHandler
;
import
org.beetl.sql.core.mapping.type.JavaSqlTypeHandler
;
import
org.beetl.sql.ext.DebugInterceptor
;
import
org.beetl.sql.ext.DebugInterceptor
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.Marker
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.boot.autoconfigure.AutoConfigureAfter
;
import
org.springframework.boot.autoconfigure.AutoConfigureAfter
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
...
@@ -88,21 +84,34 @@ public class BeetlConf {
...
@@ -88,21 +84,34 @@ public class BeetlConf {
};
};
}
}
/**
* BeetlSql 多数据源
*
* @return
*/
@Bean
@Bean
public
BeetlSqlMutipleSourceCustomize
beetlSqlMutipleSourceCustomize
(){
public
BeetlSqlMutipleSourceCustomize
beetlSqlMutipleSourceCustomize
()
{
SQLPlaceholderST
.
textFunList
.
add
(
"mapping"
);
SQLPlaceholderST
.
textFunList
.
add
(
"mapping"
);
return
(
dataSource
,
manager
)
->
{
return
(
dataSource
,
manager
)
->
{
/*bean转换处理器*/
JsonBeanProcessor
jsonBeanProcessor
=
new
JsonBeanProcessor
(
manager
);
manager
.
setDefaultBeanProcessors
(
jsonBeanProcessor
);
/*类型处理器*/
Map
<
Class
,
JavaSqlTypeHandler
>
typeHandlerMap
=
Map
<
Class
,
JavaSqlTypeHandler
>
typeHandlerMap
=
manager
.
getDefaultBeanProcessors
().
getHandlers
();
manager
.
getDefaultBeanProcessors
().
getHandlers
();
/*Java bean的属性类型处理器,从数据库类型转化到属性Date类型*/
/*Java bean的属性类型处理器,从数据库类型转化到属性Date类型*/
typeHandlerMap
.
remove
(
Date
.
class
);
typeHandlerMap
.
remove
(
Date
.
class
);
typeHandlerMap
.
put
(
Date
.
class
,
new
DateTypeHandler
());
typeHandlerMap
.
put
(
Date
.
class
,
new
DateTypeHandler
());
typeHandlerMap
.
put
(
ZonedDateTime
.
class
,
new
ZonedDateTimeTypeHandler
());
typeHandlerMap
.
put
(
ZonedDateTime
.
class
,
new
ZonedDateTimeTypeHandler
());
manager
.
setInters
(
new
Interceptor
[]{
new
StarterDebugInterceptor
()});
/*拦截器*/
manager
.
setInters
(
new
Interceptor
[]
{
new
StarterDebugInterceptor
()});
};
};
}
}
/**
* Beetl模板引擎的自定义配置
* @return
* */
@Bean
@Bean
public
BeetlTemplateCustomize
beetlTemplateCustomize
()
{
public
BeetlTemplateCustomize
beetlTemplateCustomize
()
{
return
groupTemplate
->
{
return
groupTemplate
->
{
...
@@ -128,16 +137,6 @@ public class BeetlConf {
...
@@ -128,16 +137,6 @@ public class BeetlConf {
return
platFormService
.
canAcessFunction
(
userId
,
orgId
,
functionCode
);
return
platFormService
.
canAcessFunction
(
userId
,
orgId
,
functionCode
);
});
});
groupTemplate
.
registerFunction
(
"abcd"
,
new
Function
()
{
@Override
public
Boolean
call
(
Object
[]
paras
,
Context
ctx
)
{
return
true
;
}
});
groupTemplate
.
registerFunction
(
groupTemplate
.
registerFunction
(
"env"
,
"env"
,
new
Function
()
{
new
Function
()
{
...
@@ -157,7 +156,7 @@ public class BeetlConf {
...
@@ -157,7 +156,7 @@ public class BeetlConf {
protected
String
getStr
(
String
str
)
{
protected
String
getStr
(
String
str
)
{
try
{
try
{
return
new
String
(
str
.
getBytes
(
"iso8859-1"
),
"UTF-8"
);
return
new
String
(
str
.
getBytes
(
CharsetUtil
.
ISO_8859_1
),
CharsetUtil
.
UTF_8
);
}
catch
(
UnsupportedEncodingException
e
)
{
}
catch
(
UnsupportedEncodingException
e
)
{
throw
new
RuntimeException
(
e
);
throw
new
RuntimeException
(
e
);
}
}
...
@@ -177,8 +176,13 @@ public class BeetlConf {
...
@@ -177,8 +176,13 @@ public class BeetlConf {
}
}
static
class
StarterDebugInterceptor
extends
DebugInterceptor
{
static
class
StarterDebugInterceptor
extends
DebugInterceptor
{
private
Logger
logger
=
LoggerFactory
.
getLogger
(
"beetlsql"
);
private
Logger
logger
=
LoggerFactory
.
getLogger
(
"beetlsql"
);
/**
* 将内置生成的SQL排除打印
* @param sqlId
* @return
*/
@Override
@Override
protected
boolean
isSimple
(
String
sqlId
)
{
protected
boolean
isSimple
(
String
sqlId
)
{
if
(
sqlId
.
indexOf
(
"_gen_"
)
!=
-
1
)
{
if
(
sqlId
.
indexOf
(
"_gen_"
)
!=
-
1
)
{
...
...
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/conf/handler/MappingFunction.java
View file @
c95491fc
package
com.ibeetl.admin.core.
util.beetl
;
package
com.ibeetl.admin.core.
conf.handler
;
import
cn.hutool.core.map.MapUtil
;
import
cn.hutool.core.map.MapUtil
;
import
cn.hutool.core.util.ObjectUtil
;
import
cn.hutool.core.util.ObjectUtil
;
import
cn.hutool.core.util.StrUtil
;
import
cn.hutool.core.util.StrUtil
;
import
c
n.hutool.json.JSONUtil
;
import
c
om.ibeetl.admin.core.conf.resultmap.GridMapping
;
import
com.ibeetl.admin.core.util.CacheUtil
;
import
com.ibeetl.admin.core.util.CacheUtil
;
import
java.io.IOException
;
import
java.io.StringWriter
;
import
java.io.StringWriter
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
import
org.beetl.core.Context
;
import
org.beetl.core.Context
;
import
org.beetl.core.Function
;
import
org.beetl.core.Function
;
import
org.beetl.core.GroupTemplate
;
import
org.beetl.core.GroupTemplate
;
import
org.beetl.core.ResourceLoader
;
import
org.beetl.core.resource.StringTemplateResourceLoader
;
import
org.beetl.core.resource.StringTemplateResourceLoader
;
import
org.beetl.sql.core.SQLManager
;
import
org.beetl.sql.core.SQLManager
;
import
org.beetl.sql.core.SQLResult
;
import
org.beetl.sql.core.SQLResult
;
...
@@ -20,13 +18,14 @@ import org.beetl.sql.core.SQLResult;
...
@@ -20,13 +18,14 @@ import org.beetl.sql.core.SQLResult;
public
class
MappingFunction
implements
Function
{
public
class
MappingFunction
implements
Function
{
private
static
final
StringWriter
STRING_WRITER
=
new
StringWriter
();
private
static
final
StringWriter
STRING_WRITER
=
new
StringWriter
();
private
static
final
StringTemplateResourceLoader
STRING_TEMPLATE_RESOURCE_LOADER
=
new
StringTemplateResourceLoader
();
private
static
final
StringTemplateResourceLoader
STRING_TEMPLATE_RESOURCE_LOADER
=
new
StringTemplateResourceLoader
();
@Override
@Override
public
Object
call
(
Object
[]
paras
,
Context
ctx
)
{
public
Object
call
(
Object
[]
paras
,
Context
ctx
)
{
String
currentSqlId
=
ctx
.
getGlobal
(
"_id"
).
toString
();
String
currentSqlId
=
ctx
.
getGlobal
(
"_id"
).
toString
();
Object
cache
=
CacheUtil
.
get
(
currentSqlId
);
Object
cache
=
CacheUtil
.
get
(
currentSqlId
);
if
(
ObjectUtil
.
isNotNull
(
cache
)){
if
(
ObjectUtil
.
isNotNull
(
cache
))
{
return
StrUtil
.
EMPTY
;
return
StrUtil
.
EMPTY
;
}
}
String
sqlSegmentId
=
(
String
)
paras
[
0
];
String
sqlSegmentId
=
(
String
)
paras
[
0
];
...
@@ -43,10 +42,10 @@ public class MappingFunction implements Function {
...
@@ -43,10 +42,10 @@ public class MappingFunction implements Function {
/*获取参数指定的sqlid所在的md文件名*/
/*获取参数指定的sqlid所在的md文件名*/
String
file
=
this
.
getParentId
(
ctx
);
String
file
=
this
.
getParentId
(
ctx
);
SQLResult
result
;
SQLResult
result
;
if
(
sqlSegmentId
.
indexOf
(
"."
)==-
1
){
if
(
sqlSegmentId
.
indexOf
(
"."
)
==
-
1
)
{
/*同一个md文件的sql段*/
/*同一个md文件的sql段*/
result
=
sm
.
getSQLResult
(
file
+
"."
+
sqlSegmentId
,
inputParas
,
ctx
);
result
=
sm
.
getSQLResult
(
file
+
"."
+
sqlSegmentId
,
inputParas
,
ctx
);
}
else
{
}
else
{
/*另一个md文件的sql段*/
/*另一个md文件的sql段*/
result
=
sm
.
getSQLResult
(
sqlSegmentId
,
inputParas
,
ctx
);
result
=
sm
.
getSQLResult
(
sqlSegmentId
,
inputParas
,
ctx
);
}
}
...
@@ -61,8 +60,9 @@ public class MappingFunction implements Function {
...
@@ -61,8 +60,9 @@ public class MappingFunction implements Function {
result
.
jdbcSql
,
inputParas
,
STRING_WRITER
,
STRING_TEMPLATE_RESOURCE_LOADER
);
result
.
jdbcSql
,
inputParas
,
STRING_WRITER
,
STRING_TEMPLATE_RESOURCE_LOADER
);
if
(
MapUtil
.
isNotEmpty
(
rsMap
))
{
if
(
MapUtil
.
isNotEmpty
(
rsMap
))
{
/*TODO 待移到非测试代码中,重写为保持GridMapping,而不是保持Map*/
GridMapping
mapping
=
CacheUtil
.
put
(
currentSqlId
,
rsMap
.
values
().
stream
().
findFirst
().
get
());
new
GridMapping
((
Map
<
String
,
Object
>)
rsMap
.
values
().
stream
().
findFirst
().
get
());
CacheUtil
.
put
(
currentSqlId
,
mapping
);
}
}
return
StrUtil
.
EMPTY
;
return
StrUtil
.
EMPTY
;
...
...
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/conf/processor/JsonBeanProcessor.java
0 → 100644
View file @
c95491fc
package
com.ibeetl.admin.core.conf.processor
;
import
cn.hutool.core.bean.BeanUtil
;
import
cn.hutool.core.collection.CollUtil
;
import
cn.hutool.core.map.MapUtil
;
import
cn.hutool.core.util.ClassUtil
;
import
cn.hutool.core.util.ObjectUtil
;
import
cn.hutool.core.util.StrUtil
;
import
com.ibeetl.admin.core.conf.resultmap.GridColumn
;
import
com.ibeetl.admin.core.conf.resultmap.GridHeader
;
import
com.ibeetl.admin.core.conf.resultmap.GridMapping
;
import
com.ibeetl.admin.core.conf.resultmap.GridRow
;
import
com.ibeetl.admin.core.util.CacheUtil
;
import
java.beans.IntrospectionException
;
import
java.beans.PropertyDescriptor
;
import
java.sql.ResultSet
;
import
java.sql.ResultSetMetaData
;
import
java.sql.SQLException
;
import
java.util.ArrayList
;
import
java.util.Collection
;
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.kit.BeanKit
;
import
org.beetl.sql.core.mapping.BeanProcessor
;
public
class
JsonBeanProcessor
extends
BeanProcessor
{
public
JsonBeanProcessor
(
SQLManager
sm
)
{
super
(
sm
);
}
/**
* 网格化输出结果集
*
* @param resultSet
* @throws SQLException
*/
public
void
printfResultSet
(
ResultSet
resultSet
)
throws
SQLException
{
Map
<
String
,
List
<
Object
>>
map
=
MapUtil
.<
String
,
List
<
Object
>>
builder
().
build
();
ResultSetMetaData
metaData
=
resultSet
.
getMetaData
();
int
count
=
metaData
.
getColumnCount
();
int
rn
=
0
;
resultSet
.
absolute
(
0
);
while
(
resultSet
.
next
())
{
for
(
int
i
=
1
;
i
<=
count
;
i
++)
{
String
columnLabel
=
metaData
.
getColumnLabel
(
i
);
List
<
Object
>
objectList
=
map
.
getOrDefault
(
columnLabel
,
CollUtil
.
newArrayList
());
Object
object
=
resultSet
.
getObject
(
i
);
objectList
.
add
(
object
);
map
.
put
(
columnLabel
,
objectList
);
}
rn
++;
}
resultSet
.
absolute
(
0
);
Set
<
String
>
keySet
=
map
.
keySet
();
for
(
String
key
:
keySet
)
{
System
.
out
.
printf
(
"| %-32s "
,
key
);
}
System
.
out
.
println
();
for
(
int
i
=
0
;
i
<
rn
;
i
++)
{
Set
<
Entry
<
String
,
List
<
Object
>>>
entrySet
=
map
.
entrySet
();
for
(
Entry
<
String
,
List
<
Object
>>
entry
:
entrySet
)
{
System
.
out
.
printf
(
"| %-32s "
,
entry
.
getValue
().
get
(
i
));
}
System
.
out
.
println
();
}
}
/**
* 将ResultSet映射为一个POJO对象
*
* @param rs
* @param type
* @return
* @throws SQLException
*/
@Override
public
<
T
>
T
toBean
(
String
sqlId
,
ResultSet
rs
,
Class
<
T
>
type
)
throws
SQLException
{
List
<
T
>
results
=
new
ArrayList
<
T
>();
PropertyDescriptor
[]
props
=
this
.
propertyDescriptors
(
type
);
ResultSetMetaData
rsmd
=
rs
.
getMetaData
();
int
[]
columnToProperty
=
this
.
mapColumnsToProperties
(
type
,
rsmd
,
props
);
GridMapping
mapping
=
(
GridMapping
)
CacheUtil
.
get
(
sqlId
);
if
(
null
==
mapping
)
{
/*无映射的情况下使用beetlsql默认自带的映射*/
do
{
super
.
createBean
(
sqlId
,
rs
,
type
,
props
,
columnToProperty
);
}
while
(
rs
.
next
());
}
else
{
/*复杂结果集映射,取消TailBean的便利性*/
rs
.
absolute
(
0
);
fillMappingRow
(
rs
,
mapping
);
results
=
convertMapping
(
mapping
,
type
);
}
return
CollUtil
.
getFirst
(
results
);
}
/**
*
* 将ResultSet映射为一个List<POJO>集合
* @param sqlId
* @param rs
* @param type
* @param <T>
* @return
* @throws SQLException
*/
@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
);
GridMapping
mapping
=
(
GridMapping
)
CacheUtil
.
get
(
sqlId
);
if
(
null
==
mapping
)
{
/*无映射的情况下使用beetlsql默认自带的映射*/
do
{
results
.
add
(
super
.
createBean
(
sqlId
,
rs
,
type
,
props
,
columnToProperty
));
}
while
(
rs
.
next
());
}
else
{
/*复杂结果集映射,取消TailBean的便利性*/
rs
.
absolute
(
0
);
fillMappingRow
(
rs
,
mapping
);
results
=
convertMapping
(
mapping
,
type
);
}
return
results
;
}
/**
* 循环转换整个网格映射
*
* @param mapping
* @param objType
* @param <T>
* @return
*/
public
<
T
>
List
<
T
>
convertMapping
(
GridMapping
mapping
,
Class
<
T
>
objType
)
throws
SQLException
{
List
<
T
>
results
=
new
ArrayList
<
T
>();
List
<
GridRow
>
mappingNestedRows
=
mapping
.
getNestedRows
();
for
(
GridRow
mappingNestedRow
:
mappingNestedRows
)
{
T
obj
=
convertRow
(
mappingNestedRow
,
objType
);
results
.
add
(
obj
);
}
return
results
;
}
/**
* 递归转换整个网格行
*
* @param row
* @param objType
* @param <T>
* @return
*/
public
<
T
>
T
convertRow
(
GridRow
row
,
Class
<
T
>
objType
)
throws
SQLException
{
T
obj
=
super
.
newInstance
(
objType
);
List
<
GridColumn
>
nestedColumns
=
row
.
getNestedColumns
();
GridColumn
curObjCol
=
nestedColumns
.
get
(
0
);
for
(
int
i
=
1
;
i
<
nestedColumns
.
size
();
i
++)
{
GridColumn
nestedColumn
=
nestedColumns
.
get
(
i
);
GridHeader
mappingHeader
=
nestedColumn
.
getMappingHeader
();
String
resultType
=
mappingHeader
.
getResultType
();
List
<
GridRow
>
nestedRows
=
nestedColumn
.
getNestedRows
();
for
(
GridRow
nestedRow
:
nestedRows
)
{
if
(
StrUtil
.
isNotBlank
(
resultType
))
{
/*在映射中标明类型,证明是复杂类型*/
Class
nestedPropType
=
ClassUtil
.
loadClass
(
resultType
);
String
nestedPropName
=
mappingHeader
.
getNestedPropName
();
boolean
isCollection
=
mappingHeader
.
getIsCollection
();
Object
resultObj
=
BeanUtil
.
getFieldValue
(
obj
,
nestedPropName
);
Object
nestedPropObj
=
convertRow
(
nestedRow
,
nestedPropType
);
if
(
isCollection
)
{
((
Collection
)
resultObj
).
add
(
nestedPropObj
);
resultObj
=
CollUtil
.
removeNull
(((
Collection
)
resultObj
));
}
else
{
resultObj
=
nestedPropObj
;
}
BeanUtil
.
setFieldValue
(
obj
,
nestedPropName
,
resultObj
);
}
else
{
/*在映射中没有标明类型,证明是基本类型*/
String
nestedPropName
=
mappingHeader
.
getNestedPropName
();
boolean
isCollection
=
mappingHeader
.
getIsCollection
();
Object
resultObj
=
BeanUtil
.
getFieldValue
(
obj
,
nestedPropName
);
Map
<
String
,
Object
>
beanMap
=
nestedRow
.
getNestedColumns
().
get
(
0
).
getBeanMap
();
/*几乎此处说明内嵌的字段是一个基本类型的集合,所以beanmap中应该只有一个值*/
Object
nestedPropObj
=
CollUtil
.
getFirst
(
beanMap
.
values
());
if
(
isCollection
)
{
((
Collection
)
resultObj
).
add
(
nestedPropObj
);
resultObj
=
CollUtil
.
removeNull
(((
Collection
)
resultObj
));
}
else
{
resultObj
=
nestedPropObj
;
}
BeanUtil
.
setFieldValue
(
obj
,
nestedPropName
,
resultObj
);
}
}
}
/*TODO 重写,以便提供命名转换*/
BeanUtil
.
fillBeanWithMap
(
curObjCol
.
getBeanMap
(),
obj
,
true
,
true
);
return
obj
;
}
/**
* 填充整个网格映射mapping数据结构:通过网格头映射生成一个个网格行
*
* @param resultSet
* @param mapping
* @throws SQLException
*/
protected
void
fillMappingRow
(
ResultSet
resultSet
,
GridMapping
mapping
)
throws
SQLException
{
GridHeader
header
=
mapping
.
getHeader
();
GridColumn
column
=
new
GridColumn
();
while
(
resultSet
.
next
())
{
List
<
GridRow
>
mappingNestedRows
=
mapping
.
getNestedRows
();
GridRow
row
=
fillRowColumn
(
resultSet
,
header
,
column
);
if
(!
mappingNestedRows
.
contains
(
row
))
{
mappingNestedRows
.
add
(
row
);
}
}
}
/** 网格行中存在一个个网格列,也对应着相应的网格头结构 */
protected
GridRow
fillRowColumn
(
ResultSet
resultSet
,
GridHeader
header
,
GridColumn
column
)
{
/*搜寻已经存在的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
);
}
}
row
.
getNestedColumns
().
get
(
0
).
setBeanMap
(
beanMap
);
return
row
;
}
/**
* 遍历网格头,由网格头的信息从结果集中读取值。<br>
* 这样做的好处是方便算法编写;坏处是失去了tailbean的处理,因为无法确定结果集列的读取状态。
*
* @param resultSet
* @param header
* @return
*/
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
{
try
{
return
BeanKit
.
propertyDescriptors
(
c
);
}
catch
(
IntrospectionException
e
)
{
throw
new
SQLException
(
"Bean introspection failed: "
+
e
.
getMessage
());
}
}
}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/conf/resultmap/GridColumn.java
0 → 100644
View file @
c95491fc
package
com.ibeetl.admin.core.conf.resultmap
;
import
cn.hutool.core.collection.CollUtil
;
import
cn.hutool.core.map.MapUtil
;
import
cn.hutool.core.util.ObjectUtil
;
import
java.io.Serializable
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map.Entry
;
import
java.util.Set
;
/**
* 网格列,结果集映射的java类型中的基本类型属性,都应该在一个列中。<br>
* 非基本类型的属性字段,应该内嵌多行 <br>
* 包含:值映射map、映射类型、最关键的obj key<br>
* objkey 决定了数据库结果集的多条重复记录会被唯一记录成一个对象。
*/
public
class
GridColumn
implements
Serializable
{
/** 对应的属性与数据库中值的映射,用于map to Bean 转换 */
Map
<
String
,
Object
>
beanMap
=
MapUtil
.
newHashMap
();
/** 映射类型 */
String
resultType
;
/** 一个网格列包含一个对象中的所有数据列,通过对这些数据列进行hash得到数据列的唯一性 */
Integer
objKey
;
/** 包含的网格行 */
List
<
GridRow
>
nestedRows
=
CollUtil
.<
GridRow
>
newArrayList
();
/** 归属的网格行 */
GridRow
belongRow
;
GridHeader
mappingHeader
;
public
Map
<
String
,
Object
>
getBeanMap
()
{
return
beanMap
;
}
public
void
setBeanMap
(
Map
<
String
,
Object
>
beanMap
)
{
this
.
beanMap
=
beanMap
;
}
public
String
getResultType
()
{
return
resultType
;
}
public
void
setResultType
(
String
resultType
)
{
this
.
resultType
=
resultType
;
}
public
Integer
getObjKey
()
{
objKey
=
calculateKey
(
beanMap
);
return
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
()
{
return
nestedRows
;
}
public
void
setNestedRows
(
List
<
GridRow
>
nestedRows
)
{
this
.
nestedRows
=
nestedRows
;
}
public
GridRow
getBelongRow
()
{
return
belongRow
;
}
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
;
}
}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/conf/resultmap/GridHeader.java
0 → 100644
View file @
c95491fc
package
com.ibeetl.admin.core.conf.resultmap
;
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.io.Serializable
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map.Entry
;
import
java.util.Set
;
/**
* 网格头,保存了属性与列的映射关系,以及映射的java类型。<br>
* 内嵌的网格头,内嵌网格头的映射java类型,是否是映射至List集合字段
*/
public
class
GridHeader
implements
Serializable
{
/** java属性名与数据库列名的对应。顺序:prop:column */
Map
<
String
,
String
>
javaToJdbcMap
;
/** 映射java类型,如果该值为空,代表为基础类型,并且忽视javaToJdbcMap中的key,因为此刻是基本类型的List, */
String
resultType
;
/** 嵌套类型的网格头 */
List
<
GridHeader
>
nestedHeaders
=
CollUtil
.<
GridHeader
>
newArrayList
();
/** 嵌套类型的网格头 */
GridHeader
parentHeader
;
/** 嵌套字段属性名 */
String
nestedPropName
;
/** 嵌套类型是否是一个集合 */
boolean
isCollection
=
false
;
/** 网格头所属的网格映射 */
GridMapping
belongMapping
;
public
GridHeader
(
Map
<
String
,
Object
>
resultMapping
)
{
javaToJdbcMap
=
new
HashMap
<
String
,
String
>();
processResultMapping
(
resultMapping
);
}
public
Map
<
String
,
String
>
getJavaToJdbcMap
()
{
return
javaToJdbcMap
;
}
public
void
setJavaToJdbcMap
(
Map
<
String
,
String
>
javaToJdbcMap
)
{
this
.
javaToJdbcMap
=
javaToJdbcMap
;
}
public
String
getResultType
()
{
return
resultType
;
}
public
void
setResultType
(
String
resultType
)
{
this
.
resultType
=
resultType
;
}
public
List
<
GridHeader
>
getNestedHeaders
()
{
return
nestedHeaders
;
}
public
void
setNestedHeaders
(
List
<
GridHeader
>
nestedHeaders
)
{
this
.
nestedHeaders
=
nestedHeaders
;
}
public
GridHeader
getParentHeader
()
{
return
parentHeader
;
}
public
void
setParentHeader
(
GridHeader
parentHeader
)
{
this
.
parentHeader
=
parentHeader
;
}
public
String
getNestedPropName
()
{
return
nestedPropName
;
}
public
void
setNestedPropName
(
String
nestedPropName
)
{
this
.
nestedPropName
=
nestedPropName
;
}
public
boolean
getIsCollection
()
{
return
isCollection
;
}
public
void
setIsCollection
(
boolean
isCollection
)
{
this
.
isCollection
=
isCollection
;
}
public
GridMapping
getBelongMapping
()
{
return
belongMapping
;
}
public
void
setBelongMapping
(
GridMapping
belongMapping
)
{
this
.
belongMapping
=
belongMapping
;
}
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
();
Class
<?>
valClass
=
ClassUtil
.
getClass
(
value
);
if
(
List
.
class
.
isAssignableFrom
(
valClass
))
{
/*生成嵌套网格头,此嵌套网格头的类型对应集合字段*/
Map
<
String
,
Object
>
nestedMapping
=
(
Map
<
String
,
Object
>)
((
List
)
value
).
stream
().
findFirst
().
orElse
(
MapUtil
.
newHashMap
(
0
));
GridHeader
nestedHeader
=
new
GridHeader
(
nestedMapping
);
nestedHeader
.
setIsCollection
(
true
);
nestedHeader
.
setNestedPropName
(
key
);
nestedHeader
.
setBelongMapping
(
this
.
getBelongMapping
());
this
.
getNestedHeaders
().
add
(
nestedHeader
);
nestedHeader
.
setParentHeader
(
this
);
}
else
if
(
Map
.
class
.
isAssignableFrom
(
valClass
))
{
/*生成嵌套网格头,此嵌套网格头的类型对应单个对象字段*/
Map
<
String
,
Object
>
nestedMapping
=
(
Map
<
String
,
Object
>)
value
;
GridHeader
nestedHeader
=
new
GridHeader
(
nestedMapping
);
nestedHeader
.
setIsCollection
(
false
);
nestedHeader
.
setNestedPropName
(
key
);
nestedHeader
.
setBelongMapping
(
this
.
getBelongMapping
());
this
.
getNestedHeaders
().
add
(
nestedHeader
);
nestedHeader
.
setParentHeader
(
this
);
}
else
if
(
isNotBlank
(
key
)
||
(
null
!=
value
&&
isNotBlank
(
String
.
valueOf
(
value
))))
{
javaToJdbcMap
.
put
(
key
,
String
.
valueOf
(
value
));
}
}
}
}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/conf/resultmap/GridMapping.java
0 → 100644
View file @
c95491fc
package
com.ibeetl.admin.core.conf.resultmap
;
import
static
cn
.
hutool
.
core
.
util
.
StrUtil
.
EMPTY
;
import
static
java
.
util
.
Optional
.
ofNullable
;
import
cn.hutool.core.collection.CollUtil
;
import
cn.hutool.core.lang.Assert
;
import
cn.hutool.json.JSON
;
import
cn.hutool.json.JSONUtil
;
import
java.io.Serializable
;
import
java.util.List
;
import
java.util.Map
;
/** 网格映射数据结构: 包含一个网格头 {@link GridHeader}和多个网格行{@link GridRow} */
public
class
GridMapping
implements
Serializable
{
/** 映射id */
String
mappingId
;
/** 当前映射配置对应的class类型 */
String
resultType
;
/** 网格头 */
GridHeader
header
;
List
<
GridRow
>
nestedRows
=
CollUtil
.
newArrayList
();
public
GridMapping
(
Map
<
String
,
Object
>
resultMapping
)
{
JSON
parse
=
JSONUtil
.
parse
(
resultMapping
);
String
id
=
ofNullable
(
parse
.
getByPath
(
"id"
)).
orElse
(
EMPTY
).
toString
();
String
resultType
=
ofNullable
(
parse
.
getByPath
(
"mapping.resultType"
)).
orElse
(
EMPTY
).
toString
();
Assert
.
notBlank
(
id
,
"result mapping must have [id]."
);
Assert
.
notBlank
(
resultType
,
"result mapping must have [resultType]."
);
this
.
mappingId
=
id
;
this
.
resultType
=
resultType
;
this
.
header
=
new
GridHeader
((
Map
<
String
,
Object
>)
parse
.
getByPath
(
"mapping"
));
}
public
GridHeader
getHeader
()
{
return
header
;
}
public
void
setHeader
(
GridHeader
header
)
{
this
.
header
=
header
;
this
.
header
.
setBelongMapping
(
this
);
}
public
String
getMappingId
()
{
return
mappingId
;
}
public
void
setMappingId
(
String
mappingId
)
{
this
.
mappingId
=
mappingId
;
}
public
String
getResultType
()
{
return
resultType
;
}
public
void
setResultType
(
String
resultType
)
{
this
.
resultType
=
resultType
;
}
public
List
<
GridRow
>
getNestedRows
()
{
return
nestedRows
;
}
public
void
setNestedRows
(
List
<
GridRow
>
nestedRows
)
{
this
.
nestedRows
=
nestedRows
;
}
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
;
}
}
plus-admin/admin-core/src/main/java/com/ibeetl/admin/core/conf/resultmap/GridRow.java
0 → 100644
View file @
c95491fc
package
com.ibeetl.admin.core.conf.resultmap
;
import
cn.hutool.core.collection.CollUtil
;
import
cn.hutool.core.util.ObjectUtil
;
import
java.io.Serializable
;
import
java.util.List
;
/**
* 网格行,包含一个个网格列<br>
* 一个网格行,对应着SQL select查询出的一个Java的逻辑对象
*/
public
class
GridRow
implements
Serializable
{
/** 包含的列,第0个列代表的是当前整个类的映射,从0列之后是内部对象字段的映射 */
List
<
GridColumn
>
nestedColumns
=
CollUtil
.<
GridColumn
>
newArrayList
();
/** 所属的列 */
GridColumn
belongColumn
;
/** 映射对象的类型名 */
String
resultType
;
/** 通过每个列的key进行hash得到一个唯一row id */
Integer
rowKey
;
public
GridRow
()
{}
public
List
<
GridColumn
>
getNestedColumns
()
{
return
nestedColumns
;
}
public
void
setNestedColumns
(
List
<
GridColumn
>
nestedColumns
)
{
this
.
nestedColumns
=
nestedColumns
;
}
public
String
getResultType
()
{
return
resultType
;
}
public
void
setResultType
(
String
resultType
)
{
this
.
resultType
=
resultType
;
}
public
Integer
getRowKey
()
{
return
this
.
nestedColumns
.
get
(
0
).
getObjKey
();
}
public
GridColumn
getBelongColumn
()
{
return
belongColumn
;
}
public
void
setBelongColumn
(
GridColumn
belongColumn
)
{
this
.
belongColumn
=
belongColumn
;
}
/**
* 根据网格头,生成对应的网格行结构。 行套列或者列套行再套列两种。
*
* @return
*/
public
static
GridRow
generateRowByHeader
(
GridHeader
gridHeader
)
{
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
);
containerColumn
.
getNestedRows
().
add
(
nestedRow
);
nestedRow
.
setBelongColumn
(
containerColumn
);
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
;
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment