Java中,将ResultSet映射为对象和队列及其他辅助函数
关于对象关系映射(ORM)在数据库访问中用到的最多,在Java中,很多库都试图将一个ResultSet映射为一个自定义的Java Bean对象或队列,下面是我的实现
1 从ResultSet中读取数据
首先是,如何能正确的从ResultSet中读取到自己想要的数据,包括已知列序号和已知列名的情况.
已知列序号,读取ResultSet中的数据值:
public static <T> T ReadValue(Class<T> t, ResultSet set, int columnIndex) throws SQLException;
已知列名,读取 ResultSet中的数据值:
public static <T> T ReadValue(Class<T> t, ResultSet set, Map<String, Integer> columns, String field)
columns中存储这列索引与列名的对应关系,如果该参数为空,则自己创建这样一个队列.
下面是实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | /** * 取得ResultSet中的值 * @param t * @param set * @param columnIndex * @return * @throws SQLException */ @SuppressWarnings ( "unchecked" ) public static <T> T ReadValue(Class<T> t, ResultSet set, int columnIndex) throws SQLException { if (t == null || set == null ) { return null ; } if (t == Object. class ) { return (T)set.getObject(columnIndex); } if (t == Integer. class ) { Object val = set.getInt(columnIndex); return (T)val; } if (t == short . class ) { Object val = set.getShort(columnIndex); return (T)val; } if (t == Boolean. class ) { Object val = set.getBoolean(columnIndex); return (T)val; } if (t == long . class ) { Object val = set.getLong(columnIndex); return (T)val; } if (t == float . class ) { Object val = set.getFloat(columnIndex); return (T)val; } if (t == double . class ) { Object val = set.getDouble(columnIndex); return (T)val; } if (t == String. class ) { Object val = set.getString(columnIndex); return (T)val; } if (t == java.sql.Date. class ) { Object val = set.getDate(columnIndex); return (T)val; } if (t == java.sql.Time. class ) { Object val = set.getTime(columnIndex); return (T)val; } if (t == java.sql.Timestamp. class ) { Object val = set.getTimestamp(columnIndex); return (T)val; } if (t == Byte. class ) { Object val = set.getByte(columnIndex); return (T)val; } return (T)set.getObject(columnIndex); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /** * 取得ResultSet中的值 * @param t * @param set * @param columns * @param field * @return * @throws SQLException */ public static <T> T ReadValue(Class<T> t, ResultSet set, Map<String, Integer> columns, String field) throws SQLException { if (columns == null ) { columns = GetFieldIndex(set); } if (columns == null ) { return null ; } if (!columns.containsKey(field)) { return null ; } int index = columns.get(field); return ReadValue(t, set, index); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /** * 取得列名对应的列索引 * @param set * @return * @throws SQLException */ public static Map<String, Integer> GetFieldIndex(ResultSet set) throws SQLException { if (set == null ) { return null ; } ResultSetMetaData meta = set.getMetaData(); if (meta == null ) { return null ; } Map<String, Integer> map = new HashMap<String, Integer>(); int count = meta.getColumnCount(); for ( int i = 0 ; i < count; i++) { map.put(meta.getColumnName(i), i); } return map; } |
其实GetFieldIndex还是可以扩展的,例如包含数据的类型,暂时不需要,也没有进行扩展.
2 数据到对象的映射
下面是数据到对象的映射
接口:
1 2 3 4 5 6 7 8 9 10 | /** * 根据ResultSet装载对象 * @param cls * @param t * @param set * @param columns * @return * @throws SQLException */ public static <T> boolean FillObject(Class<T> cls, T t, ResultSet set, Map<String, Integer> columns) throws SQLException |
实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /** * 根据ResultSet装载对象 * @param cls * @param t * @param set * @param columns * @return * @throws SQLException */ public static <T> boolean FillObject(Class<T> cls, T t, ResultSet set, Map<String, Integer> columns) throws SQLException { if (cls == null || t == null || set == null ) { return false ; } if (columns == null ) { columns = GetFieldIndex(set); } final Map<String, Integer> cols = columns; return HiCBO.FillObjectEx(t, cls, new IEventRet8Param<Object, String>(){ @Override public final Object OnEvent(String v) { try { return ReadValue(Object. class , set, cols, v); } catch (Exception ex) { ex.printStackTrace(); return null ; } } }); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /** * 创建并装载对象数据 * @param cls * @param set * @return */ public static <T> T CreateObject(Class<T> cls, ResultSet set, Map<String, Integer> columns) { try { T t = cls.newInstance(); FillObject(cls, t, set, columns); return t; } catch (Exception ex) { ex.printStackTrace(); return null ; } } |
注: CreateObject中,如果T没有默认构造函数,则会存在问题,编译时期不会进行错误提示,这一点需要注意.
取得队列:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | /** * 取得Set的列表 * @param cls * @param set * @return * @throws SQLException */ public static <T> List<T> GetResultsList(Class<T> cls, ResultSet set) throws SQLException { if (cls == null || set == null ) { return null ; } Map<String, Integer> columns = GetFieldIndex(set); if (columns == null ) { return null ; } if (!set.first()) { return null ; } List<T> list = new ArrayList<T>(); T t = GetFirst(cls, set, columns); if (t != null ) { list.add(t); } while (set.next()) { T it = CreateObject(cls, set); if (it != null ) { list.add(it); } } return list; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?