首先问题原因如下:
在查询语句里面Mysql返回的字段名称为数据库字段的名称格式。如:fileName字段 输出 fileName
但,oracle数据库返回的字段名称则全部为大写字段。如:fileName字段 输出 FILENAME
所以,当两中数据库都用如下方法去匹配类中对应的字段变量时,会报如下错误
java.lang.IllegalArgumentException: Could not find field [LOCATION] on target [Student [flowId=0, type=0, idCard=null, examCard=null, studentName=null, location=null, grade=0]]
这是因为大小写的问题,Oracle是没有办法进行操作,而导致配不到该字段所致。
// 5. 若 Map 不为空集, 利用反射创建 clazz 对应的对象
if (values.size() > 0) {
entity = clazz.newInstance();
// 5. 遍历 Map 对象, 利用反射为 Class 对象的对应的属性赋值.
for (Map.Entryentry : values.entrySet()) {
String fieldName = entry.getKey();
Object value = entry.getValue();
ReflectionUtils.setFieldValue(entity, fieldName, value);
}
}
作为替代办法,我现在改用 Beanutils 类进行修改。主要使用该类下的setProperty()方法。
BeanUtils.setProperty(Object, name, value);
Object :是实例化的类
name : 是Object类中的属性名
value :是对name所赋的具体值
该方法其实是对定义的JavaBean代码中get、set方法的拼接。setProperty()方法,就是进行 set+name的一个拼接。
同理get。
例如 对如下的JavaBean轻微set方法改造即可。(将类中的set方法名中的字段名全部改为大写以便跟Beanutils.serProperty(Object,NAME,value)方法中的NAME参数进行匹配)
public class Student {
private int flowId;
private int type;
private String idCard;
private String examCard;
private String studentName;
private String location;
private int grade;
//无参的构造方法
public Student() {
super();
// TODO Auto-generated constructor stub
}
//全参的构造方法
public Student(int flowId, int type, String idCard, String examCard,
String studentName, String location, int grade) {
super();
this.flowId = flowId;
this.type = type;
this.idCard = idCard;
this.examCard = examCard;
this.studentName = studentName;
this.location = location;
this.grade = grade;
}
public int getFlowId() {
return flowId;
}
public void setFLOWID(int flowId) {
this.flowId = flowId;
}
public int getType() {
return type;
}
//set+参数大写
public void setTYPE(int type) {
this.type = type;
}
public String getIdCard() {
return idCard;
}
//set+参数大写
public void setIDCARD(String idCard) {
this.idCard = idCard;
}
public String getExamCard() {
return examCard;
}
//set+参数大写
public void setEXAMCARD(String examCard) {
this.examCard = examCard;
}
public String getStudentName() {
return studentName;
}
//set+参数大写
public void setSTUDENTNAME(String studentName) {
this.studentName = studentName;
}
public String getLocation() {
return location;
}
//set+参数大写
public void setLOCATION(String location) {
this.location = location;
}
public int getGrade() {
return grade;
}
//set+参数大写
public void setGRADE(int grade) {
this.grade = grade;
}
@Override
public String toString() {
return "Student [flowId=" + flowId + ", type=" + type + ", idCard="
+ idCard + ", examCard=" + examCard + ", studentName="
+ studentName + ", location=" + location + ", grade=" + grade
+ "]";
}
}
PS:文末附上两种反射机制的处理代码
在利用反射机制去处理JDBC的查询方法时,我们用到了“泛型”的概念。
具体思路如下:
// 1. 得到 ResultSet 对象
// 2. 得到 ResultSetMetaData 对象
// 3. 创建一个 Map对象,(键值对的形式进行存储)
//键: SQL 查询的列的别名,
// 值: 列的值
// 4. 处理结果集. 利用 ResultSetMetaData 填充 3 对应的 Map 对象
// 5. 若 Map 不为空集, 利用反射创建 clazz 对应的对象
//6. 遍历 Map 对象, 利用反射为 Class 对象的对应的属性赋值.
具体实现如下:
通用型的代码形式(oracle与MySQL均可用)
注:该方式需要手工引入:commons下的三个jar包
commons-beanutils-1.9.2
commons-logging-1.2.jar
commons-collections.jar (注意该jar版本问题,可能出现报
java.lang.NoClassDefFoundError: org/apache/commons/collections/map/LRUMap错误,在commons-collections-2.1.1.jar包中找到了LRUMap.class文件但他没在map文件夹下而是直接放在了collections下。后来换了个包commons-collections-3.1.jar.问题解决)
// 反射机制做查询
public T jdbcSelect(Classclazz, String sql, Object... args) {
T entity = null;
try {
conn = getConn();
pres = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
pres.setObject(i + 1, args[i]);
}
rst = pres.executeQuery();
ResultSetMetaData rsmt = rst.getMetaData();
HashMapmap = new HashMap();
while (rst.next()) {
for (int i = 0; i < rsmt.getColumnCount(); i++) {
String columnLable = rsmt.getColumnLabel(i + 1);
Object columnValue = rst.getObject(i + 1);
//System.out.println(columnLable + "=====" + columnValue);
map.put(columnLable, columnValue);
}
}
if (map.size() > 0) {
entity = clazz.newInstance();
for (Map.Entryentry : map.entrySet()) {
String filedName = entry.getKey();
Object filedVaule = entry.getValue();
System.out.println(filedName + "=====" + filedVaule);
//MySql可以实现的方法
ReflectionUtils.setFieldValue(entity, fieldName, value);
//Oracle,MySql通用方法
BeanUtils.setProperty(entity, filedName, filedVaule);
}
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
releaseJDBC(conn, pres, rst);
}
return entity;
}