当前位置: 首页 > 后端技术 > Java

Foxnic-SQL(十二)——DAO特性:记录和记录集

时间:2023-04-01 17:33:00 Java

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>groupedMap=rs.getGroupedMap("id","code");}排序、过滤、去重RcdSet也提供了排序、过滤、去重的几种方法,其中示例代码如下:/***排序、过滤、去重*/@Testpublicvoiddemo_misc(){//创建DAODAOdao=DBInstance.DEFAULT.dao();RcdSetrs=dao.queryPage("select*fromsys_dictwherecodelike?",50,1,"%o%");rs.parallelStream().forEach(r->{System.out.println(r.toJSONObject());});//通过指定字段去重rs.distinct("id");//按指定字段排序rs.sort("create_time",true,true);//搜索,精确匹配,返回第一个匹配记录Rcdr=rs.find("name","cabinetstatus");System.out.println(r==null?"notfound":r.toJSONObject());//过滤指定匹配算子RcdSetresult=rs.filter("id","36",FilterOperator.CONTAINS);for(Rcdrcd:result){System.out.println("filter"+rcd.toJSONObject());}//添加排名列rs.rank("rank","id",true);for(Rcdrcd:rs){System.out.println("rank-1:id="+rcd.getString("id")+",rank="+rcd.getInteger("rank"));}//填充排名值现有列rs.fillRankField("version","create_time",false);for(Rcdrcd:rs){System.out.println("rank-2:id="+rcd.getString("create_time")+",rank="+rcd.getInteger("version"));}}序列化RcdSet的序列化主要是将自身或Rcd转换成JSON对象Foxnic-SQL依赖FastJSON,示例代码如下:/***Serialization*/@Testpublicvoiddemo_serialization(){//创建DAODAOdao=DBInstance.DEFAULT.dao();RcdSetrs=dao.queryPage("select*fromsys_dictwherecodelike?",50,1,"%o%");//序列化记录集是JSONArray每个元素都是JSONObjectJSONArrayarray1=rs.toJSONArrayWithJSONObject();//序列化记录集为JSONArray每个元素为JSONArrayJSONArrayarray2=rs.toJSONArrayWithJSONArray();//将记录集序列化为JSONArray每个元素为JSONObject,指定哪些字段转为JSONObjectJSONArrayarray4=rs.toJSONArrayWithJSONObject("id","code","name");System.out.println(array4);//序列化记录for(Rcdr:rs){//将所有字段转换为JSONObjectobject1=r.toJSONObject();System.out.println(object1);//指定字段转换JSONObjectobject2=r.toJSONObject("id","code","name");System.out.println(object2);}//指定列名转换规则,DB_UPPER_CASE表示与数据库完全一致,整体增加编写rs.setDataNameFormat(DataNameFormat.DB_UPPER_CASE);System.out.println(rs.toJSONArrayWithJSONObject());}实体转换RcdSet除了JSON对象外,还可以转换为JavaPojo对象;当转换为Foxnic生成的实体对象时,会获得更高性能的示例代码如下:/***处理实体数据*/@Testpublicvoiddemo_entity(){//创建DAODAOdao=DBInstance.DEFAULT.dao();RcdSetrs=dao.queryPage("select*fromexample_address",50,1);//转换为实体列表List

addressList=rs.toEntityList(Address.class);System.out.println(JSON.toJSON(地址列表));//转为分页实体列表PagedList
addressPageList=rs.toPagedEntityList(Address.class);System.out.println(JSON.toJSON(addressPageList));//逐一遍历转换for(Rcdr:rs){Addressaddress=r.toEntity(Address.class);System.out.println(JSON.toJSON(地址));}}数据操作开发者可以通过RcdSet和Rcd完成数据持久化操作。Rcd为开发者提供了insert、update、save、delete等方法,可以直接操作库中的数据。示例代码如下:/***操作数据*/@Testpublicvoiddemo_crud(){//创建DAODAOdao=DBInstance.DEFAULT.dao();字符串id=IDGenerator.getSnowflakeIdString();Rcdr=dao.queryRecord("select*fromexample_addresswhereid=?",id);布尔成功=假;如果(r==null){r=dao.createRecord("example_address");河设置(“编号”,编号);r.set("名字","leefj");//为null则不连接SQL语句r.set("phone_number","13444252562");r.set("地址","宁波");r.set("region_type","国内");r.set("create_time",newDate());//设置数据库表达式r.setExpr("update_time","now()");//执行插入操作suc=r.insert();System.out.println("数据插入"+(suc?"成功":"失败"));}else{r.set("update_time",newDate());r.set("你pdate_by","leefj");//执行更新操作suc=r.update(SaveMode.DIRTY_FIELDS);System.out.println("Dataupdate"+(suc?"Success":"Failure"));}suc=r.delete();System.out.println("删除数据"+(suc?"Success":"Failure"));}小结本节主要介绍Foxnic-SQL中的记录集(RcdSet)和记录(Rcd),它们为开发者提供了很多功能,例如遍历和访问值、结构转换、过滤和排序、数据操作等。记录集(RcdSet)和记录(Rcd)在没有Po对象的场景下处理数据特别有用,以及它的动力学特别适用于许多高级场景。相关项目https://gitee.com/LeeFJ/foxnichttps://gitee.com/LeeFJ/foxnic-webhttps://gitee.com/lank/eamhttps://gitee.com/LeeFJ/foxnic-samples官方文档http://foxnicweb.com/docs/doc.html