Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
renren-generator
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
吴迪
renren-generator
Commits
aa84ce70
Commit
aa84ce70
authored
May 12, 2020
by
独孤求胜
Committed by
Gitee
May 12, 2020
Browse files
Options
Browse Files
Download
Plain Diff
!7 增加了支持Mongo的功能 同时解决了选用其他数据库的mongo自动获取连接的问题
Merge pull request !7 from 龚宣璋/master
parents
d1face53
1c9a8cd0
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1169 additions
and
52 deletions
+1169
-52
pom.xml
pom.xml
+7
-0
RenrenApplication.java
src/main/java/io/renren/RenrenApplication.java
+3
-1
MongoTableInfoAdaptor.java
src/main/java/io/renren/adaptor/MongoTableInfoAdaptor.java
+66
-0
DbConfig.java
src/main/java/io/renren/config/DbConfig.java
+25
-8
MongoCondition.java
src/main/java/io/renren/config/MongoCondition.java
+18
-0
MongoConfig.java
src/main/java/io/renren/config/MongoConfig.java
+92
-0
MongoManager.java
src/main/java/io/renren/config/MongoManager.java
+38
-0
MongoNullCondition.java
src/main/java/io/renren/config/MongoNullCondition.java
+17
-0
MongoDBGeneratorDao.java
src/main/java/io/renren/dao/MongoDBGeneratorDao.java
+56
-0
MongoDefinition.java
src/main/java/io/renren/entity/mongo/MongoDefinition.java
+98
-0
MongoGeneratorEntity.java
...ain/java/io/renren/entity/mongo/MongoGeneratorEntity.java
+50
-0
Type.java
src/main/java/io/renren/entity/mongo/Type.java
+35
-0
MongoDBCollectionFactory.java
...main/java/io/renren/factory/MongoDBCollectionFactory.java
+101
-0
SysGeneratorService.java
src/main/java/io/renren/service/SysGeneratorService.java
+19
-6
GenUtils.java
src/main/java/io/renren/utils/GenUtils.java
+165
-36
MongoScanner.java
src/main/java/io/renren/utils/MongoScanner.java
+301
-0
application.yml
src/main/resources/application.yml
+12
-1
generator.properties
src/main/resources/generator.properties
+1
-0
MongoChildrenEntity.java.vm
src/main/resources/template/MongoChildrenEntity.java.vm
+29
-0
MongoEntity.java.vm
src/main/resources/template/MongoEntity.java.vm
+36
-0
No files found.
pom.xml
View file @
aa84ce70
...
...
@@ -29,6 +29,7 @@
<mysql.version>
8.0.17
</mysql.version>
<mssql.version>
4.0
</mssql.version>
<oracle.version>
11.2.0.3
</oracle.version>
<mongo.version>
3.11.0
</mongo.version>
</properties>
<dependencies>
...
...
@@ -120,6 +121,12 @@
<groupId>
org.postgresql
</groupId>
<artifactId>
postgresql
</artifactId>
</dependency>
<!-- mongo驱动 -->
<dependency>
<groupId>
org.mongodb
</groupId>
<artifactId>
mongo-java-driver
</artifactId>
<version>
${mongo.version}
</version>
</dependency>
</dependencies>
<build>
...
...
src/main/java/io/renren/RenrenApplication.java
View file @
aa84ce70
...
...
@@ -3,8 +3,10 @@ package io.renren;
import
org.mybatis.spring.annotation.MapperScan
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
import
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration
;
import
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration
;
@SpringBootApplication
@SpringBootApplication
(
exclude
=
{
MongoAutoConfiguration
.
class
,
MongoDataAutoConfiguration
.
class
})
@MapperScan
(
"io.renren.dao"
)
public
class
RenrenApplication
{
...
...
src/main/java/io/renren/adaptor/MongoTableInfoAdaptor.java
0 → 100644
View file @
aa84ce70
package
io
.
renren
.
adaptor
;
import
io.renren.entity.mongo.MongoDefinition
;
import
io.renren.entity.mongo.Type
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
/**
* mongo适配器
*
* @author: gxz gongxuanzhang@foxmail.com
**/
public
class
MongoTableInfoAdaptor
{
/**
* 查询表信息的时候 mongo只能获得表名 其他只能手动填写
*
* @param names 表名
*/
public
static
List
<
Map
<
String
,
String
>>
tableInfo
(
List
<
String
>
names
)
{
List
<
Map
<
String
,
String
>>
result
=
new
ArrayList
<>(
names
.
size
());
for
(
String
name
:
names
)
{
result
.
add
(
tableInfo
(
name
));
}
return
result
;
}
public
static
Map
<
String
,
String
>
tableInfo
(
String
name
)
{
Map
<
String
,
String
>
tableInfo
=
new
HashMap
<>(
4
*
4
/
3
+
1
);
tableInfo
.
put
(
"engine"
,
"mongo无引擎"
);
tableInfo
.
put
(
"createTime"
,
"mongo无法查询创建时间"
);
tableInfo
.
put
(
"tableComment"
,
"mongo无备注"
);
tableInfo
.
put
(
"tableName"
,
name
);
return
tableInfo
;
}
/**
* 在查询列名的时候 需要将解析出的mongo信息适配成关系型数据库所需要的信息形式
* 此方法只针对主Bean
*/
public
static
List
<
Map
<
String
,
String
>>
columnInfo
(
MongoDefinition
mongoDefinition
)
{
List
<
MongoDefinition
>
child
=
mongoDefinition
.
getChild
();
List
<
Map
<
String
,
String
>>
result
=
new
ArrayList
<>(
child
.
size
());
final
String
mongoKey
=
"_id"
;
for
(
MongoDefinition
definition
:
child
)
{
Map
<
String
,
String
>
map
=
new
HashMap
<>(
5
*
4
/
3
+
1
);
String
type
=
Type
.
typeInfo
(
definition
.
getType
());
String
propertyName
=
definition
.
getPropertyName
();
String
extra
=
definition
.
isArray
()
?
"array"
:
""
;
map
.
put
(
"extra"
,
extra
);
map
.
put
(
"columnComment"
,
""
);
map
.
put
(
"dataType"
,
definition
.
hasChild
()
?
propertyName
:
type
);
map
.
put
(
"columnName"
,
propertyName
);
// mongo默认主键是_id
String
columnKey
=
propertyName
.
equals
(
mongoKey
)
?
"PRI"
:
""
;
map
.
put
(
"columnKey"
,
columnKey
);
result
.
add
(
map
);
}
return
result
;
}
}
src/main/java/io/renren/config/DbConfig.java
View file @
aa84ce70
/**
* Copyright (c) 2018 人人开源 All rights reserved.
*
*
<p>
* https://www.renren.io
*
*
<p>
* 版权所有,侵权必究!
*/
...
...
@@ -13,6 +13,7 @@ import io.renren.utils.RRException;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Conditional
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Primary
;
...
...
@@ -34,19 +35,35 @@ public class DbConfig {
@Autowired
private
PostgreSQLGeneratorDao
postgreSQLGeneratorDao
;
private
static
boolean
mongo
=
false
;
@Bean
@Primary
public
GeneratorDao
getGeneratorDao
(){
if
(
"mysql"
.
equalsIgnoreCase
(
database
)){
@Conditional
(
MongoNullCondition
.
class
)
public
GeneratorDao
getGeneratorDao
()
{
if
(
"mysql"
.
equalsIgnoreCase
(
database
))
{
return
mySQLGeneratorDao
;
}
else
if
(
"oracle"
.
equalsIgnoreCase
(
database
))
{
}
else
if
(
"oracle"
.
equalsIgnoreCase
(
database
))
{
return
oracleGeneratorDao
;
}
else
if
(
"sqlserver"
.
equalsIgnoreCase
(
database
))
{
}
else
if
(
"sqlserver"
.
equalsIgnoreCase
(
database
))
{
return
sqlServerGeneratorDao
;
}
else
if
(
"postgresql"
.
equalsIgnoreCase
(
database
))
{
}
else
if
(
"postgresql"
.
equalsIgnoreCase
(
database
))
{
return
postgreSQLGeneratorDao
;
}
else
{
}
else
{
throw
new
RRException
(
"不支持当前数据库:"
+
database
);
}
}
@Bean
@Primary
@Conditional
(
MongoCondition
.
class
)
public
GeneratorDao
getMongoDBDao
(
MongoDBGeneratorDao
mongoDBGeneratorDao
)
{
mongo
=
true
;
return
mongoDBGeneratorDao
;
}
public
static
boolean
isMongo
()
{
return
mongo
;
}
}
src/main/java/io/renren/config/MongoCondition.java
0 → 100644
View file @
aa84ce70
package
io
.
renren
.
config
;
import
org.apache.commons.lang.StringUtils
;
import
org.springframework.context.annotation.Condition
;
import
org.springframework.context.annotation.ConditionContext
;
import
org.springframework.core.type.AnnotatedTypeMetadata
;
/**
* @author: gxz gongxuanzhang@foxmail.com
**/
public
class
MongoCondition
implements
Condition
{
@Override
public
boolean
matches
(
ConditionContext
context
,
AnnotatedTypeMetadata
metadata
)
{
String
database
=
context
.
getEnvironment
().
getProperty
(
"renren.database"
);
return
"mongodb"
.
equalsIgnoreCase
(
database
);
}
}
src/main/java/io/renren/config/MongoConfig.java
0 → 100644
View file @
aa84ce70
package
io
.
renren
.
config
;
import
com.mongodb.MongoClient
;
import
com.mongodb.MongoClientOptions
;
import
com.mongodb.MongoCredential
;
import
com.mongodb.ServerAddress
;
import
com.mongodb.client.MongoDatabase
;
import
io.renren.factory.MongoDBCollectionFactory
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Conditional
;
import
org.springframework.stereotype.Component
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* @author: gxz gongxuanzhang@foxmail.com
**/
@Component
@ConfigurationProperties
(
prefix
=
"mongodb"
)
public
class
MongoConfig
{
private
String
host
;
private
int
port
;
private
String
username
;
private
String
password
;
private
String
dataBase
;
private
boolean
auth
;
private
String
source
;
@Bean
@Conditional
(
MongoCondition
.
class
)
private
MongoClient
getMongoClient
()
{
List
<
ServerAddress
>
adds
=
new
ArrayList
<>();
ServerAddress
serverAddress
=
new
ServerAddress
(
this
.
host
,
this
.
port
);
adds
.
add
(
serverAddress
);
if
(
this
.
auth
)
{
MongoCredential
mongoCredential
=
MongoCredential
.
createScramSha1Credential
(
this
.
username
,
this
.
source
,
this
.
password
.
toCharArray
());
MongoClientOptions
mongoClientOptions
=
MongoClientOptions
.
builder
().
build
();
return
new
MongoClient
(
adds
,
mongoCredential
,
mongoClientOptions
);
}
return
new
MongoClient
(
adds
);
}
@Bean
@Conditional
(
MongoCondition
.
class
)
public
MongoDatabase
getDataBase
()
{
return
getMongoClient
().
getDatabase
(
dataBase
);
}
public
MongoConfig
setHost
(
String
host
)
{
this
.
host
=
host
;
return
this
;
}
public
MongoConfig
setPort
(
int
port
)
{
this
.
port
=
port
;
return
this
;
}
public
MongoConfig
setUsername
(
String
username
)
{
this
.
username
=
username
;
return
this
;
}
public
MongoConfig
setPassword
(
String
password
)
{
this
.
password
=
password
;
return
this
;
}
public
MongoConfig
setDataBase
(
String
dataBase
)
{
this
.
dataBase
=
dataBase
;
return
this
;
}
public
MongoConfig
setAuth
(
boolean
auth
)
{
this
.
auth
=
auth
;
return
this
;
}
public
MongoConfig
setSource
(
String
source
)
{
this
.
source
=
source
;
return
this
;
}
}
src/main/java/io/renren/config/MongoManager.java
0 → 100644
View file @
aa84ce70
package
io
.
renren
.
config
;
import
io.renren.entity.mongo.MongoDefinition
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
/**
* @author gxz
* @date 2020/5/10 12:05
*/
public
class
MongoManager
{
/***mongo扫描很消耗性能 尤其是子类的封装 使用缓存**/
private
static
Map
<
String
,
MongoDefinition
>
mongoCache
=
new
ConcurrentHashMap
<>();
public
static
Map
<
String
,
MongoDefinition
>
getCache
()
{
return
mongoCache
;
}
public
static
MongoDefinition
getInfo
(
String
tableName
)
{
return
mongoCache
.
getOrDefault
(
tableName
,
null
);
}
public
static
MongoDefinition
putInfo
(
String
tableName
,
MongoDefinition
mongoDefinition
)
{
return
mongoCache
.
put
(
tableName
,
mongoDefinition
);
}
/**
* 当前配置是否为mongo内容
*/
public
static
boolean
isMongo
()
{
return
DbConfig
.
isMongo
();
}
}
src/main/java/io/renren/config/MongoNullCondition.java
0 → 100644
View file @
aa84ce70
package
io
.
renren
.
config
;
import
org.springframework.context.annotation.Condition
;
import
org.springframework.context.annotation.ConditionContext
;
import
org.springframework.core.type.AnnotatedTypeMetadata
;
/**
* @author: gxz gongxuanzhang@foxmail.com
**/
public
class
MongoNullCondition
implements
Condition
{
@Override
public
boolean
matches
(
ConditionContext
context
,
AnnotatedTypeMetadata
metadata
)
{
String
database
=
context
.
getEnvironment
().
getProperty
(
"renren.database"
);
return
!
"mongodb"
.
equalsIgnoreCase
(
database
);
}
}
src/main/java/io/renren/dao/MongoDBGeneratorDao.java
0 → 100644
View file @
aa84ce70
package
io
.
renren
.
dao
;
import
io.renren.adaptor.MongoTableInfoAdaptor
;
import
io.renren.config.MongoCondition
;
import
io.renren.config.MongoManager
;
import
io.renren.entity.mongo.MongoDefinition
;
import
io.renren.factory.MongoDBCollectionFactory
;
import
io.renren.utils.MongoScanner
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Conditional
;
import
org.springframework.stereotype.Repository
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
/**
* @author: gxz gongxuanzhang@foxmail.com
**/
@Repository
@Conditional
(
MongoCondition
.
class
)
public
class
MongoDBGeneratorDao
implements
GeneratorDao
{
@Autowired
private
MongoDBCollectionFactory
mongoDBCollectionFactory
;
@Override
public
List
<
Map
<
String
,
Object
>>
queryList
(
Map
<
String
,
Object
>
map
)
{
List
<
String
>
collectionNames
=
MongoDBCollectionFactory
.
getCollectionNames
(
map
);
return
(
List
)
MongoTableInfoAdaptor
.
tableInfo
(
collectionNames
);
}
@Override
public
Map
<
String
,
String
>
queryTable
(
String
tableName
)
{
Map
<
String
,
String
>
result
=
new
HashMap
<>(
4
*
4
/
3
+
1
);
result
.
put
(
"engine"
,
""
);
result
.
put
(
"createTime"
,
""
);
result
.
put
(
"tableComment"
,
"mongoDB "
+
tableName
);
result
.
put
(
"tableName"
,
tableName
);
return
result
;
}
@Override
public
List
<
Map
<
String
,
String
>>
queryColumns
(
String
tableName
)
{
MongoDefinition
mongoDefinition
=
MongoManager
.
getInfo
(
tableName
);
if
(
mongoDefinition
==
null
)
{
System
.
out
.
println
(
tableName
);
MongoScanner
mongoScanner
=
new
MongoScanner
(
mongoDBCollectionFactory
.
getCollection
(
tableName
));
mongoDefinition
=
mongoScanner
.
getProduct
();
}
return
MongoTableInfoAdaptor
.
columnInfo
(
mongoDefinition
);
}
}
src/main/java/io/renren/entity/mongo/MongoDefinition.java
0 → 100644
View file @
aa84ce70
package
io
.
renren
.
entity
.
mongo
;
import
io.renren.adaptor.MongoTableInfoAdaptor
;
import
org.apache.commons.collections.CollectionUtils
;
import
java.io.Serializable
;
import
java.util.*
;
/**
* 解析表之后得到的信息实体
* 换句话说这个类就是一张mongo一张表的内容
*
* @author gxz 514190950@qq.com
*/
public
class
MongoDefinition
implements
Serializable
{
/***属性名**/
private
String
propertyName
;
/***属性类型 对应mongodb api $type 如果没有类型 表示这是一个顶层实体 而不是内嵌属性**/
private
Integer
type
;
/***此属性是否是数组**/
private
boolean
array
=
false
;
/***如果此属性是对象 那么他仍然有此类型的子类**/
private
List
<
MongoDefinition
>
child
;
public
List
<
MongoGeneratorEntity
>
getChildrenInfo
(
String
tableName
)
{
List
<
MongoGeneratorEntity
>
result
=
new
ArrayList
<>();
MongoGeneratorEntity
info
=
new
MongoGeneratorEntity
();
// 表信息
Map
<
String
,
String
>
tableInfo
=
MongoTableInfoAdaptor
.
tableInfo
(
tableName
);
// 列名信息
List
<
Map
<
String
,
String
>>
columnsInfo
=
new
ArrayList
<>();
info
.
setColumns
(
columnsInfo
);
info
.
setTableInfo
(
tableInfo
);
result
.
add
(
info
);
List
<
MongoDefinition
>
child
=
this
.
getChild
();
for
(
MongoDefinition
mongoDefinition
:
child
)
{
Map
<
String
,
String
>
columnInfo
=
new
HashMap
<>(
5
);
columnInfo
.
put
(
"columnName"
,
mongoDefinition
.
getPropertyName
());
columnInfo
.
put
(
"dataType"
,
Type
.
typeInfo
(
mongoDefinition
.
getType
()));
columnInfo
.
put
(
"extra"
,
mongoDefinition
.
isArray
()
?
"array"
:
""
);
columnsInfo
.
add
(
columnInfo
);
if
(
mongoDefinition
.
hasChild
())
{
result
.
addAll
(
mongoDefinition
.
getChildrenInfo
(
mongoDefinition
.
getPropertyName
()));
}
}
return
result
;
}
public
boolean
hasChild
()
{
final
int
objectType
=
3
;
return
type
==
null
||
Objects
.
equals
(
type
,
objectType
)
||
CollectionUtils
.
isNotEmpty
(
child
);
}
public
boolean
primaryBean
()
{
return
type
==
null
;
}
public
MongoDefinition
setType
(
Integer
type
)
{
this
.
type
=
type
;
return
this
;
}
public
String
getPropertyName
()
{
return
propertyName
;
}
public
MongoDefinition
setPropertyName
(
String
propertyName
)
{
this
.
propertyName
=
propertyName
;
return
this
;
}
public
Integer
getType
()
{
return
type
;
}
public
boolean
isArray
()
{
return
array
;
}
public
MongoDefinition
setArray
(
boolean
array
)
{
this
.
array
=
array
;
return
this
;
}
public
List
<
MongoDefinition
>
getChild
()
{
return
child
;
}
public
MongoDefinition
setChild
(
List
<
MongoDefinition
>
child
)
{
this
.
child
=
child
;
return
this
;
}
}
src/main/java/io/renren/entity/mongo/MongoGeneratorEntity.java
0 → 100644
View file @
aa84ce70
package
io
.
renren
.
entity
.
mongo
;
import
io.renren.entity.TableEntity
;
import
java.util.List
;
import
java.util.Map
;
/**
* mysql一张表只需要一个表信息和列名信息
* 但是mongo一张表可能需要多个实体类 所以单独用一个bean封装
*
* @author gxz
* @date 2020/5/10 0:14
*/
public
class
MongoGeneratorEntity
{
/***表信息**/
private
Map
<
String
,
String
>
tableInfo
;
/***主类的列名信息**/
private
List
<
Map
<
String
,
String
>>
columns
;
public
TableEntity
toTableEntity
()
{
TableEntity
tableEntity
=
new
TableEntity
();
Map
<
String
,
String
>
tableInfo
=
this
.
tableInfo
;
tableEntity
.
setTableName
(
tableInfo
.
get
(
"tableName"
));
tableEntity
.
setComments
(
""
);
return
tableEntity
;
}
public
Map
<
String
,
String
>
getTableInfo
()
{
return
tableInfo
;
}
public
MongoGeneratorEntity
setTableInfo
(
Map
<
String
,
String
>
tableInfo
)
{
this
.
tableInfo
=
tableInfo
;
return
this
;
}
public
List
<
Map
<
String
,
String
>>
getColumns
()
{
return
columns
;
}
public
MongoGeneratorEntity
setColumns
(
List
<
Map
<
String
,
String
>>
columns
)
{
this
.
columns
=
columns
;
return
this
;
}
}
src/main/java/io/renren/entity/mongo/Type.java
0 → 100644
View file @
aa84ce70
package
io
.
renren
.
entity
.
mongo
;
import
java.util.Objects
;
public
enum
Type
{
/***
* 类型 和对应mongodb api 的$type的数字
**/
varchar
(
2
),
NUMBER
(
16
),
bigint
(
18
),
OBJECT
(
3
),
ARRAY
(
4
),
date
(
9
),
bit
(
8
),
DOUBLE
(
1
);
private
final
int
num
;
Type
(
int
num
)
{
this
.
num
=
num
;
}
public
static
String
typeInfo
(
int
num
)
{
Type
[]
values
=
values
();
for
(
Type
value
:
values
)
{
if
(
Objects
.
equals
(
num
,
value
.
num
))
{
return
value
.
toString
();
}
}
return
null
;
}
}
src/main/java/io/renren/factory/MongoDBCollectionFactory.java
0 → 100644
View file @
aa84ce70
package
io
.
renren
.
factory
;
import
com.mongodb.client.MongoCollection
;
import
com.mongodb.client.MongoDatabase
;
import
com.mongodb.client.MongoIterable
;
import
io.renren.config.MongoCondition
;
import
org.bson.Document
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Conditional
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.PostConstruct
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
/**
* @author: gxz gongxuanzhang@foxmail.com
**/
@Component
@Conditional
(
MongoCondition
.
class
)
public
class
MongoDBCollectionFactory
{
private
static
final
String
TABLE_NAME_KEY
=
"tableName"
;
private
static
final
String
LIMIT_KEY
=
"limit"
;
private
static
final
String
OFFSET_KEY
=
"offset"
;
private
static
MongoDatabase
mongoDatabase
;
// 此处是为了兼容mongo相关内容和关系型数据库的静态耦合所导致的问题
@Autowired
private
MongoDatabase
database
;
@PostConstruct
public
void
initMongoDatabase
(){
mongoDatabase
=
database
;
}
/***
* 通过表名获得查询对象
* @author gxz
* @date 2020/5/9
* @param collectionName mongo的集合名(表名)
* @return 连接查询对象
**/
public
MongoCollection
<
Document
>
getCollection
(
String
collectionName
)
{
return
mongoDatabase
.
getCollection
(
collectionName
);
}
/***
* 获得当前数据库的集合名称
* 注: mongo相对关系型数据库较为特殊,查询表名无法分页,用stream实现
* @author gxz
* @date 2020/5/9
* @param map 这是查询条件 和关系型数据库一致
* @return 集合名称
**/
public
static
List
<
String
>
getCollectionNames
(
Map
<
String
,
Object
>
map
)
{
int
limit
=
Integer
.
valueOf
(
map
.
get
(
LIMIT_KEY
).
toString
());
int
skip
=
Integer
.
valueOf
(
map
.
get
(
OFFSET_KEY
).
toString
());
List
<
String
>
names
;
if
(
map
.
containsKey
(
TABLE_NAME_KEY
))
{
names
=
getCollectionNames
(
map
.
get
(
TABLE_NAME_KEY
).
toString
());
}
else
{
names
=
getCollectionNames
();
}
return
names
.
stream
().
skip
(
skip
).
limit
(
limit
).
collect
(
Collectors
.
toList
());
}
/***
* 获得集合名称总数(表的数量) 为了适配MyBatisPlus的分页插件 提供方法
* @author gxz
* @date 2020/5/9
* @param map 这是查询条件 和关系型数据库一致
* @return int
**/
public
static
int
getCollectionTotal
(
Map
<
String
,
Object
>
map
)
{
if
(
map
.
containsKey
(
TABLE_NAME_KEY
))
{
return
getCollectionNames
(
map
.
get
(
TABLE_NAME_KEY
).
toString
()).
size
();
}
return
getCollectionNames
().
size
();
}
private
static
List
<
String
>
getCollectionNames
()
{
MongoIterable
<
String
>
names
=
mongoDatabase
.
listCollectionNames
();
List
<
String
>
result
=
new
ArrayList
<>();
for
(
String
name
:
names
)
{
result
.
add
(
name
);
}
return
result
;
}
private
static
List
<
String
>
getCollectionNames
(
String
likeName
)
{
return
getCollectionNames
()
.
stream
()
.
filter
((
name
)
->
name
.
contains
(
likeName
)).
collect
(
Collectors
.
toList
());
}
}
src/main/java/io/renren/service/SysGeneratorService.java
View file @
aa84ce70
/**
* Copyright (c) 2018 人人开源 All rights reserved.
*
*
<p>
* https://www.renren.io
*
*
<p>
* 版权所有,侵权必究!
*/
...
...
@@ -10,7 +10,11 @@ package io.renren.service;
import
com.github.pagehelper.Page
;
import
com.github.pagehelper.PageHelper
;
import
io.renren.config.MongoManager
;
import
io.renren.dao.GeneratorDao
;
import
io.renren.dao.MongoDBGeneratorDao
;
import
io.renren.entity.mongo.MongoDefinition
;
import
io.renren.factory.MongoDBCollectionFactory
;
import
io.renren.utils.GenUtils
;
import
io.renren.utils.PageUtils
;
import
io.renren.utils.Query
;
...
...
@@ -33,11 +37,15 @@ public class SysGeneratorService {
@Autowired
private
GeneratorDao
generatorDao
;
public
PageUtils
queryList
(
Query
query
)
{
Page
<?>
page
=
PageHelper
.
startPage
(
query
.
getPage
(),
query
.
getLimit
());
List
<
Map
<
String
,
Object
>>
list
=
generatorDao
.
queryList
(
query
);
return
new
PageUtils
(
list
,
(
int
)
page
.
getTotal
(),
query
.
getLimit
(),
query
.
getPage
());
int
total
=
(
int
)
page
.
getTotal
();
if
(
generatorDao
instanceof
MongoDBGeneratorDao
)
{
total
=
MongoDBCollectionFactory
.
getCollectionTotal
(
query
);
}
return
new
PageUtils
(
list
,
total
,
query
.
getLimit
(),
query
.
getPage
());
}
public
Map
<
String
,
String
>
queryTable
(
String
tableName
)
{
...
...
@@ -48,11 +56,11 @@ public class SysGeneratorService {
return
generatorDao
.
queryColumns
(
tableName
);
}
public
byte
[]
generatorCode
(
String
[]
tableNames
)
{
ByteArrayOutputStream
outputStream
=
new
ByteArrayOutputStream
();
ZipOutputStream
zip
=
new
ZipOutputStream
(
outputStream
);
for
(
String
tableName
:
tableNames
){
for
(
String
tableName
:
tableNames
)
{
//查询表信息
Map
<
String
,
String
>
table
=
queryTable
(
tableName
);
//查询列信息
...
...
@@ -60,6 +68,11 @@ public class SysGeneratorService {
//生成代码
GenUtils
.
generatorCode
(
table
,
columns
,
zip
);
}
if
(
MongoManager
.
isMongo
())
{
GenUtils
.
generatorMongoCode
(
tableNames
,
zip
);
}
IOUtils
.
closeQuietly
(
zip
);
return
outputStream
.
toByteArray
();
}
...
...
src/main/java/io/renren/utils/GenUtils.java
View file @
aa84ce70
package
io
.
renren
.
utils
;
import
io.renren.config.MongoManager
;
import
io.renren.entity.ColumnEntity
;
import
io.renren.entity.TableEntity
;
import
io.renren.entity.mongo.MongoDefinition
;
import
io.renren.entity.mongo.MongoGeneratorEntity
;
import
org.apache.commons.configuration.Configuration
;
import
org.apache.commons.configuration.ConfigurationException
;
import
org.apache.commons.configuration.PropertiesConfiguration
;
...
...
@@ -28,19 +31,35 @@ import java.util.zip.ZipOutputStream;
*/
public
class
GenUtils
{
public
static
List
<
String
>
getTemplates
(){
private
static
String
currentTableName
;
public
static
List
<
String
>
getTemplates
()
{
List
<
String
>
templates
=
new
ArrayList
<
String
>();
templates
.
add
(
"template/Entity.java.vm"
);
templates
.
add
(
"template/Dao.java.vm"
);
templates
.
add
(
"template/Dao.xml.vm"
);
templates
.
add
(
"template/menu.sql.vm"
);
templates
.
add
(
"template/Service.java.vm"
);
templates
.
add
(
"template/ServiceImpl.java.vm"
);
templates
.
add
(
"template/Controller.java.vm"
);
templates
.
add
(
"template/
menu.sql
.vm"
);
templates
.
add
(
"template/
Dao.java
.vm"
);
templates
.
add
(
"template/index.vue.vm"
);
templates
.
add
(
"template/add-or-update.vue.vm"
);
if
(
MongoManager
.
isMongo
())
{
// mongo不需要mapper、sql 实体类需要替换
templates
.
remove
(
0
);
templates
.
remove
(
1
);
templates
.
remove
(
2
);
templates
.
add
(
"template/MongoEntity.java.vm"
);
}
return
templates
;
}
public
static
List
<
String
>
getMongoChildTemplates
()
{
List
<
String
>
templates
=
new
ArrayList
<
String
>();
templates
.
add
(
"template/MongoChildrenEntity.java.vm"
);
return
templates
;
}
...
...
@@ -52,10 +71,11 @@ public class GenUtils {
//配置信息
Configuration
config
=
getConfig
();
boolean
hasBigDecimal
=
false
;
boolean
hasList
=
false
;
//表信息
TableEntity
tableEntity
=
new
TableEntity
();
tableEntity
.
setTableName
(
table
.
get
(
"tableName"
));
tableEntity
.
setComments
(
table
.
get
(
"tableComment"
));
tableEntity
.
setTableName
(
table
.
get
(
"tableName"
));
tableEntity
.
setComments
(
table
.
get
(
"tableComment"
));
//表名转换成Java类名
String
className
=
tableToJava
(
tableEntity
.
getTableName
(),
config
.
getStringArray
(
"tablePrefix"
));
tableEntity
.
setClassName
(
className
);
...
...
@@ -63,12 +83,12 @@ public class GenUtils {
//列信息
List
<
ColumnEntity
>
columsList
=
new
ArrayList
<>();
for
(
Map
<
String
,
String
>
column
:
columns
)
{
for
(
Map
<
String
,
String
>
column
:
columns
)
{
ColumnEntity
columnEntity
=
new
ColumnEntity
();
columnEntity
.
setColumnName
(
column
.
get
(
"columnName"
));
columnEntity
.
setDataType
(
column
.
get
(
"dataType"
));
columnEntity
.
setComments
(
column
.
get
(
"columnComment"
));
columnEntity
.
setExtra
(
column
.
get
(
"extra"
));
columnEntity
.
setColumnName
(
column
.
get
(
"columnName"
));
columnEntity
.
setDataType
(
column
.
get
(
"dataType"
));
columnEntity
.
setComments
(
column
.
get
(
"columnComment"
));
columnEntity
.
setExtra
(
column
.
get
(
"extra"
));
//列名转换成Java属性名
String
attrName
=
columnToJava
(
columnEntity
.
getColumnName
());
...
...
@@ -76,13 +96,18 @@ public class GenUtils {
columnEntity
.
setAttrname
(
StringUtils
.
uncapitalize
(
attrName
));
//列的数据类型,转换成Java类型
String
attrType
=
config
.
getString
(
columnEntity
.
getDataType
(),
"unknowType"
);
String
attrType
=
config
.
getString
(
columnEntity
.
getDataType
(),
columnToJava
(
columnEntity
.
getDataType
())
);
columnEntity
.
setAttrType
(
attrType
);
if
(!
hasBigDecimal
&&
attrType
.
equals
(
"BigDecimal"
))
{
if
(!
hasBigDecimal
&&
attrType
.
equals
(
"BigDecimal"
))
{
hasBigDecimal
=
true
;
}
if
(!
hasList
&&
"array"
.
equals
(
columnEntity
.
getExtra
()))
{
hasList
=
true
;
}
//是否主键
if
(
"PRI"
.
equalsIgnoreCase
(
column
.
get
(
"columnKey"
))
&&
tableEntity
.
getPk
()
==
null
)
{
if
(
"PRI"
.
equalsIgnoreCase
(
column
.
get
(
"columnKey"
))
&&
tableEntity
.
getPk
()
==
null
)
{
tableEntity
.
setPk
(
columnEntity
);
}
...
...
@@ -97,9 +122,9 @@ public class GenUtils {
//设置velocity资源加载器
Properties
prop
=
new
Properties
();
prop
.
put
(
"file.resource.loader.class"
,
"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"
);
prop
.
put
(
"file.resource.loader.class"
,
"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"
);
Velocity
.
init
(
prop
);
String
mainPath
=
config
.
getString
(
"mainPath"
);
String
mainPath
=
config
.
getString
(
"mainPath"
);
mainPath
=
StringUtils
.
isBlank
(
mainPath
)
?
"io.renren"
:
mainPath
;
//封装模板数据
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
...
...
@@ -111,11 +136,12 @@ public class GenUtils {
map
.
put
(
"pathName"
,
tableEntity
.
getClassname
().
toLowerCase
());
map
.
put
(
"columns"
,
tableEntity
.
getColumns
());
map
.
put
(
"hasBigDecimal"
,
hasBigDecimal
);
map
.
put
(
"hasList"
,
hasList
);
map
.
put
(
"mainPath"
,
mainPath
);
map
.
put
(
"package"
,
config
.
getString
(
"package"
));
map
.
put
(
"moduleName"
,
config
.
getString
(
"moduleName"
));
map
.
put
(
"author"
,
config
.
getString
(
"author"
));
map
.
put
(
"email"
,
config
.
getString
(
"email"
));
map
.
put
(
"package"
,
config
.
getString
(
"package"
));
map
.
put
(
"moduleName"
,
config
.
getString
(
"moduleName"
));
map
.
put
(
"author"
,
config
.
getString
(
"author"
));
map
.
put
(
"email"
,
config
.
getString
(
"email"
));
map
.
put
(
"datetime"
,
DateUtils
.
format
(
new
Date
(),
DateUtils
.
DATE_TIME_PATTERN
));
VelocityContext
context
=
new
VelocityContext
(
map
);
...
...
@@ -124,13 +150,13 @@ public class GenUtils {
for
(
String
template
:
templates
)
{
//渲染模板
StringWriter
sw
=
new
StringWriter
();
Template
tpl
=
Velocity
.
getTemplate
(
template
,
"UTF-8"
);
Template
tpl
=
Velocity
.
getTemplate
(
template
,
"UTF-8"
);
tpl
.
merge
(
context
,
sw
);
try
{
//添加到zip
zip
.
putNextEntry
(
new
ZipEntry
(
getFileName
(
template
,
tableEntity
.
getClassName
(),
config
.
getString
(
"package"
),
config
.
getString
(
"moduleName"
))));
IOUtils
.
write
(
sw
.
toString
(),
zip
,
"UTF-8"
);
zip
.
putNextEntry
(
new
ZipEntry
(
getFileName
(
template
,
tableEntity
.
getClassName
(),
config
.
getString
(
"package"
),
config
.
getString
(
"moduleName"
))));
IOUtils
.
write
(
sw
.
toString
(),
zip
,
"UTF-8"
);
IOUtils
.
closeQuietly
(
sw
);
zip
.
closeEntry
();
}
catch
(
IOException
e
)
{
...
...
@@ -139,20 +165,116 @@ public class GenUtils {
}
}
/**
* 生成mongo其他实体类的代码
*/
public
static
void
generatorMongoCode
(
String
[]
tableNames
,
ZipOutputStream
zip
)
{
for
(
String
tableName
:
tableNames
)
{
MongoDefinition
info
=
MongoManager
.
getInfo
(
tableName
);
currentTableName
=
tableName
;
List
<
MongoGeneratorEntity
>
childrenInfo
=
info
.
getChildrenInfo
(
tableName
);
childrenInfo
.
remove
(
0
);
for
(
MongoGeneratorEntity
mongoGeneratorEntity
:
childrenInfo
)
{
generatorChildrenBeanCode
(
mongoGeneratorEntity
,
zip
);
}
}
}
private
static
void
generatorChildrenBeanCode
(
MongoGeneratorEntity
mongoGeneratorEntity
,
ZipOutputStream
zip
)
{
//配置信息
Configuration
config
=
getConfig
();
boolean
hasList
=
false
;
//表信息
TableEntity
tableEntity
=
mongoGeneratorEntity
.
toTableEntity
();
//表名转换成Java类名
String
className
=
tableToJava
(
tableEntity
.
getTableName
(),
config
.
getStringArray
(
"tablePrefix"
));
tableEntity
.
setClassName
(
className
);
tableEntity
.
setClassname
(
StringUtils
.
uncapitalize
(
className
));
//列信息
List
<
ColumnEntity
>
columsList
=
new
ArrayList
<>();
for
(
Map
<
String
,
String
>
column
:
mongoGeneratorEntity
.
getColumns
())
{
ColumnEntity
columnEntity
=
new
ColumnEntity
();
String
columnName
=
column
.
get
(
"columnName"
);
if
(
columnName
.
contains
(
"."
))
{
columnName
=
columnName
.
substring
(
columnName
.
lastIndexOf
(
"."
)
+
1
);
}
columnEntity
.
setColumnName
(
columnName
);
columnEntity
.
setDataType
(
column
.
get
(
"dataType"
));
columnEntity
.
setExtra
(
column
.
get
(
"extra"
));
//列名转换成Java属性名
String
attrName
=
columnToJava
(
columnEntity
.
getColumnName
());
columnEntity
.
setAttrName
(
attrName
);
columnEntity
.
setAttrname
(
StringUtils
.
uncapitalize
(
attrName
));
//列的数据类型,转换成Java类型
String
attrType
=
config
.
getString
(
columnEntity
.
getDataType
(),
columnToJava
(
columnEntity
.
getDataType
()));
columnEntity
.
setAttrType
(
attrType
);
if
(!
hasList
&&
"array"
.
equals
(
columnEntity
.
getExtra
()))
{
hasList
=
true
;
}
columsList
.
add
(
columnEntity
);
}
tableEntity
.
setColumns
(
columsList
);
//设置velocity资源加载器
Properties
prop
=
new
Properties
();
prop
.
put
(
"file.resource.loader.class"
,
"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"
);
Velocity
.
init
(
prop
);
String
mainPath
=
config
.
getString
(
"mainPath"
);
mainPath
=
StringUtils
.
isBlank
(
mainPath
)
?
"io.renren"
:
mainPath
;
//封装模板数据
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
map
.
put
(
"tableName"
,
tableEntity
.
getTableName
());
map
.
put
(
"comments"
,
tableEntity
.
getComments
());
map
.
put
(
"pk"
,
tableEntity
.
getPk
());
map
.
put
(
"className"
,
tableEntity
.
getClassName
());
map
.
put
(
"classname"
,
tableEntity
.
getClassname
());
map
.
put
(
"pathName"
,
tableEntity
.
getClassname
().
toLowerCase
());
map
.
put
(
"columns"
,
tableEntity
.
getColumns
());
map
.
put
(
"hasList"
,
hasList
);
map
.
put
(
"mainPath"
,
mainPath
);
map
.
put
(
"package"
,
config
.
getString
(
"package"
));
map
.
put
(
"moduleName"
,
config
.
getString
(
"moduleName"
));
map
.
put
(
"author"
,
config
.
getString
(
"author"
));
map
.
put
(
"email"
,
config
.
getString
(
"email"
));
map
.
put
(
"datetime"
,
DateUtils
.
format
(
new
Date
(),
DateUtils
.
DATE_TIME_PATTERN
));
VelocityContext
context
=
new
VelocityContext
(
map
);
//获取模板列表
List
<
String
>
templates
=
getMongoChildTemplates
();
for
(
String
template
:
templates
)
{
//渲染模板
StringWriter
sw
=
new
StringWriter
();
Template
tpl
=
Velocity
.
getTemplate
(
template
,
"UTF-8"
);
tpl
.
merge
(
context
,
sw
);
try
{
//添加到zip
zip
.
putNextEntry
(
new
ZipEntry
(
getFileName
(
template
,
tableEntity
.
getClassName
(),
config
.
getString
(
"package"
),
config
.
getString
(
"moduleName"
))));
IOUtils
.
write
(
sw
.
toString
(),
zip
,
"UTF-8"
);
IOUtils
.
closeQuietly
(
sw
);
zip
.
closeEntry
();
}
catch
(
IOException
e
)
{
throw
new
RRException
(
"渲染模板失败,表名:"
+
tableEntity
.
getTableName
(),
e
);
}
}
}
/**
* 列名转换成Java属性名
*/
public
static
String
columnToJava
(
String
columnName
)
{
return
WordUtils
.
capitalizeFully
(
columnName
,
new
char
[]{
'_'
}).
replace
(
"_"
,
""
);
return
WordUtils
.
capitalizeFully
(
columnName
,
new
char
[]{
'_'
}).
replace
(
"_"
,
""
);
}
/**
* 表名转换成Java类名
*/
public
static
String
tableToJava
(
String
tableName
,
String
[]
tablePrefixArray
)
{
if
(
null
!=
tablePrefixArray
&&
tablePrefixArray
.
length
>
0
)
{
for
(
String
tablePrefix
:
tablePrefixArray
)
{
if
(
null
!=
tablePrefixArray
&&
tablePrefixArray
.
length
>
0
)
{
for
(
String
tablePrefix
:
tablePrefixArray
)
{
tableName
=
tableName
.
replace
(
tablePrefix
,
""
);
}
}
...
...
@@ -164,7 +286,7 @@ public class GenUtils {
*/
public
static
Configuration
getConfig
()
{
try
{
return
new
PropertiesConfiguration
(
"generator.properties"
);
return
new
PropertiesConfiguration
(
"generator.properties"
);
}
catch
(
ConfigurationException
e
)
{
throw
new
RRException
(
"获取配置文件失败,"
,
e
);
}
...
...
@@ -178,45 +300,52 @@ public class GenUtils {
if
(
StringUtils
.
isNotBlank
(
packageName
))
{
packagePath
+=
packageName
.
replace
(
"."
,
File
.
separator
)
+
File
.
separator
+
moduleName
+
File
.
separator
;
}
if
(
template
.
contains
(
"Entity.java.vm"
))
{
if
(
template
.
contains
(
"MongoChildrenEntity.java.vm"
))
{
return
packagePath
+
"entity"
+
File
.
separator
+
"inner"
+
File
.
separator
+
currentTableName
+
File
.
separator
+
splitInnerName
(
className
)+
"InnerEntity.java"
;
}
if
(
template
.
contains
(
"Entity.java.vm"
)
||
template
.
contains
(
"MongoEntity.java.vm"
))
{
return
packagePath
+
"entity"
+
File
.
separator
+
className
+
"Entity.java"
;
}
if
(
template
.
contains
(
"Dao.java.vm"
))
{
if
(
template
.
contains
(
"Dao.java.vm"
))
{
return
packagePath
+
"dao"
+
File
.
separator
+
className
+
"Dao.java"
;
}
if
(
template
.
contains
(
"Service.java.vm"
))
{
if
(
template
.
contains
(
"Service.java.vm"
))
{
return
packagePath
+
"service"
+
File
.
separator
+
className
+
"Service.java"
;
}
if
(
template
.
contains
(
"ServiceImpl.java.vm"
))
{
if
(
template
.
contains
(
"ServiceImpl.java.vm"
))
{
return
packagePath
+
"service"
+
File
.
separator
+
"impl"
+
File
.
separator
+
className
+
"ServiceImpl.java"
;
}
if
(
template
.
contains
(
"Controller.java.vm"
))
{
if
(
template
.
contains
(
"Controller.java.vm"
))
{
return
packagePath
+
"controller"
+
File
.
separator
+
className
+
"Controller.java"
;
}
if
(
template
.
contains
(
"Dao.xml.vm"
))
{
if
(
template
.
contains
(
"Dao.xml.vm"
))
{
return
"main"
+
File
.
separator
+
"resources"
+
File
.
separator
+
"mapper"
+
File
.
separator
+
moduleName
+
File
.
separator
+
className
+
"Dao.xml"
;
}
if
(
template
.
contains
(
"menu.sql.vm"
))
{
if
(
template
.
contains
(
"menu.sql.vm"
))
{
return
className
.
toLowerCase
()
+
"_menu.sql"
;
}
if
(
template
.
contains
(
"index.vue.vm"
))
{
if
(
template
.
contains
(
"index.vue.vm"
))
{
return
"main"
+
File
.
separator
+
"resources"
+
File
.
separator
+
"src"
+
File
.
separator
+
"views"
+
File
.
separator
+
"modules"
+
File
.
separator
+
moduleName
+
File
.
separator
+
className
.
toLowerCase
()
+
".vue"
;
}
if
(
template
.
contains
(
"add-or-update.vue.vm"
))
{
if
(
template
.
contains
(
"add-or-update.vue.vm"
))
{
return
"main"
+
File
.
separator
+
"resources"
+
File
.
separator
+
"src"
+
File
.
separator
+
"views"
+
File
.
separator
+
"modules"
+
File
.
separator
+
moduleName
+
File
.
separator
+
className
.
toLowerCase
()
+
"-add-or-update.vue"
;
}
return
null
;
}
private
static
String
splitInnerName
(
String
name
){
name
=
name
.
replaceAll
(
"\\."
,
"_"
);
return
name
;
}
}
src/main/java/io/renren/utils/MongoScanner.java
0 → 100644
View file @
aa84ce70
package
io
.
renren
.
utils
;
import
com.mongodb.BasicDBObject
;
import
com.mongodb.MongoCommandException
;
import
com.mongodb.client.AggregateIterable
;
import
com.mongodb.client.MongoCollection
;
import
com.mongodb.client.MongoCursor
;
import
io.renren.config.MongoManager
;
import
io.renren.entity.mongo.MongoDefinition
;
import
io.renren.entity.mongo.Type
;
import
org.bson.Document
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.util.*
;
import
java.util.concurrent.ForkJoinPool
;
import
java.util.concurrent.ForkJoinTask
;
import
java.util.concurrent.RecursiveTask
;
import
java.util.stream.Collectors
;
/**
* @author: gxz 514190950@qq.com
**/
public
class
MongoScanner
{
private
Logger
logger
=
LoggerFactory
.
getLogger
(
getClass
());
private
MongoCollection
<
Document
>
collection
;
final
private
int
scanCount
;
private
List
<
String
>
colNames
;
private
MongoDefinition
mongoDefinition
;
private
final
static
int
[]
TYPE
=
{
3
,
16
,
18
,
8
,
9
,
2
,
1
};
private
final
static
int
ARRAY_TYPE
=
4
;
private
final
static
int
MAX_COUNT
=
200000
;
private
final
static
int
DEFAULT_COUNT
=
100000
;
public
MongoScanner
(
MongoCollection
<
Document
>
collection
)
{
this
.
collection
=
collection
;
this
.
scanCount
=
DEFAULT_COUNT
;
scan
();
}
private
void
scan
()
{
// 初始化
initColNames
();
// 解析属性值
mongoDefinition
=
scanType
();
MongoManager
.
putInfo
(
collection
.
getNamespace
().
getCollectionName
(),
mongoDefinition
);
// 解析完成之后释放链接资源
this
.
collection
=
null
;
}
public
MongoDefinition
getProduct
()
{
return
mongoDefinition
;
}
/**
* 功能描述:分组发送聚合函数(获得一级属性名)
*
* @author : gxz
*/
public
List
<
String
>
groupAggregation
(
Integer
skip
,
Integer
limit
)
throws
MongoCommandException
{
skip
=
skip
==
null
?
0
:
skip
;
limit
=
limit
==
null
?
scanCount
:
limit
;
MongoCollection
<
Document
>
collection
=
this
.
collection
;
BasicDBObject
$project
=
new
BasicDBObject
(
"$project"
,
new
BasicDBObject
(
"arrayofkeyvalue"
,
new
BasicDBObject
(
"$objectToArray"
,
"$$ROOT"
)));
BasicDBObject
$unwind
=
new
BasicDBObject
(
"$unwind"
,
"$arrayofkeyvalue"
);
BasicDBObject
$skip
=
new
BasicDBObject
(
"$skip"
,
skip
);
BasicDBObject
$limit
=
new
BasicDBObject
(
"$limit"
,
limit
);
BasicDBObject
filed
=
new
BasicDBObject
(
"_id"
,
"null"
);
filed
.
append
(
"allkeys"
,
new
BasicDBObject
(
"$addToSet"
,
"$arrayofkeyvalue.k"
));
BasicDBObject
$group
=
new
BasicDBObject
(
"$group"
,
filed
);
List
<
BasicDBObject
>
dbStages
=
Arrays
.
asList
(
$project
,
$skip
,
$limit
,
$unwind
,
$group
);
// System.out.println(dbStages); 发送的聚合函数 获得所有参数名称
AggregateIterable
<
Document
>
aggregate
=
collection
.
aggregate
(
dbStages
);
Document
document
=
aggregate
.
first
();
if
(
document
==
null
)
{
BasicDBObject
existsQuery
=
new
BasicDBObject
(
"$ROOT"
,
new
BasicDBObject
(
"$exists"
,
true
));
MongoCursor
<
Document
>
existsList
=
collection
.
find
(
existsQuery
).
limit
(
100
).
iterator
();
Set
<
String
>
keySet
=
new
HashSet
<>();
while
(
existsList
.
hasNext
())
{
Document
next
=
existsList
.
next
();
Map
<
String
,
Object
>
keyMap
=
(
Document
)
next
.
get
(
"$ROOT"
);
keySet
.
addAll
(
keyMap
.
keySet
());
}
return
new
ArrayList
<>(
keySet
);
}
else
{
return
(
List
<
String
>)
document
.
get
(
"allkeys"
);
}
}
/**
* 如果一个文档是对象类型 获得这个属性的下一级的属性名的集合
* 例子: user:{name:"张三",age:12} 传入user 返回[name,age]
*
* @param parameterName 上层参数名 这个参数名可以包含一个或多个.
* 注: 参数传递之前需确认: 1.上层属性一定是对象类型
* @return 返回这个属性内的所有属性名
*/
public
Set
<
String
>
getNextParameterNames
(
String
parameterName
)
{
Document
condition
=
new
Document
(
parameterName
,
new
Document
(
"$exists"
,
true
));
Document
match
=
new
Document
(
"$match"
,
condition
);
String
unwindName
=
parameterName
;
if
(
parameterName
.
contains
(
"."
))
{
unwindName
=
parameterName
.
split
(
"\\."
)[
0
];
}
Document
unwind
=
new
Document
(
"$unwind"
,
"$"
+
unwindName
);
Document
limit
=
new
Document
(
"$limit"
,
3000
);
Document
project
=
new
Document
(
"$project"
,
new
Document
(
"list"
,
"$"
+
parameterName
).
append
(
"_id"
,
false
));
Document
unwind2
=
new
Document
(
"$unwind"
,
"$list"
);
AggregateIterable
<
Document
>
aggregate
=
this
.
collection
.
aggregate
(
Arrays
.
asList
(
match
,
unwind
,
limit
,
project
,
unwind2
));
Set
<
String
>
names
=
new
HashSet
<>();
for
(
Document
document
:
aggregate
)
{
Object
list
=
document
.
get
(
"list"
);
if
(
list
instanceof
Map
)
{
Set
<
String
>
documentNames
=
((
Document
)
list
).
keySet
();
names
.
addAll
(
documentNames
);
}
}
logger
.
info
(
"解析"
+
parameterName
+
"有"
+
names
.
size
()
+
"个子属性"
);
return
names
;
}
/**
* 功能描述:提供属性名 解析属性类型
* 获取相应的属性信息 封装成generator对象
*
* @return : 解析之后的Model {@see #MongoDefinition}
* @param: propertyName 属性名 可以是层级名 比如 name 也可以是info.name
* @see MongoDefinition
*/
public
MongoDefinition
processNameType
(
String
propertyName
)
{
MongoCollection
<
Document
>
collection
=
this
.
collection
;
MongoDefinition
result
=
new
MongoDefinition
();
if
(
"_id"
.
equals
(
propertyName
))
{
result
.
setType
(
2
);
result
.
setPropertyName
(
"_id"
);
return
result
;
}
result
.
setPropertyName
(
propertyName
);
MongoCursor
<
Document
>
isArray
=
collection
.
find
(
new
Document
(
propertyName
,
new
Document
(
"$type"
,
ARRAY_TYPE
))).
limit
(
1
).
iterator
();
if
(
isArray
.
hasNext
())
{
result
.
setArray
(
true
);
for
(
int
i
:
TYPE
)
{
MongoCursor
<
Document
>
iterator
=
collection
.
find
(
new
Document
(
propertyName
,
new
Document
(
"$type"
,
i
))).
limit
(
1
).
iterator
();
if
(
iterator
.
hasNext
())
{
if
(
i
==
3
)
{
result
.
setChild
(
this
.
produceChildList
(
propertyName
));
}
//1是double 2是string 3是对象 4是数组 16是int 18 是long
result
.
setType
(
i
);
logger
.
info
(
"解析["
+
propertyName
+
"]是[List]["
+
Type
.
typeInfo
(
result
.
getType
())
+
"]"
);
return
result
;
}
}
}
else
{
for
(
int
i
:
TYPE
)
{
MongoCursor
<
Document
>
iterator
=
collection
.
find
(
new
Document
(
propertyName
,
new
Document
(
"$type"
,
i
))).
limit
(
1
).
iterator
();
if
(
iterator
.
hasNext
())
{
if
(
i
==
3
)
{
result
.
setChild
(
this
.
produceChildList
(
propertyName
));
}
//1是double 2是string 3是对象 4是数组 16是int 18 是long
//到这里就是数组了
result
.
setType
(
i
);
logger
.
info
(
"解析["
+
propertyName
+
"]是["
+
Type
.
typeInfo
(
result
.
getType
())
+
"]"
);
return
result
;
}
}
result
.
setType
(
2
);
}
logger
.
info
(
"解析["
+
propertyName
+
"]是["
+
Type
.
typeInfo
(
result
.
getType
())
+
"]"
);
return
result
;
}
private
List
<
MongoDefinition
>
produceChildList
(
String
parentName
)
{
Set
<
String
>
nextParameterNames
=
this
.
getNextParameterNames
(
parentName
);
List
<
String
>
strings
=
new
ArrayList
<>(
nextParameterNames
);
List
<
String
>
collect
=
strings
.
stream
().
map
(
name
->
parentName
+
"."
+
name
).
collect
(
Collectors
.
toList
());
ForkJoinPool
pool
=
new
ForkJoinPool
();
ForkJoinTask
<
List
<
MongoDefinition
>>
task
=
new
ForkJoinProcessType
(
collect
);
return
pool
.
invoke
(
task
);
}
private
List
<
String
>
distinctAndJoin
(
List
<
String
>
a
,
List
<
String
>
b
)
{
a
.
removeAll
(
b
);
a
.
addAll
(
b
);
return
a
;
}
/**
* 功能描述:解析这个集合的列名 用ForkJoin框架实现
*/
private
void
initColNames
()
{
long
start
=
System
.
currentTimeMillis
();
int
scan
=
this
.
scanCount
;
long
count
=
this
.
collection
.
countDocuments
();
ForkJoinPool
pool
=
new
ForkJoinPool
();
ForkJoinTask
<
List
<
String
>>
task
;
if
(
count
>
(
long
)
scan
)
{
task
=
new
ForkJoinGetProcessName
(
0
,
scan
);
}
else
{
task
=
new
ForkJoinGetProcessName
(
0
,
(
int
)
count
);
}
this
.
colNames
=
pool
.
invoke
(
task
);
logger
.
info
(
"collection["
+
this
.
collection
.
getNamespace
().
getCollectionName
()
+
"]初始化列名成功..... 用时: "
+
(
System
.
currentTimeMillis
()
-
start
)
+
"毫秒"
);
}
private
MongoDefinition
scanType
()
{
MongoDefinition
result
=
new
MongoDefinition
();
List
<
String
>
colNames
=
this
.
colNames
;
ForkJoinPool
pool
=
new
ForkJoinPool
();
ForkJoinTask
<
List
<
MongoDefinition
>>
task
=
new
ForkJoinProcessType
(
colNames
);
List
<
MongoDefinition
>
invoke
=
pool
.
invoke
(
task
);
return
result
.
setChild
(
invoke
).
setPropertyName
(
this
.
collection
.
getNamespace
().
getCollectionName
());
}
/**
* 功能描述:forkJoin多线程框架的实现 通过业务拆分解析类型
*/
class
ForkJoinProcessType
extends
RecursiveTask
<
List
<
MongoDefinition
>>
{
List
<
String
>
names
;
private
final
int
THRESHOLD
=
6
;
ForkJoinProcessType
(
List
<
String
>
names
)
{
this
.
names
=
names
;
}
@Override
protected
List
<
MongoDefinition
>
compute
()
{
if
(
names
.
size
()
<=
THRESHOLD
)
{
List
<
MongoDefinition
>
result
=
new
ArrayList
<>();
for
(
String
name
:
names
)
{
MongoDefinition
childrenDefinition
=
processNameType
(
name
);
result
.
add
(
childrenDefinition
);
}
return
result
;
}
else
{
int
size
=
names
.
size
();
int
middle
=
size
/
2
;
List
<
String
>
leftList
=
names
.
subList
(
0
,
middle
);
List
<
String
>
rightList
=
names
.
subList
(
middle
,
size
);
ForkJoinProcessType
pre
=
new
ForkJoinProcessType
(
leftList
);
pre
.
fork
();
ForkJoinProcessType
next
=
new
ForkJoinProcessType
(
rightList
);
next
.
fork
();
return
mergeList
(
pre
.
join
(),
next
.
join
());
}
}
}
/**
* 功能描述:forkJoin多线程框架的实现 通过业务拆分获得属性名
*/
class
ForkJoinGetProcessName
extends
RecursiveTask
<
List
<
String
>>
{
private
int
begin
;
//查询开始位置
private
int
end
;
private
final
int
THRESHOLD
=
5000
;
ForkJoinGetProcessName
(
int
begin
,
int
end
)
{
this
.
begin
=
begin
;
this
.
end
=
end
;
}
@Override
protected
List
<
String
>
compute
()
{
int
count
=
end
-
begin
;
if
(
THRESHOLD
>=
count
)
{
return
groupAggregation
(
begin
,
count
);
}
else
{
int
middle
=
(
begin
+
end
)
/
2
;
ForkJoinGetProcessName
pre
=
new
ForkJoinGetProcessName
(
begin
,
middle
);
pre
.
fork
();
ForkJoinGetProcessName
next
=
new
ForkJoinGetProcessName
(
middle
+
1
,
end
);
next
.
fork
();
return
distinctAndJoin
(
pre
.
join
(),
next
.
join
());
//去重合并
}
}
}
public
<
T
>
List
<
T
>
mergeList
(
List
<
T
>
list1
,
List
<
T
>
list2
){
list1
.
addAll
(
list2
);
return
list1
;
}
}
src/main/resources/application.yml
View file @
aa84ce70
...
...
@@ -25,12 +25,23 @@ spring:
# url: jdbc:postgresql://192.168.10.10:5432/renren_fast
# username: postgres
# password: 123456
jackson
:
time-zone
:
GMT+8
date-format
:
yyyy-MM-dd HH:mm:ss
resources
:
static-locations
:
classpath:/static/,classpath:/views/
#mongodb:
# host: localhost
# port: 27017
# auth: false #是否使用密码验证
# username: tincery
# password: renren
# source: 123456
# database: test
mybatis-plus
:
mapperLocations
:
classpath:mapper/**/*.xml
...
...
@@ -42,7 +53,7 @@ pagehelper:
params
:
count=countSql
#指定数据库,可选值有【mysql、oracle、sqlserver、postgresql】
#指定数据库,可选值有【mysql、oracle、sqlserver、postgresql
、mongodb
】
renren
:
database
:
mysql
src/main/resources/generator.properties
View file @
aa84ce70
...
...
@@ -30,6 +30,7 @@ text=String
mediumtext
=
String
longtext
=
String
date
=
Date
datetime
=
Date
timestamp
=
Date
...
...
src/main/resources/template/MongoChildrenEntity.java.vm
0 → 100644
View file @
aa84ce70
package
${
package
}.${
moduleName
}.
entity
;
#
if
(${
hasList
})
import
java
.
util
.
List
;
#
end
import
java
.
io
.
Serializable
;
import
java
.
util
.
Date
;
import
lombok
.
Data
;
import
org
.
springframework
.
data
.
mongodb
.
core
.
mapping
.
Document
;
import
org
.
springframework
.
data
.
annotation
.
Id
;
/**
*
${
comments
}
*
*
@
author
${
author
}
*
@
email
${
email
}
*
@
date
${
datetime
}
*/
@
Data
public
class
${
className
}
InnerEntity
{
#
foreach
($
column
in
$
columns
)
private
#
if
($
column
.
extra
==
"array"
)
List
<#
end
$
column
.
attrType
#
if
($
column
.
extra
==
"array"
)>#
end
$
column
.
attrname
;
#
end
}
src/main/resources/template/MongoEntity.java.vm
0 → 100644
View file @
aa84ce70
package
${
package
}.${
moduleName
}.
entity
;
#
if
(${
hasBigDecimal
})
import
java
.
math
.
BigDecimal
;
#
end
#
if
(${
hasList
})
import
java
.
util
.
List
;
#
end
import
java
.
io
.
Serializable
;
import
java
.
util
.
Date
;
import
lombok
.
Data
;
import
org
.
springframework
.
data
.
mongodb
.
core
.
mapping
.
Document
;
import
org
.
springframework
.
data
.
annotation
.
Id
;
/**
*
${
comments
}
*
*
@
author
${
author
}
*
@
email
${
email
}
*
@
date
${
datetime
}
*/
@
Data
@
Document
(
collection
=
"${tableName}"
)
public
class
${
className
}
Entity
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
#
foreach
($
column
in
$
columns
)
#
if
($
column
.
columnName
==
"id"
)
@
Id
#
end
private
#
if
($
column
.
extra
==
"array"
)
List
<#
end
$
column
.
attrType
#
if
($
column
.
extra
==
"array"
)>#
end
$
column
.
attrname
;
#
end
}
Write
Preview
Markdown
is supported
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