1:背景
偶然的原因,第一次接触 jdbc 调用 oracle 数据库的场景,开始的时候,也是尝尽了苦头。包括 oracle 数据分页没有 limit ,字段会自动变成大写,类型转换异常,模糊查询等等。
2:orcale 数据查询返回的字段全是大写的 & 类型转换
针对一条数据的单独查询,比如,根据 id 查询数据,有如下代码:
/**
* 针对于不同的表的通用的查询操作,返回表中的一条记录
*/
public <T> T getInstance(Class<T> clazz,String sql, Object... args) {
JDBC jdbc = new JDBC();
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = jdbc.getConnection();
ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
rs = ps.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
if (rs.next()) {
T t = clazz.newInstance();
for (int i = 0; i < columnCount; i++) {
Object columValue = rs.getObject(i + 1);
String columnLabel = rsmd.getColumnLabel(i + 1);
// 给t对象指定的columnName属性,赋值为columValue:通过反射,获取的数据库字段都是大写的,需要写方法去转化
// 我这边是定义了一个数据库返回的大写字段和对象字段的枚举,用来转化
Field field = clazz.getDeclaredField(Objects.requireNonNull(getFieldName(columnLabel)));
field.setAccessible(true);
// oracle 数据库定义的 number() 类型,返回过来的是 BigDecimal
if(!Objects.isNull(columValue) && "java.math.BigDecimal".equals(columValue.getClass().getName())){
columValue=Integer.parseInt(String.valueOf(columValue));
}
// oracle 数据库定义的 date 类型,返回过来的是 Timestamp
if(!Objects.isNull(columValue) && "java.sql.Timestamp".equals(columValue.getClass().getName())){
Timestamp tt= (Timestamp) columValue;
columValue=new Date(tt.getTime());
}
field.set(t, columValue);
}
return t;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
jdbc.closeResource(conn, ps, rs);
}
return null;
}
转化 oracle 返回字段和对象字段的方法:
/**
* 转化 oracle 返回字段和对象字段,前提是定义好相应的枚举对象
*/
private String getFieldName(String columnLabel){
for (InterfaceDtoEnum value : InterfaceDtoEnum.values()) {
if(value.getColumName().equals(columnLabel)){
return value.getFiledName();
}
}
return null;
}
3:orcale 多条数据的查询
/**
* 针对于不同的表的通用的查询操作,返回表中的多条记录
*/
public <T> List<T> getForList(Class<T> clazz, String sql, Object... args){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
JDBC jdbc = new JDBC();
try {
conn = jdbc.getConnection();
ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
rs = ps.executeQuery();
// 获取结果集的元数据 :ResultSetMetaData
ResultSetMetaData rsmd = rs.getMetaData();
// 通过ResultSetMetaData获取结果集中的列数
int columnCount = rsmd.getColumnCount();
//创建集合对象
ArrayList<T> list = new ArrayList<>();
while (rs.next()) {
T t = clazz.newInstance();
// 处理结果集一行数据中的每一个列:给t对象指定的属性赋值
for (int i = 0; i < columnCount; i++) {
// 获取列值
Object columValue = rs.getObject(i + 1);
// 获取每个列的列名
String columnLabel = rsmd.getColumnLabel(i + 1);
// 给t对象指定的columnName属性,赋值为columValue:通过反射
String fieldName = getFieldName(columnLabel);
if(!StringUtils.isEmpty(fieldName)){
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
if(!Objects.isNull(columValue) &"java.math.BigDecimal".equals(columValue.getClass().getName())){
columValue=Integer.parseInt(String.valueOf(columValue));
}
if(!Objects.isNull(columValue) && "java.sql.Timestamp".equals(columValue.getClass().getName())){
Timestamp tt= (Timestamp) columValue;
columValue=new Date(tt.getTime());
}
field.set(t, columValue);
}
}
list.add(t);
}
return list;
} catch (Exception e) {
e.printStackTrace();
} finally {
jdbc.closeResource(conn, ps, rs);
}
return null;
}
3:orcale 通用的增删改
/**
* 通用的增删改操作
*/
public void update(String sql, Object ...args){
JDBC jdbc = new JDBC();
Connection conn = null;
PreparedStatement ps = null;
try {
//1.获取数据库连接
conn =jdbc.getConnection();
//2.预编译sql语句,返回PreparedStatement的实列
ps = conn.prepareStatement(sql);
//3.填充占位符
for (int i=0;i<args.length;i++){
ps.setObject(i + 1, args[i]);
}
//4.执行
boolean execute = ps.execute();
} catch (Exception e) {
e.printStackTrace();
}finally {
//5.资源的关闭
jdbc.closeResource(conn,ps);
}
}
4: orcale 的模糊查询,根据时间排序,并分页
参考如下代码:
public List<InterfaceDto> getInterfacesByParams(InterfaceRequest request) {
String string1 = (StringUtils.isEmpty(request.getMethod())) ? ("'%'") : ("'%" + request.getMethod() + "%'");
String string2 = (StringUtils.isEmpty(request.getInterfaceName())) ? ("'%'") : ("'%" + request.getInterfaceName() + "%'");
String string3 = (StringUtils.isEmpty(request.getUrl())) ? ("'%'") : ("'%" + request.getUrl() + "%'");
String string4 = (StringUtils.isEmpty(request.getApplyLabel())) ? ("'%'") : ("'%" + request.getApplyLabel() + "%'");
String sql ="select * from (" +
"select T.*,ROWNUM rn from (" +
"select * from interface_dto A " +
"where NVL(method,0) like " + string1 +
"and NVL(interface_name,0) like" + string2 +
"and NVL(url,0) like" + string3 +
"and NVL(apply_label,0) like" + string4 +
"and valid =1 and latest_version=1 order by create_time desc) T )D" +
"where rn between ? and ?";
Integer end= request.getPageIndex() * request.getPageSize();
Integer start= (request.getPageIndex()-1) * request.getPageSize() +1;
List<InterfaceDto> list = interfaceJdbc.getForList(InterfaceDto.class, sql,end, start);
return list;
}