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 Fragment的用法(一)
1.碎片是什么 碎片(Fragment)是一种可以嵌入在活动当中的UI片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用的非常广泛.虽然碎片对你来说应该是个全新的概念,但我相信你学习起 ...
- linux下编译opencv
1.安装cmake:sudo apt-get install cmake 2.下载opencv-2.4.10.zip,解压 3.编译opencv cd /home/opencv-2.4.10 mkdi ...
- CTS问题分析6
遇到一个Android P相关的问题,和原来CTS/GTS 问题分析1的表现是一样的,但是将 这个修复cp过来,发现不生效,仍然报错,因此记录一下 问题初探 测试命令: run gts -m GtsG ...
- 【原】Java学习笔记007 - 流程控制
package cn.temptation; public class Sample01 { public static void main(String[] args) { // for循环 // ...
- 文件操作命令(move)
move命令: // 描述: 将一个或多个文件从一个目录移动到另一个目录. // 语法: move [{/y | /-y}] [<Source>] [<Target>] // ...
- MySql 学习之路-高级2
目录: 1.约束 2.ALTER TABLE 3.VIEW 1.约束 说明:SQL约束用于规定表中的数据规则,如果存在违反约束的数据行为,行为会被约束终止,约束可以在建表是规定,也可以在建表后规定,通 ...
- 全民抵制“辱华”品牌秀,D&G神回复:呵呵~ 那不是我!
### 补发一下,前写天写的: 就在今天下午,有网友爆出知名品牌 Dolce&Gabbana(杜嘉班纳)的设计师兼创始人Stefano Gabbana在ins上公然发表辱华言论. 下面截图 可 ...
- kernel笔记——VFS
vfs(the virtual filesystem, virtual file switch)为应用程序访问文件提供了统一的接口,如read.write.open等. 下面我们看加载文件系统模块.格 ...
- HashMap线程不安全的体现
前言:我们都知道HashMap是线程不安全的,在多线程环境中不建议使用,但是其线程不安全主要体现在什么地方呢,本文将对该问题进行解密. 1.jdk1.7中的HashMap 在jdk1.8中对HashM ...
- python学习之类的反射
在学习网络编程的时候用到反射,然后发现自己反射这部分的应用不是很熟练,决定返回来重新整理一下 对于类的反射,主要有四个用法,下面都说一下 1.hasattr 判断对象或者类是否存在指定的属性,看代码以 ...