将ResultSet转实体类
将ResultSet转实体类
sqlExecutor.executeQuery的执行结果的返回值是ResultSet:package java.sql;
一般在程序中我们需要把查询结果转为实体类返回给前端,此处可以使用的方法:
ResultSet转实体类方法1 2
1:resultSet.getXXX(columnIndex) 根据列的序号依次取值,并赋值给实体类的具体属性
定义一个实体类比如EntityDefine.class
public class EntityDefine implements Serializable {private static final long serialVersionUID = 3394089767543785764L;// 定义属性private String key;private Integer count;private Date updateTime;...;// get set 方法public String getKey(){return this.key;}public String setKey(String key) {this.key = key;}...;
}
定义一个处理ResultSet的方法handleResultSet
private EntityDefine handleResultSet(ResultSet resultSet) throws SQLException {EntityDefine entity = new EntityDefine();int col = 1;// 字符型entity.setKey(resultSet.getString(col++));// 整型entity.setCount(resultSet.getInt(col++));// 时间戳entity updateTime = resultSet.getTimestamp(col++);entity.setUpdateTime(updateTime);entity.setXXX(resultSet.getString(col++));return entity;
}
以上即可将ResultSet转为实体类。
优点是简单 ;
缺点是需要对ResultSet中的数据提前调试,确定每一列对应的属性(一般和数据库列的顺序一致)
2:实体类+注解+反射
注解是一种在Java中用来提供元数据的工具,它们可以在编译时和运行时为代码添加信息,并且可以被反射机制获取和处理。
(1)首先我们定义一个注解,用在实体类的所有属性上,都加上;
需要在注解中声明对应的数据库字段名;
属性对应的get方法可以编码时直接给出(如果属性值过多则配置会麻烦),或者用方法动态拼接(例子用这种方法);
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyResultSetFiled {/** 对应的数据库字段名 */String dbFiled();Class<?> fieldType() default String.class;/** 属性对应的get方法 */String get() default "";/** 是否需要自动补充当前时间 */boolean autoDate() default false;
}
关于注解:
注解按生命周期来划分可分为3类:
1、RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
2、RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;
3、RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;这3个生命周期分别对应于:Java源文件(.java文件) —> .class文件 —> 内存中的字节码。
那怎么来选择合适的注解生命周期呢?
首先要明确生命周期长度 SOURCE < CLASS < RUNTIME ,所以前者能作用的地方后者一定也能作用。
一般如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解;
如果要在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife),就用 CLASS注解;
如果只是做一些检查性的操作,比如 @Override 和 @SuppressWarnings,则可选用 SOURCE 注解。
@Target 指的是注解的作用目标。
@Target(ElementType.TYPE)——接口、类、枚举、注解
@Target(ElementType.FIELD)——字段、枚举的常量
@Target(ElementType.METHOD)——方法
@Target(ElementType.PARAMETER)——方法参数
@Target(ElementType.CONSTRUCTOR) ——构造函数
@Target(ElementType.LOCAL_VARIABLE)——局部变量
@Target(ElementType.ANNOTATION_TYPE)——注解
@Target(ElementType.PACKAGE)——包
(2)定义一个实体类比如EntityDefine.class
public class EntityDefine implements Serializable {private static final long serialVersionUID = 3394089767543785764L;// 定义属性,并添加注解@MyResultSetFiled(dbFiled = "key")private String key;@MyResultSetFiled(dbFiled = "count")private Integer count;@MyResultSetFiled(dbFiled = "update_time")private Date updateTime;...;// get set 方法public String getKey(){return this.key;}public String setKey(String key) {this.key = key;}...;
}
注意此处dbFiled要是数据库中的字段名,一般是采用下划线命名法,与实体类中定义属性的驼峰命名法有所区别。
可以将dbFiled后面跟的这些值封装成常量,便于维护。
(3)定义一个抽象类,在此方法中直接给类的各种属性封装好对应的值,所以建议做成构造函数的实现形式
public abstract class ResultSetWrapper implements Serializable{private static final long serialVersionUID = -2088813051606973972L;/*** 给给定的类的属性赋值,根据注解获取数据库的字段,从ResultSet中获取对应的值value* 动态拼接对应属性的Set方法* 利用反射,执行Set方法,将value赋值给对应的属性* 此方法没有返回值,给定的对象在该方法中执行一遍set后返回* @param resultSet 数据库查询结果集* @param clazz 要转化的实体类*/public void setData(ResultSet resultSet, Class<?> clazz) {try {// 获取类中所有定义的属性Field[] fields = clazz.getDeclaredFields();// 遍历for(Field field : fields) {// 获取属性上的注解信息MyResultSetFiled resultSetFiled = field.getAnnotation(AuditField.class);if(resultSetFiled==null) continue;// resultSet.getObject(列名),// 此方法可以配合我们获取注解中的数据库字段名使用,来获取对应的列的值Object value = resultSet.getObject(resultSetFiled.dbFiled());// 动态凭借对应属性的Set方法String fieldSetName = parSetName(field.getName());// 反射获取方法Method fieldSetMet = clazz.getMethod(fieldSetName, field.getType());if (null != value && !"".equals(value)) {String fieldType = value.getClass().getSimpleName();// 根据value的不同:String, Int, Data等,执行不同的set方法,即invoke(this, value)if ("String".equals(fieldType)) {fieldSetMet.invoke(this, value);} else if ("CLOB".equals(fieldType)) {// Clob转String,见第三部分《Clob转String》介绍String strClob = ClobToString((Clob) value);fieldSetMet.invoke(this, strClob);} else if ("Date".equals(fieldType) || "TIMESTAMP".equals(fieldType)) {Date temp = parseDate(value.toString());fieldSetMet.invoke(this, temp);} else if ("Integer".equals(fieldType)|| "int".equals(fieldType)) {Integer intval = Integer.parseInt(value.toString());fieldSetMet.invoke(this, intval);} else if ("Long".equalsIgnoreCase(fieldType)) {Long temp = Long.parseLong(value.toString());fieldSetMet.invoke(this, temp);} else if ("Double".equalsIgnoreCase(fieldType)) {Double temp = Double.parseDouble(value.toString());fieldSetMet.invoke(this, temp);} else if ("Boolean".equalsIgnoreCase(fieldType)) {Boolean temp = Boolean.parseBoolean(value.toString());fieldSetMet.invoke(this, temp);} else {System.out.println("not supper type" + fieldType);}}}}catch(NoSuchMethodException|SecurityException|IllegalAccessException|IllegalArgumentException|InvocationTargetException|SQLException e) {}}/*** 拼接在某属性的 set方法* @param fieldName 字段名* @return String setXXX*/private String parSetName(String fieldName) {if (null == fieldName || "".equals(fieldName)) {return null;}return "set" + fieldName.substring(0, 1).toUpperCase()+ fieldName.substring(1);}}
实体类EntityDefine.class完善,继承上述抽象类,并在构造方法中,声明:
public class EntityDefine extends ResultItem {...;public EntityDefine() {}// 构造方法public EntityDefine (ResultSet resultSet){super();this.setData(resultSet, EntityDefine.class);}...;}
(4)程序中处理:
new EntityDefine(resultSet);
即可获取到一个被完整赋值的对象实例;
优点:定义好了注解、构造函数之后,在使用时,直接new 即可,非常方便
缺点:配置复杂
Clob转String
在ResultSet转实体类中,存在Clob类型转换问题,需要转为String
/*** CLOB转String* @param clob clob* @return 字符串*/
public static String ClobToString(Clob clob) {String reString = "";try {// 得到流Reader is = clob.getCharacterStream();BufferedReader br = new BufferedReader(is);String s = br.readLine();StringBuilder sb = new StringBuilder();// 执行循环将字符串全部取出付值给StringBuilder,由StringBuilder转成STRINGwhile (s != null) {sb.append(s).append("\n");s = br.readLine();}reString = sb.toString();} catch (SQLException|IOException e) {e.printStackTrace();}return reString;
}
相关文章:
将ResultSet转实体类
将ResultSet转实体类 sqlExecutor.executeQuery的执行结果的返回值是ResultSet:package java.sql; 一般在程序中我们需要把查询结果转为实体类返回给前端,此处可以使用的方法: ResultSet转实体类方法1 2 1:resultSet.getXXX(columnIndex)…...
Web后端开发
一、Maven 1.1 简介 1.2 作用 1.3 流程 通过各种插件实现项目的标准化构建。 1.4 安装 1.5 配置环境 1.5.1 当前工程环境 1.5.2 全局环境 1.6 创建 Maven项目 1.7 导入项目 1.8 依赖管理 1.8.1 依赖配置 1.8.2 依赖传递 pom.xml——右键——Diagrams——show dependen…...
CAN201 计网概念收集
Lecture 1 the theoretical basis for networking Network edge and core 地理覆盖范围:广WAN,城MAN,局LAN,个PAN 交换方式,电路,报文,分组 电路交换vs报文vs分组 Network performance pr…...
【占用网络】FlashOcc:快速、易部署的占用预测模型
前言 FlashOcc是一个它只需2D卷积就能实现“占用预测模型”,具有快速、节约内存、易部署的特点。 它首先采用2D卷积提取图形信息,生成BEV特征。然后通过通道到高度变换,将BEV特征提升到3D空间特征。 对于常规的占用预测模型,将…...
239.【2023年华为OD机试真题(C卷)】求幸存者之和(模拟跳数-JavaPythonC++JS实现)
🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-求幸存数之和二.解题思路三.题解代码Python题解…...
Pytorch中的标准维度顺序
在PyTorch中,如果一个张量包括通道数(C)、宽度(W)、高度(H)和批量大小(N),那么它的标准维度顺序是 [N, C, H, W],即: 第一个维度 N 是…...
Nginx的安装配置和使用
最近有好几个地方用到了nginx,但是一直还没时间记录下nginx的安装、配置和使用,这篇文章可以将这块内容整理出来,方便大家一起学习~ 安装 安装是相对简单一些的,直接使用yum即可。 yum install -y nginx 默认安装位置在/usr/sb…...
P1643 完美数 题解
完美数 首先,介绍一下这篇题解的特邀嘉宾:ChatGPT4.0 传送门 题目描述 考古队员小星在一次考察中意外跌入深渊,穿越到了一个神秘的荒漠。这里有许多超越他认识的事物存在,例如许多漂浮在空中的建筑,例如各种奇怪的…...
docker一键安装
1.把docker_compose_install文件夹放在任意路径; 2.chmod -R 777 install.sh 3.执行./install.sh 兼容:CentOS7.6、麒麟V10服务器版、统信UOS等操作系统。 下载地址(本人上传,免积分下载):https://downlo…...
模板管理支持批量操作,DataEase开源数据可视化分析平台v2.2.0发布
2024年1月8日,DataEase开源数据可视化分析平台正式发布v2.2.0版本。 这一版本的功能升级包括:在“模板管理”页面中,用户可以通过模板管理的批量操作功能,对已有模板进行快速重新分类、删除等维护操作;数据大屏中&…...
阿里云实时计算企业级状态存储引擎 Gemini 技术解读
本文整理自阿里云 Flink 存储引擎团队李晋忠,兰兆千,梅源关于阿里云实时计算企业级状态存储引擎 Gemini 的研究,内容主要分为以下五部分: 流计算状态访问的痛点企业级状态存储引擎GeminiGemini 性能评测&线上表现结语参考 一、…...
web缓存之nginx缓存
一、nginx缓存知识 网络缓存位于客户端和 "源服务器 "之间,保存着所有可见内容的副本。当客户端请求缓存中存储的内容时,它可以直接从缓存中检索内容,而无需与服务器通信。这样,网络缓存就 "接近 "了客户端&a…...
【用法总结】无障碍AccessibilityService
一、背景 本文仅用于做学习总结,转换成自己的理解,方便需要时快速查阅,深入研究可以去官网了解更多:官网链接点这里 之前对接AI语音功能时,发现有些按钮(或文本)在我没有主动注册唤醒词场景…...
AI绘画风格化实战
在社交软件和短视频平台上,我们时常能看到各种特色鲜明的视觉效果,比如卡通化的图片和中国风的视频剪辑。这些有趣的风格化效果其实都是图像风格化技术的应用成果。 风格化效果举例 MidLibrary 这个网站提供了不同的图像风格,每一种都带有鲜…...
008定点小数、奇偶校验码
...
一、二进制方式 安装部署K8S
目录 一、操作系统初始化 1、关闭防火墙 2、关闭 SELinu 3、 关闭 swap 4、添加hosts 5、同步系统时间 二、集群搭建 —— 使用外部Etcd集群 1、自签证书 2、自签 Etcd SSL 证书 ① 创建 CA 配置文件:ca-config.json ② 创建 CA 证书签名请求文件ÿ…...
【simple-admin】FMS模块如何快速接入阿里云oss 腾讯云cos 服务 实现快速上传文件功能落地
让我们一起支持群主维护simple-admin 社群吧!!! 不能加入星球的朋友记得来点个Star!! https://github.com/suyuan32/simple-admin-core 一、前提准备 1、goctls版本 goctls官方git:https://github.com/suyuan32/goctls 确保 goctls是最新版本 v1.6.19 goctls -v goct…...
数据结构.线性表(2)
一、模板 例子: a: b: 二、基本操作的实现 (1)初始化 (2)销毁和清空 (3)求长度和判断是否为空 (4)取值 (5)查找 (6)插入 &…...
【计算机网络】TCP原理 | 可靠性机制分析(三)
个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【网络编程】【Java系列】 本专栏旨在分享学习网络编程、计算机网络的一点学习心得,欢迎大家在评论区交流讨论💌 目…...
【昕宝爸爸小模块】线程的几种状态,状态之间怎样流转
➡️博客首页 https://blog.csdn.net/Java_Yangxiaoyuan 欢迎优秀的你👍点赞、🗂️收藏、加❤️关注哦。 本文章CSDN首发,欢迎转载,要注明出处哦! 先感谢优秀的你能认真的看完本文&…...
Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
CSS 工具对比:UnoCSS vs Tailwind CSS,谁是你的菜?
在现代前端开发中,Utility-First (功能优先) CSS 框架已经成为主流。其中,Tailwind CSS 无疑是市场的领导者和标杆。然而,一个名为 UnoCSS 的新星正以其惊人的性能和极致的灵活性迅速崛起。 这篇文章将深入探讨这两款工具的核心理念、技术差…...
python打卡day49@浙大疏锦行
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 一、通道注意力模块复习 & CBAM实现 import torch import torch.nn as nnclass CBAM(nn.Module):def __init__…...
Copilot for Xcode (iOS的 AI辅助编程)
Copilot for Xcode 简介Copilot下载与安装 体验环境要求下载最新的安装包安装登录系统权限设置 AI辅助编程生成注释代码补全简单需求代码生成辅助编程行间代码生成注释联想 代码生成 总结 简介 尝试使用了Copilot,它能根据上下文补全代码,快速生成常用…...
