Java 生成sql mock 文件 json转sql mock
一、概述
1、把一个json 数组文件,如何转换成 sql mock的形式呢?
2、假设json数组如下 (Navicat 导出的表数据):
{
"RECORDS": [
{
"id": "1",
"name": "小明",
"age": "18",
"addr": "东城区"
},
{
"id": "2",
"name": "小红",
"age": "22",
"addr": "西城区"
}
]
}
3、定义的sql mock格式如下:
SELECT
1 AS id,
'小明' AS NAME,
18 AS age,
'东城区' AS addr
FROM DUAL
UNION ALL
SELECT
2 AS id,
'小红' AS NAME,
22 AS age,
'西城区' AS addr
FROM DUAL
4、即拼接字符串,生成: SELECT 1 as id FROM DUAL 这种形式的字符串即可!
二、实现思路
1、使用 IO流,读取 josn文件,转换为 json 字符串
2、使用 jackson 反序列化字符串,转换为 Map 对象
3、拼接字符串生成 sql mock 格式字符串/ 文件
三、代码实现
1、使用 IO流,读取 josn文件,转换为 json 字符串
/**
* @Description: 根据json文件,生成sql的mock数据
* @example 这种:SELECT 1 as id , '哈哈' as name FROM dual
* @param filePath json文件路径
* @param destPath 生成的sql文件路径 --- 传参null不生成文件
* @return void
* @version v1.0
* @author wu
* @date 2021年12月9日 下午5:11:52
*/
public static void genSQL(String filePath , String destPath){
// 读取json文件,转换为字符串
String str = ReadJsonTest.read(filePath);
generate(str , destPath);
}
2、使用 jackson 反序列化字符串,转换为 Map 对象
/**
* @Description: 生成 sql mock 格式文件
* @param str --- josn字符串
* @param destPath --- 生成文件存放路径
* @return void
* @version v1.0
* @author wu
* @date 2021年12月9日 下午5:22:33
*/
private static void generate(String str, String destPath) {
// json 字符串反序列化为 Map对象
Map<?, ?> maps = JsonMapper.getInstance().fromJson(str, Map.class);
@SuppressWarnings("unchecked")
List<Map<String , Object>> list = (List<Map<String , Object>>)maps.get("RECORDS");
generate(list, destPath);
}
3、拼接字符串生成 sql mock 格式字符串/ 文件
/**
* @Description: 拼接字符串 生成 sql mock 文件
* @param list
* @param destPath
* @return void
* @version v1.0
* @author wu
* @date 2021年12月10日 上午10:50:49
*/
private static void generate(List<Map<String , Object>> list, String destPath) {
StringBuffer sb = new StringBuffer();
int count = 1 ; //
for(int x = 0 , length = list.size() ; x < length ; x++ ) {
Map<String, Object> map = (Map<String, Object>)list.get(x);
Iterator<Entry<String, Object>> iterator = map.entrySet().iterator();
sb.append(SELECT);
int mapSize = map.size();
int mapCount = 1 ;
while(iterator.hasNext()) {
Entry<String, Object> next = iterator.next();
String k = next.getKey();
Object v = next.getValue();
if(v instanceof String && NumberUtils.isCreatable(String.valueOf(v))){
// 增加判断,如果为 数字类型,则不增加单引号 ''
// SELECT 1 as id , '哈哈' as name FROM dual
sb.append(TAB).append(v).append(TAB);
}else {
// SELECT 'uuid-123' as id , '哈哈' as name FROM dual
sb.append(TAB).append(QUOTES).append(v).append(QUOTES).append(TAB);
}
// 添加 字段名 AS name
sb.append(AS).append(TAB).append(k).append(TAB);
if(mapSize != mapCount) {
// 最后一列字段,不需要添加“,” 逗号
sb.append(",");
}
mapCount++;
}
sb.append(FROM_DUAL).append(TAB);
if(length != count) {
// 最后一行数据,不需要添加 union all
sb.append(UNION_ALL).append(TAB);
}
count++;
}
System.out.println("生成的sql内容如下:"+TAB + sb.toString());
if(StringUtils.isNotBlank(destPath)) {
ReadJsonTest.writer(sb.toString(), destPath);
}
}
以上,即可生成步骤【一-3】中格式sql mock 文件
四、总结
1、以上只是个简单的实现,核心在于字符串的拼接 , 方法中用到的常量如下:
/**
* SQL 中 select 关键字
*/
static final String SELECT = "SELECT" ;
/**
* FROM DUAL 关键字
*/
static final String FROM_DUAL = "FROM DUAL" ;
/**
* tab 制表符
*/
static final String TAB = "\t" ;
/**
* UNION ALL 关键字
*/
static final String UNION_ALL = "UNION ALL" ;
/**
* SQL 中 AS 关键字
*/
static final String AS = "AS" ;
/**
* quotes 单引号
*/
static final String QUOTES = "'";
2、注意做好边界处理,拼接中,要注意:
- 最后一列字段,不需要加 ”,“ 逗号
- 最后一行字段,不需要加 UNION ALL 关键字连接
3、有兴趣的,可以继续往下做:做成文件导入的 , 导入json文件,导入excel ; 返回 sql 文件 ...
4、若不理解的,可以私聊,直接提供 源代码工具类 ,谢谢。