前言
这次被环境坑惨了额,本来制定的实现方案是要求家里搭建个oracel环境的(本机资源有限不想装)。然后领导觉得没必要,没有跟运维下发这个环境搭建的任务,在群里我也不想反驳,不然又落下个不给领导面子。结果周五,确实有需要调试,上报风险,领导火急火燎的要搞,运维说要到下周一了,又结果搭建的环境莫名其妙。最后还是自己搭建到本机,不然还要莫名其妙。
一、oracle新版本特性
我好几年前用的最新版是11g,后来换工作,一般公司都用不起oracle,本次我装的是最新版本的21c。记忆中的以前几板斧创建用户、授权,开用,居然不好使了,创建用户就报错。原来从12c就分CDB、PDB,在CDB容器中创建用户需要带c##,具体的我也不多说,有博友写的很详细了,oracle环境切换与创建用户详解
二、坑的过程
1.查询字段别名驼峰
我这么处理本来是准备方便做resultSet对象转对象的,结果居然查询结果一个都没转换到对象的属性,看sql执行结果,又是正常的。
解决:
全部改_ + 大写,管你是win还是centos、服务器是否设置了不区分大小写。(以前用sybase数据库要求字段都大写)
2.转对象的坑
我的想法是resultSet + json + 反射,转换成对象,看看我的处理方法:
while (resultSet.next()) {
//结果集转json
//JSONObject jsonObj = RefUtil.getJsonObjData(resultSet, XzdProjectResult.class);
JSONObject jsonObj = RefUtil.getJsonObjDataByIndex(resultSet, XzdProjectResult.class);
//log.info("----后"+JSONUtil.toJsonStr(jsonObj)+"----");
//json转实体
XzdProjectResult projectResult = JSONUtil.toBean(jsonObj, XzdProjectResult.class);
.....
}
上面的RefUtil.getJsonObjData就是自己写的公共方法,讲resultSet转为json对象,下面再用jsonutil工具转对象。
/**
* jdbcResultSet和实体class一起转换json
*
* @param resultSet jdbcResultSet
* @param clazz class
* @return json
*/
public static JSONObject getJsonObjData(ResultSet resultSet, Class clazz) {
JSONObject jsonObj = new JSONObject();
Field[] fields = ReflectUtil.getFields(clazz);
if (ArrayUtil.isNotEmpty(fields)) {
Arrays.stream(fields).forEach(c -> {
String name = c.getName();
String lineName = RefUtil.humpToLine(name);
try {
Object resultObj = resultSet.getObject(lineName);
jsonObj.putOpt(name, resultObj);
} catch (Exception e) {
log.debug("(字段小写驼峰)查询结果没有字段{}或转换异常,原因:{}", lineName, e.getMessage());
String columnUpName = lineName.toUpperCase();
try {
Object resultObj = resultSet.getObject(columnUpName);
jsonObj.putOpt(name, resultObj);
} catch (SQLException ex) {
log.debug("(字段全大写)查询结果没有字段{}或转换异常,原因:{}", columnUpName, ex.getMessage());
}
}
});
}
return jsonObj;
}
PS:这里面已经冗余了先取小写、再取大写,结果依然没有从resultSet取到属性,我整改人都不好了。然后只能在写个变种方法处理。
利用ResultSetMetaData
/**
* 通过result的index转jsonobj
*
* @param resultSet
* @param clazz
* @return
*/
public static JSONObject getJsonObjDataByIndex(ResultSet resultSet, Class clazz) {
Map<String, String> columnMp = new HashMap<>();
JSONObject jsonObj = new JSONObject();
Field[] fields = ReflectUtil.getFields(clazz);
if (ArrayUtil.isNotEmpty(fields)) {
Arrays.stream(fields).forEach(c -> {
String name = c.getName();
String lineName = RefUtil.humpToLine(name);
columnMp.put(lineName.toUpperCase(), name);
});
}
try {
//获取结果集的元数据:ResultSetMetaData
ResultSetMetaData rsmd = resultSet.getMetaData();
//通过结果集的元数据获得列数
int columnCount = rsmd.getColumnCount();
if (resultSet.next()) {
for (int i = 0; i < columnCount; i++) {
Object value = resultSet.getObject(i + 1);
//获取每个列的列名
String columnName = rsmd.getColumnName(i + 1);
String beanpropName = columnMp.get(columnName);
jsonObj.putOpt(beanpropName, value);
}
}
} catch (SQLException e) {
//throw new RuntimeException(e);
log.error("查询结果resultSet转jsonObj异常,原因:", e.getMessage());
}
return jsonObj;
}
结果就ok了。
总结
1、oracle还是那么强大,补充几个命令lsnrctl start、lsnrctl status、lsnrctl stop查看、重启、停止监听的命令(在windows里的服务里也可以去操作)
2、sqlplus命令框里连接数据库,后面按照提示输入直到出现sql>