在不整合框架的情况下,使用jdbc从数据库读取数据时都得一个个的get和set,不仅累代码还显得不简洁,所以利用java的反射机制写了一个工具类,这样用jdbc从数据库拿数据的时候就不用那么麻烦了。

因为很多情况下数据不止一条,所以返回的是对象类的一个集合。

需要注意的地方:在这里,数据库字段命名格式为:user_name 下划线格式,而java类型的命名格式为驼峰命名格式。

具体代码如下:

package com.xc.sap.util;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList; import cnblogs.com.ooo0.oracle.OperateOracle; public class Test { public static void main(String[] args) {
try {
// oracle数据库连接
OperateOracle oo = new OperateOracle();//https://www.cnblogs.com/ooo0/p/10225374.html
Connection connection = oo.getConnection(); String mainSql = "select * from users";
PreparedStatement pstm = connection.prepareStatement(mainSql);
ResultSet rs = pstm.executeQuery(); ArrayList<Users> putResult = ResultSetPropertiesSimplifyHelps.putResult(rs, Users.class); for (int i = 0; i < putResult.size(); i++) {
System.out.println(putResult.get(i).toString());
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}
package com.xc.sap.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date; /**
* java jdbc ResultSet结果通过java反射赋值给java对象
*
* @author xc
*/
public class ResultSetPropertiesSimplifyHelps { /**
* 把ResultSet的结果放到java对象中
*
* @param <T>
* @param rs
* ResultSet
* @param obj
* java类的class
* @return
*/
public static <T> ArrayList<T> putResult(ResultSet rs, Class<T> obj) {
try {
ArrayList<T> arrayList = new ArrayList<T>();
ResultSetMetaData metaData = rs.getMetaData();
/**
* 获取总列数
*/
int count = metaData.getColumnCount();
while (rs.next()) {
/**
* 创建对象实例
*/
T newInstance = obj.newInstance();
for (int i = 1; i <= count; i++) {
/**
* 给对象的某个属性赋值
*/
String name = metaData.getColumnName(i).toLowerCase();
name = toJavaField(name);// 改变列名格式成java命名格式
String substring = name.substring(0, 1);// 首字母大写
String replace = name.replaceFirst(substring, substring.toUpperCase());
Class<?> type = null;
try {
type = obj.getDeclaredField(name).getType();// 获取字段类型
} catch (NoSuchFieldException e) { // Class对象未定义该字段时,跳过
continue;
} Method method = obj.getMethod("set" + replace, type);
/**
* 判断读取数据的类型
*/
if (type.isAssignableFrom(String.class)) {
method.invoke(newInstance, rs.getString(i));
} else if (type.isAssignableFrom(byte.class) || type.isAssignableFrom(Byte.class)) {
method.invoke(newInstance, rs.getByte(i));// byte 数据类型是8位、有符号的,以二进制补码表示的整数
} else if (type.isAssignableFrom(short.class) || type.isAssignableFrom(Short.class)) {
method.invoke(newInstance, rs.getShort(i));// short 数据类型是 16 位、有符号的以二进制补码表示的整数
} else if (type.isAssignableFrom(int.class) || type.isAssignableFrom(Integer.class)) {
method.invoke(newInstance, rs.getInt(i));// int 数据类型是32位、有符号的以二进制补码表示的整数
} else if (type.isAssignableFrom(long.class) || type.isAssignableFrom(Long.class)) {
method.invoke(newInstance, rs.getLong(i));// long 数据类型是 64 位、有符号的以二进制补码表示的整数
} else if (type.isAssignableFrom(float.class) || type.isAssignableFrom(Float.class)) {
method.invoke(newInstance, rs.getFloat(i));// float 数据类型是单精度、32位、符合IEEE 754标准的浮点数
} else if (type.isAssignableFrom(double.class) || type.isAssignableFrom(Double.class)) {
method.invoke(newInstance, rs.getDouble(i));// double 数据类型是双精度、64 位、符合IEEE 754标准的浮点数
} else if (type.isAssignableFrom(BigDecimal.class)) {
method.invoke(newInstance, rs.getBigDecimal(i));
} else if (type.isAssignableFrom(boolean.class) || type.isAssignableFrom(Boolean.class)) {
method.invoke(newInstance, rs.getBoolean(i));// boolean数据类型表示一位的信息
} else if (type.isAssignableFrom(Date.class)) {
method.invoke(newInstance, rs.getDate(i));
}
}
arrayList.add(newInstance);
}
return arrayList; } catch (InstantiationException | IllegalAccessException | SQLException | SecurityException | NoSuchMethodException | IllegalArgumentException
| InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} return null;
} /**
* 数据库命名格式转java命名格式
*
* @param str
* 数据库字段名
* @return java字段名
*/
public static String toJavaField(String str) { String[] split = str.split("_");
StringBuilder builder = new StringBuilder();
builder.append(split[0]);// 拼接第一个字符 // 如果数组不止一个单词
if (split.length > 1) {
for (int i = 1; i < split.length; i++) {
// 去掉下划线,首字母变为大写
String string = split[i];
String substring = string.substring(0, 1);
split[i] = string.replaceFirst(substring, substring.toUpperCase());
builder.append(split[i]);
}
} return builder.toString();
} }

参考文章:

https://blog.csdn.net/a975261294/article/details/70049963

优化内容:

1.NoSuchFieldException异常处理,Class对象未定义该字段时,跳过

2.完善了大部分的基本数据类型的取值 http://www.runoob.com/java/java-basic-datatypes.html

java jdbc ResultSet结果通过java反射赋值给java对象的更多相关文章

  1. [原创] Java JDBC连接数据库,反射创建实体类对象并赋值数据库行记录(支持存储过程)

    1.SqlHelper.java import java.lang.reflect.*; import java.sql.*; import java.util.*; public class Sql ...

  2. JAVA基础知识之JDBC——ResultSet的滚动和更新(statement的额外参数)

    ResultSet不仅可以内存中的一张二维表一样保存statement执行SQL的结果集,还能通过结果集修改DB的数据.ResultSetMetaData则可以用来获得ResultSet对象的相关信息 ...

  3. java jdbc 封装。。

    JDBC工具类...package it.cast.jdbcutils; import java.io.InputStream; import java.sql.Connection; import ...

  4. Java JDBC下执行SQL的不同方式、参数化预编译防御

    相关学习资料 http://zh.wikipedia.org/wiki/Java数据库连接 http://lavasoft.blog.51cto.com/62575/20588 http://blog ...

  5. java jdbc 连接mysql 数据库

    JDBC连接MySQL 加载及注册JDBC驱动程序 Class.forName("com.mysql.jdbc.Driver"); Class.forName("com. ...

  6. java JDBC (一)

    package cn.sasa.demo1; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Re ...

  7. java JDBC链接sqlserver/mysql/oracle

    今天初学数据库的一些简单创建数据库和表,并进行简单的查询,插入. 接下学习的就是java工程中怎么链接数据库呢.主要的方法和用到的类如下. 切记,mysql需要的jar包 mysql-connecto ...

  8. JAVA JDBC(存储过程和事务管理)

    1.什么是存储过程 存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程 ...

  9. java jdbc与odbc数据库的连接mysql数据库

    1.jdbc连接数据库要添加mysql-connector-java-5.1.38-bin.jar库 2.odbc连接数据库要添加odbc数据源 3.测试代码 DBHelper.java代码jdbc连 ...

随机推荐

  1. Linux查杀stopped进程

      在Linux系统下面,top命令可以查看查看stopped进程.但是不能查看stopped进程的详细信息.那么如何查看stopped 进程,并且杀掉这些stopped进程呢? ps -e j | ...

  2. jQuery如何制作动画

    下面为一组图片(四张)展示 1 2 3 4 页面代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN& ...

  3. Cs231n-assignment 2作业笔记

    assignment 2 assignment2讲解参见: https://blog.csdn.net/BigDataDigest/article/details/79286510 http://ww ...

  4. VMware虚拟机系统无法使用桥接联网

    1.环境 VMware 14.1.1 虚拟系统:Windows Server 2008 32位 2.解决办法 打开虚拟网络编辑器 有红框中的提示出现时,就点击更改设置 点击桥接模式,在VMnet信息中 ...

  5. linux环境快速编译安装python3.6

    一.下载python3源码包 cd /tmp/wget https://www.python.org/ftp/python/3.6.2/Python-3.6.2.tgz 二.下载python3编译的依 ...

  6. Django 路由层(urlconf)

    Django 的路由层(URLconf) URL配置(conf)就像是Django所支撑的网站的目录; 本质就是:URL与调用该URL执行的视图函数的映射表; 通俗的讲:就是用户使用哪个url,URL ...

  7. Redis学习笔记(3)——Redis的命令大全

    Redis是一种nosql数据库,常被称作数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted se ...

  8. 高性能队列——Disruptor

    背景 Disruptor是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内存队列的延迟问题(在性能测试中发现竟然与I/O操作处于同样的数量级).基于Disruptor开发的系统单线程能 ...

  9. R语言学习——处理数据对象的实用函数

    length(object) # 显示对象中元素/成分的数量 dim(boject) # 显示某个对象的维度 str(object) # 显示某个对象的结构 class(object) # 显示某个对 ...

  10. R语言学习——向量

    以下为在RStudio中输入 #为注释符,其后内容程序不执行 > #向量是用于储存数值型.字符型或者逻辑型数据的一维数组.执行组合功能的函数c()可用来创建向量.示例如下: > a< ...