java jdbc ResultSet结果通过java反射赋值给java对象
在不整合框架的情况下,使用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对象的更多相关文章
- [原创] Java JDBC连接数据库,反射创建实体类对象并赋值数据库行记录(支持存储过程)
1.SqlHelper.java import java.lang.reflect.*; import java.sql.*; import java.util.*; public class Sql ...
- JAVA基础知识之JDBC——ResultSet的滚动和更新(statement的额外参数)
ResultSet不仅可以内存中的一张二维表一样保存statement执行SQL的结果集,还能通过结果集修改DB的数据.ResultSetMetaData则可以用来获得ResultSet对象的相关信息 ...
- java jdbc 封装。。
JDBC工具类...package it.cast.jdbcutils; import java.io.InputStream; import java.sql.Connection; import ...
- Java JDBC下执行SQL的不同方式、参数化预编译防御
相关学习资料 http://zh.wikipedia.org/wiki/Java数据库连接 http://lavasoft.blog.51cto.com/62575/20588 http://blog ...
- java jdbc 连接mysql 数据库
JDBC连接MySQL 加载及注册JDBC驱动程序 Class.forName("com.mysql.jdbc.Driver"); Class.forName("com. ...
- java JDBC (一)
package cn.sasa.demo1; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Re ...
- java JDBC链接sqlserver/mysql/oracle
今天初学数据库的一些简单创建数据库和表,并进行简单的查询,插入. 接下学习的就是java工程中怎么链接数据库呢.主要的方法和用到的类如下. 切记,mysql需要的jar包 mysql-connecto ...
- JAVA JDBC(存储过程和事务管理)
1.什么是存储过程 存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程 ...
- java jdbc与odbc数据库的连接mysql数据库
1.jdbc连接数据库要添加mysql-connector-java-5.1.38-bin.jar库 2.odbc连接数据库要添加odbc数据源 3.测试代码 DBHelper.java代码jdbc连 ...
随机推荐
- Android Picasso最详细的使用指南
Picasso 是Square 公司开源的Android 端的图片加载和缓存框架.Square 真是一家良心公司啊,为我们Android开发者贡献了很多优秀的开源项目有木有!像什么Rerefoit . ...
- Word Count作业
Word Count作业 一.个人Gitee地址:https://gitee.com/Changyu-Guo 二.项目简介 该项目主要是模拟Linux上面的wc命令,基本要求如下: 命令格式: wc. ...
- Delphi中打开网页连接的几种方法
https://blog.csdn.net/zisongjia/article/details/69398143 正好要用,做个记录.Mark下. 使用了第一种 uses shellapi proce ...
- 用 Weave Scope 监控集群 - 每天5分钟玩转 Docker 容器技术(175)
创建 Kubernetes 集群并部署容器化应用只是第一步.一旦集群运行起来,我们需要确保一起正常,所有必要组件就位并各司其职,有足够的资源满足应用的需求.Kubernetes 是一个复杂系统,运维团 ...
- mysql安装出现问题(The service already exists)
1.管理员身份运行cmd(系统win10) 2.输入命令cd /d F:\mysql-5.7.19-win32\bin(此为mysql要安装的目录) 3.输入安装命令mysqld install 出现 ...
- Saltstack_使用指南05_数据系统-Pillar
1. 主机规划 Pillar文档 https://docs.saltstack.com/en/latest/topics/pillar/index.html 注意事项 修改了master或者minio ...
- 设置TextBlock默认样式后,其他控件的Text相关属性设置失效问题
问题: 定义了默认TextBlock样式后,再次自定义下拉框 or 其他控件 ,当内部含有TextBlock时,设置控件的字体相关样式无效,系统始终使用TextBlock设置默认样式 解决方案: 为相 ...
- Python排序算法——冒泡排序
有趣的事,Python永远不会缺席! 如需转发,请注明出处:小婷儿的python https://www.cnblogs.com/xxtalhr/p/10786904.html 一.冒泡排序(Bubb ...
- python小白——进阶之路——day3天-———运算符
(1)算数运算符: + - * / // % ** (2)比较运算符: > < >= <= == != (3)赋值运算符: = += -= *= /= //= %= ** ...
- mac 利用svn下载远程代码出现Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo.
终端输出的信息:Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo. ...