对于Oracle中Number类型的字段映射成Java中的具体类型的问题
我在Oracle中给一个用户Id字段设置为Number类型,使用JDBC在完成ORM的时候,以为其可以自动转换为Integer,因为我的POJO类id使用的就是Integer。但事实是,我在测试的时候,发现所有的用户id全为null,还在奇怪明明数据库中id是有值的,为什么取不到?
原因在于Oracle的Number类型映射为Java类型中的 java.math.BigDecimal (不可变的、任意精度的有符号十进制数)类型,并不是我简单认为的 Integer ,还会报一个错误:

就是说BigDecimal 的字段不能set进Integer类型的属性中
我发现,其实如果使用原生的JDBC来封装数据,在这个id字段上,直接使用rs.getInt进我们的Integer字段是没有问题的:
public List<User> findList2() throws Exception {
Connection connection=null;
PreparedStatement ps=null;
ResultSet rs=null;
List<User> list=null;
try {
connection = super.getConnection();
String sql="select eu_user_id from easybuy_user";
ps = connection.prepareStatement(sql);
rs = ps.executeQuery();
list = new ArrayList<User>();
while(rs.next()){
User user=new User();
user.setEu_user_id(rs.getInt("eu_user_id"));
list.add(user);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
super.closeAll(connection, ps, rs);
}
return list;
}
那么为什么我会出现这个错误呢?
原因在于为了方便JDBC的编写,我使用一个进行简单封装的BaseDaoImpl,它的查询使用的反射来做的,好像也必须使用反射,因为每个POJO类的属性类型不一致嘛:
ublic List<Object> executeQuery2(String sql, Object[] objParam, Class<?> className) throws Exception {
List<Object> list = new ArrayList<Object>();
Connection conn = this.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = null;
if (objParam != null) {
for (int i = 0; i < objParam.length; i++) {
ps.setObject((i + 1), objParam[i]);
}
}
rs = ps.executeQuery();
//Class<?> clz = Class.forName(className);
Class<?> clz=className;
Field[] fs = clz.getDeclaredFields();
while (rs.next()) {
Object objInstrance = clz.newInstance();
for (Field f : fs) {
try {
String fieldName = f.getName();
Object fieldValue = rs.getObject(fieldName);
//System.out.println(fieldName+":"+fieldValue+"\t"+f.getType()+"\t"+fieldValue.getClass());
f.setAccessible(true);
f.set(objInstrance, fieldValue);
} catch (Exception ex) {
ex.printStackTrace();
}
}
list.add(objInstrance);
}
this.closeAll(conn, ps, rs);
return list;
}
没有对BigDecimal类型进行处理,我们也不太可能在POJO中使用BigDecimal类型,所以就没能将BigDecimal 的字段映射成Integer ,就报上面的异常了,稍微修改一下,加一个判断:
public List<Object> executeQuery2(String sql, Object[] objParam, Class<?> className) throws Exception {
List<Object> list = new ArrayList<Object>();
Connection conn = this.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = null;
if (objParam != null) {
for (int i = 0; i < objParam.length; i++) {
ps.setObject((i + 1), objParam[i]);
}
}
rs = ps.executeQuery();
//Class<?> clz = Class.forName(className);
Class<?> clz=className;
Field[] fs = clz.getDeclaredFields();
while (rs.next()) {
Object objInstrance = clz.newInstance();
for (Field f : fs) {
try {
String fieldName = f.getName();
Object fieldValue = rs.getObject(fieldName);
if("java.math.BigDecimal".equals(fieldValue.getClass().getName()))
{ //如果是java.math.BigDecimal类型属性,就转换为Integer,使用Integer的parseInt即可
fieldValue=Integer.parseInt(fieldValue.toString());
}
//System.out.println(fieldName+":"+fieldValue+"\t"+f.getType()+"\t"+fieldValue.getClass());
f.setAccessible(true);
f.set(objInstrance, fieldValue);
} catch (Exception ex) {
ex.printStackTrace();
}
}
list.add(objInstrance);
}
this.closeAll(conn, ps, rs);
return list;
}
这只是一种折中的办法,因为我们的java.math.BigDecimal类型只能转换为Integer了,如果POJO中id类型为Long,又不行了。所以存在一定的局限性,不太灵活。应该是根据我们POJO类中的id属性的具体类型去转换,我不知道具体的代码应该怎样去写。
或许我们应该使用 commons-dbutils.jar 中的QueryRunner类作为BaseDao来使用?我在(Jsp+Servlet+JDBC的使用复习)中使用了一个TxQueryRunner类就是对QueryRunner进行了简单封装。
一般情况下,我们不太会遇到这种异常的出现,因为强大的框架已经帮助我们完成了这些琐碎问题的处理,但是适时的了解一下底层的东西,还是有一定好处的
对于Oracle中Number类型的字段映射成Java中的具体类型的问题的更多相关文章
- Oracle中的自连接(self join)-当表中的某一个字段与这个表中另外字段的相关时,我们可能用到自连接。
http://blog.163.com/wkyuyang_001/blog/static/10802122820091751049479/ 当表中的某一个字段与这个表中另外字段的相关时,我们可能用到自 ...
- 1、c#中可以有静态构造方法,而java中没有,例如在单例模式中c#可以直接在静态构造中实例化对象,而java不可以
1.c#中可以有静态构造方法,而java中没有,例如在单例模式中c#可以直接在静态构造中实例化对象,而java不可以
- [原创]java WEB学习笔记81:Hibernate学习之路--- 对象关系映射文件(.hbm.xml):hibernate-mapping 节点,class节点,id节点(主键生成策略),property节点,在hibernate 中 java类型 与sql类型之间的对应关系,Java 时间和日期类型的映射,Java 大对象类型 的 映射 (了解),映射组成关系
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- C++中的类型判断typeid()操作与java中的 instanceof 做比较
这是RTTI(运行阶段类型识别)的问题,c++有三个支持RTTI的元素: 1. dynamic_cast 操作符 如果可能的话,dynamic_cast操作符将使用一个指向基类的指针来生成一个 ...
- java将字段映射成另一个字段,关于 接口传参 字段不对应转换
在接口开发中我们经常会遇到一个问题,打个比方,我们的实体类A中有两个字段user和pwd但是接口中需要username和password这怎么办呢,我想到了两种方法:1.新创建一个实体类B或者new一 ...
- Java中的关键字有哪些?「Java中53个关键字的意义及使用方法」
Java中的关键字有哪些? 1)48个关键字:abstract.assert.boolean.break.byte.case.catch.char.class.continue.default.do. ...
- 平行世界中的你还是你吗?--java中的==是否相等
故事背景 <宇宙追缉令>是黄毅瑜执导的动作科幻类电影,由哥伦比亚三星公司出品,戴尔里·林多.李连杰.杰森·斯坦森领衔主演.影片于2001年11月2日在美国上映.该片讲述了邪恶尤兰,为了成为 ...
- python中实现将普通字典dict转换为java中的treeMap
上代码: from heapq import heappush,heappop from collections import OrderedDict def toTreeMap(paramMap): ...
- 关于C++类定义中不能声明该类对象,而Java中可以的原因
相信接触过C++的人,在学习Java的过程当中,会遇到这样一个问题:在Java中常常会在类定义中声明一个该类的对象(例如Person类定义中声明一些叫parents之类的Person对象),但是在C+ ...
随机推荐
- 【PL/SQL编程】数据类型说明
1. 数值类型 数值类型主要包括NUMBER.PLS_INTEGER.和BINARY_INTEGER 3种基本类型.NUMBER可以用来存储整数或浮点数,PLS_INTEGER和BINARY_INTE ...
- Buildroot构建指南——工具链
Linux系统的交叉编译工具链用来将源代码变成bin文件或者库文件的一个软件.一般大家默认工具链等于gcc或者arm-linux-gcc,但是实际上,gcc只是工具链的编译器部分,不是全部,制作一个工 ...
- OpenGL实现相机视频NV21格式转RGB格式
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解 ...
- Freemaker的java.beans.IntrospectionException: type mismatch between read and write methods
引言:freemaker在特定的spring以及jdk下的问题解决路径. 环境描述 spring 3.1.1, jdk1.8u80, freemake 2.3.19 错误信息描述: 严重: Excep ...
- TeamTalk源码分析(十一) —— pc客户端源码分析
--写在前面的话 在要不要写这篇文章的纠结中挣扎了好久,就我个人而已,我接触windows编程,已经六七个年头了,尤其是在我读研的三年内,基本心思都是花在学习和研究windows程序上 ...
- UE4中类自动生成代码解析
本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/73189272 作者:car ...
- JMter中添加断点和关联
一. 断点 断言是什么呢,它是用来检查返回结果对不对的. 用来验证结果是否正确,如果正确的话,就代表这个请求的返回是正确的,如果没有的话就代表这个请求的结果和我们预期的不一致,这 ...
- java面试题大纲
跳槽时时刻刻都在发生,但是我建议大家跳槽之前,先想清楚为什么要跳槽.切不可跟风,看到同事一个个都走了,自己也盲目的开始面试起来(期间也没有准备充分),到底是因为技术原因(影响自己的发展,偏移自己规划的 ...
- Android常见问题——Genymotion无法启动问题
在官网下载了Genymotion和VirturalBox的合集安装之后启动模拟器的时候发现启动不了(默认下载,啥都没干),在网上找了一些方法,也没有解决,最后偶然看到一种方法才解决的,先看一下具体的问 ...
- c语言第4次作业
题目7-2九九乘法表 1.代码: #include<stdio.h> int main() { int N, i, j, q; scanf("%d",&N); ...