Foxnic-SQL(十二)——DAO特性:记录和记录集概述默认情况下,JDBC从数据库中获取一个ResultSet(游标),但是打开游标消耗数据库连接,所以我们希望游标打开后立即关闭游标。Foxnic-SQL使用Rcd(记录)和RcdSet(记录集)来检索和存储游标遍历的数据。本节将详细介绍Rcd(记录)和RcdSet(记录集)的概念和用法。本文中的示例代码可以在https://gitee.com/LeeFJ/foxnic-samples项目中找到。数据结构一般来说,记录类似于一个Map结构,记录集就是由这些Map组成的列表。从内存的角度来看,这种存储结构并不是最优的,因为它不适合为每条记录存储列名。一组结构一致的记录,没有必要单独存储这些结构信息,而是统一存储。因此,Foxnic-SQL将元数据(结构数据)设计为独立的,元数据属于一个记录集,记录集中的记录结构是一致的,记录也属于记录集,不独立存在。下面的例子展示了记录、记录集和元数据之间的关系:道();//查询并获取第一条记录Rcdr=dao.queryRecord("select*fromsys_dictwherecodelike?","%o%");//输出记录数据System.out.println(r.toJSONObject());//获取当前记录所在的记录集RcdSetrs=r.getOwnerSet();//获取记录集的元数据QueryMetaDatameta=rs.getMetaData();//遍历元数据for(inti=0;i{System.out.println(r.toJSONObject());});//遍历方法-3:Lambdars.parallelStream().forEach(r->{System.out.println(r.toJSONObject());});}值类型和访问值特别值得一提的是,RcdSet在添加新的列名时只指定列名,而不指定列名列的类型。这是因为RcdSet中存储的数据实际上是动态的。DAO从数据库中取数据时,会根据从游标中取的值进行存储,Rcd类提供了多种方法来获取开发者想要的数据类型。rcd访问值可以使用数字下标或者列名,列名也有多种匹配方式。虽然Rcd支持多种命名方式,但还是建议先使用原始数据库字段名,再用驼峰命名。如下例所示:/***Valueandsettingvalue**/@Testpublicvoiddemo_Value(){//创建DAODAOdao=DBInstance.DEFAULT.dao();RcdSetrs=dao.queryPage("select*fromsys_dictwherecodelike?andcreate_timeisnotnull",50,1,"%o%");rs.parallelStream().forEach(r->{//获取Object类型的值,实际取值类型和从数据库中取出时的类型原始类型同ObjectidObj=r.getValue("id");//指定字符串类型StringidStr=r.getString("id");//指定Long类型,Rcd会尽可能的转换成Long类型,如果不能转换,则返回nullLongidLong=r。getLong("id");//指定Date类型,Rcd会尽可能将其转换为Date类型,如果无法转换则返回nullDateidDate=r.getDate("id");//获得更高的效率byserialnumberidObj=r.getValue(0);//按序号设置值,不检查类型r.set(0,"12345");//按列名设置值r.set("id","12345");//设置值,单个单词的列名不区分大小写idObj=r.getValue("id");idObj=r.getValue("ID");//Multi-word列名根据原数据库名匹配日期date1=r.getDate("create_time");//驼峰命名的多词列名匹配方法Datedate2=r.getDate("createTime");//匹配以大小写命名的多词列名MethodDatedate3=r.getDate("createtime");日期date4=r.getDate("CREATETIME");System.out.println();});}列控制通过DAO获取的记录集结构和查询语句相关,查询语句中有哪些列,那么哪些列就会在记录集中,但实际上开发者可能需要对这些列进行一些处理记录集,如添加新列、删除原有列等。/***列控件*/@Testpublicvoiddemo_Column(){//创建DAODAOdao=DBInstance.DEFAULT.dao();RcdSetrs=dao.queryPage("select*fromsys_dictwherecodelike?",50,1,"%o%");//输出列号System.out.println("查询后的大小"+rs.getFields().size());//添加列rs.addColumn("new_column");System.out.println("添加后的大小"+rs.getFields().size());for(Stringfield:rs.getFields()){System.out.println("a:"+field);}//更改列名rs.changeColumnLabel("new_column","new_column_1");for(Stringfield:rs.getFields()){System.out.println("b:"+field);}//通过列号和设置获取(Rcdr:rs){r.set("new_column_1",IDGenerator.getNanoId());}//Getnumberfor(Rcdr:rs){//使用原始列名获取数字Stringvalue1=r.getString("new_column_1");//使用驼峰式命名获取的对象value2=r.getValue("newColumn1");System.out.println("value1="+value1+";value2="+value2);assertTrue(value2.equals(value1));}}数据结构转换在某些场合,我们需要将记录集转换成某种目标结构,例如单列抽取Arrray、List或Set;或逐列提取为Map结构等。这些RcdSets可以很好地支持示例代码如下:/***数据结构转换*/@Testpublicvoiddemo_Structure(){//创建DAODAOdao=DBInstance.DEFAULT.dao();RcdSetrs=dao.queryPage("select*fromsys_dictwherecodelike?",50,1,"%o%");//将单列数据提取为数组String[]ids=rs.getValueArray("id",String.class);//提取单列数据为ListListdateList=rs.getValueList("createTime",Date.class);//提取单列数据为SetSetcodeSet=rs.getValueSet("code",Date.class);//提取指定列数据为MapMapmap=rs.getValueMap("id",String.class,"name",String.class);//将记录集转换为Map结构MaprcdMap=rs.getMappedRcds("id",String.class);//对记录集进行分组Map