首页 文章 精选 留言 我的

精选列表

搜索[轻量版],共10000篇文章
优秀的个人博客,低调大师

Ant Design Vue 2.0 正式版发布

Vue 3、TS重构、虚拟Select、暗黑主题、使用 Composition API 重构全新文档、TS / JS 双示例 来不及多说了,快上车 https://2x.antdv.com/components/overview-cn/ Ant Design of Vue 是 Ant Design 的 Vue 实现,开发和服务于企业级后台产品。 特性 提炼自企业级中后台产品的交互语言和视觉风格。 开箱即用的高质量 Vue 组件。 共享Ant Design of React设计工具体系。 支持环境 现代浏览器和 IE11 及以上, 如果需要支持 IE9,可以选择使用1.x 版本。 支持服务端渲染。 Electron

优秀的个人博客,低调大师

sqltoy-orm 4.13.12 发版,ORM 框架

开源地址: github:https://github.com/chenrenfei/sagacity-sqltoy gitee:https://gitee.com/sagacity/sagacity-sqltoy idea 插件(可直接在idea中检索安装): https://github.com/threefish/sqltoy-idea-plugins 更新内容 1、大幅改进EntityQuery和QueryExecutor,为其增加缓存翻译、filters、分页优化、日期数字格式化、安全脱敏等,为中等规模sql代码中编写提供了便利。 @Test public void findEntityByVO() { List<StaffInfoVO> staffVOs = sqlToyLazyDao.findEntity(StaffInfoVO.class, EntityQuery.create().where("#[staffId=:staffId]#[and staffName like :staffName] #[ and status=:status]") .values(new StaffInfoVO().setStatus(-1).setStaffName("陈").setStaffId("S0005")) .filters(new ParamsFilter("status").eq(-1)).filters(new ParamsFilter("staffName").rlike()) .filters(new ParamsFilter("staffId").primary()).secureMask(MaskType.ADDRESS, "address") .secureMask(MaskType.TEL, "telNo")); System.err.println(JSON.toJSONString(staffVOs)); } 2、改进isUnique的实现策略,减少一次count查询提升了效率! 3、修复update级联操作时,在mysql、postgresql、sqlite等场景下改用2次交互模式解决上述数据库自身bug导致的问题(非空字段问题)! 参见sqltoy4.2.6 版本反馈的bug mysql的on duplicate key update 当某个字段在数据库中设置为not null,发生SQL 错误 [1048] [23000]: Column 'NAME' cannot be null 快速了解 sqltoy-orm: sqltoy是全新一代的ORM框架,兼顾jpa对象式操作的优势,同时极大增强了查询功能,辅以科学的sql编写模式、巧妙的缓存翻译集成、极致的分页优化以及针对大规模数据下的分库分表、超复杂场景下的mongodb、elastic、clickhouse组合应用! sqltoy给你带来了多种主键策略,除常规的UUID、sequence、identity外,还包含雪花算法和基于redis产生有规则的业务主键等。 sqltoy还提供了针对统计分析的:数据旋转、无限级分组计算、同比环比等来减少开发者写复杂sql。 sqltoy在很多方面提供了极为实用的方法,如:树形表处理、isUnique、findTop、getRandomResult、updateFetch等等 sqltoy不走jooq全对象式、mybatis全sql式这种不是天就是地从来没有考虑过后期需求变更和运维苦逼的极端路子,紧贴项目实战发展起来的框架,让各自技术以合理的方式应用于合理的地方! 简要举例介绍(详情请参见sqltoy下面的sqltoy-quickstart演示项目): JPA式的CRUD,但规避了其不足,提供了默认的SqlToyCRUDService(简单的则无需写service方法) 和 SqlToyLazyDao(开发无需自己写Dao,只需要写Service业务逻辑),可以了解类似于update、updateAll、saveOrUpdate等内在逻辑,减少了数据库交互,考虑了高并发和业务对象变更的特征! @Autowired private SqlToyCRUDService sqlToyCRUDService; //基于对象保存 sqlToyCRUDService.save(staffInfo); //基于对象更新(字段值为null的不会参与变更) sqlToyCRUDService.update(staffInfo); //深度变更,全部字段都参与变更 sqlToyCRUDService.updateDeeply(staffInfo); //基于对象更新(制定强制修改的字段) sqlToyCRUDService.update(staffInfo,"staffName","onDuty"); //基于对象更新 sqlToyCRUDService.saveOrUpdate(staffInfo); //加载对象 sqlToyCRUDService.load(new StaffInfoVO("S190715009")); //加锁获取对象 sqlToyCRUDService.load(new StaffInfoVO("S190715009"),LockMode.UPGRADE); //判断对象是否唯一 sqlToyCRUDService.isUnique(staffInfo, "staffCode"); //delete\deleteAll\updateAll\loadAll 等等不一一写完 sqltoy提供了最简洁的动态sql编写 我们对比一下mybatis的实现! 不要顾首不顾腚式看问题: 产品改需求增加条件增加显示列,后期人员变动! 从需求调整和后期维护的角度,你自己分析mybatis这种做调整是不是很麻烦(先放入客户端调试、调试完再整理成mybatis的格式) 缓存翻译,利用缓存减少关联查询,简化sql同时大幅提升效率 极致分页优化 旋转数据并进行环比计算

优秀的个人博客,低调大师

PyTorch版CenterNet训练自己的数据集

CenterNet(Objects as points)已经有一段时间了,之前这篇文章-【目标检测Anchor-Free】CVPR 2019 Object as Points(CenterNet)中讲解了CenterNet的原理,可以回顾一下。 这篇文章是基于非官方的CenterNet实现,https://github.com/zzzxxxttt/pytorch_simple_CenterNet_45,这个版本的实现更加简单,基于官方版本(https://github.com/xingyizhou/CenterNet)进行修改,要比官方代码更适合阅读和理解,dataloader、hourglass、训练流程等原版中比较复杂的部分都进行了重写,最终要比官方的速度更快。 这篇博文主要讲解如何用这个版本的CenterNet训练自己的VOC数据集,环境的配置。 1. 环境配置 2. 配置自己的数据集 2.1 VOC类别修改 2.2 annotations 2.3 其他 3. 训练和测试 3.1 训练命令 3.2 测试命令 4. 结果 COCO: PascalVOC: 5. 参考 1. 环境配置 环境要求: python>=3.5 pytorch==0.4.1or 1.1.0 or 1.0.0(笔者用的1.0.0也可以) tensorboardX(可选) 配置: 将cudnn的batch norm关闭。打开torch/nn/functional.py文件,找到torch.batch_norm这一行,将 torch.backends.cudnn.enabled选项更改为False。 克隆项目 CenterNet_ROOT=/path/to/clone/CenterNetgitclonehttps://github.com/zzzxxxttt/pytorch_simple_CenterNet_45$CenterNet_ROOT 安装cocoAPI cd$CenterNet_ROOT/lib/cocoapi/PythonAPImakepythonsetup.pyinstall--user 编译可变形卷积DCN 如果使用的是pytorch0.4.1, 将 $CenterNet_ROOT/lib/DCNv2_old重命名为 $CenterNet_ROOT/lib/DCNv2 如果使用的是pytorch1.1.0 or 1.0.0, 将 $CenterNet_ROOT/lib/DCNv2_new重命名为 $CenterNet_ROOT/lib/DCNv2. 然后开始编译 cd$CenterNet_ROOT/lib/DCNv2./make.sh 编译NMS cd$CenterNet_ROOT/lib/nmsmake 对于COCO格式的数据集,下载链接在:http://cocodataset.org/#download。将annotations, train2017, val2017, test2017放在$CenterNet_ROOT/data/coco 对于Pascal VOC格式的数据集,下载VOC转为COCO以后的数据集: 网盘链接:https://pan.baidu.com/share/init?surl=z6BtsKPHh2MnbfT25Y4wYw 密码:4iu2 下载以后将annotations, images, VOCdevkit放在$CenterNet_ROOT/data/voc PS:以上两者是官方数据集,如果制作自己的数据集的话可以往下看。 如果选择Hourglass-104作为骨干网络,下载CornerNet提供的Hourglass预训练模型: 网盘链接:https://pan.baidu.com/s/1tp9-5CAGwsX3VUSdV276Fg 密码:y1z4 将下载的权重checkpoint.t7放到$CenterNet_ROOT/ckpt/pretrain中。 2. 配置自己的数据集 这个版本提供的代码是针对官方COCO或者官方VOC数据集进行配置的,所以有一些细节需要修改。 由于笔者习惯VOC格式数据集,所以以Pascal VOC格式为例,修改自己的数据集。 笔者只有一个类,‘dim target’,所以按照一个类来修改,其他的类别也很容易修改。 2.1 VOC类别修改 将datasets/pascal.py中16行内容: VOC_NAMES=['__background__',"aeroplane","bicycle","bird","boat","bottle","bus","car","cat","chair","cow","diningtable","dog","horse","motorbike","person","pottedplant","sheep","sofa","train","tvmonitor"] 修改为自己类别的名称: VOC_NAMES=['__background__','dimtarget'] 将datasets/pascal.py中第33行内容: num_classes=20修改为自己对应的类别个数num_classes=1 将datasets/pascal.py中的第35行内容: self.valid_ids = np.arange(1, 21, dtype=np.int32)中的21修改为类别数目+1 2.2 annotations VOC格式数据集中没有annotations中所需要的json文件,这部分需要重新构建。 下面是一个VOC转COCO格式的脚本,需要改xml path和json file的名称。 importxml.etree.ElementTreeasETimportosimportjsoncoco=dict()coco['images']=[]coco['type']='instances'coco['annotations']=[]coco['categories']=[]category_set=dict()image_set=set()category_item_id=0image_id=20200000000annotation_id=0defaddCatItem(name):globalcategory_item_idcategory_item=dict()category_item['supercategory']='none'category_item_id+=1category_item['id']=category_item_idcategory_item['name']=namecoco['categories'].append(category_item)category_set[name]=category_item_idreturncategory_item_iddefaddImgItem(file_name,size):globalimage_idiffile_nameisNone:raiseException('Couldnotfindfilenametaginxmlfile.')ifsize['width']isNone:raiseException('Couldnotfindwidthtaginxmlfile.')ifsize['height']isNone:raiseException('Couldnotfindheighttaginxmlfile.')image_id+=1image_item=dict()image_item['id']=image_idimage_item['file_name']=file_nameimage_item['width']=size['width']image_item['height']=size['height']coco['images'].append(image_item)image_set.add(file_name)returnimage_iddefaddAnnoItem(object_name,image_id,category_id,bbox):globalannotation_idannotation_item=dict()annotation_item['segmentation']=[]seg=[]#bbox[]isx,y,w,h#left_topseg.append(bbox[0])seg.append(bbox[1])#left_bottomseg.append(bbox[0])seg.append(bbox[1]+bbox[3])#right_bottomseg.append(bbox[0]+bbox[2])seg.append(bbox[1]+bbox[3])#right_topseg.append(bbox[0]+bbox[2])seg.append(bbox[1])annotation_item['segmentation'].append(seg)annotation_item['area']=bbox[2]*bbox[3]annotation_item['iscrowd']=0annotation_item['ignore']=0annotation_item['image_id']=image_idannotation_item['bbox']=bboxannotation_item['category_id']=category_idannotation_id+=1annotation_item['id']=annotation_idcoco['annotations'].append(annotation_item)defparseXmlFiles(xml_path):forfinos.listdir(xml_path):ifnotf.endswith('.xml'):continuereal_file_name=f.split(".")[0]+".jpg"bndbox=dict()size=dict()current_image_id=Nonecurrent_category_id=Nonefile_name=Nonesize['width']=Nonesize['height']=Nonesize['depth']=Nonexml_file=os.path.join(xml_path,f)print(xml_file)tree=ET.parse(xml_file)root=tree.getroot()ifroot.tag!='annotation':raiseException('pascalvocxmlrootelementshouldbeannotation,ratherthan{}'.format(root.tag))#elemis<folder>,<filename>,<size>,<object>foreleminroot:current_parent=elem.tagcurrent_sub=Noneobject_name=Noneifelem.tag=='folder':continueifelem.tag=='filename':file_name=real_file_name#elem.textiffile_nameincategory_set:raiseException('file_nameduplicated')#addimgitemonlyafterparse<size>tagelifcurrent_image_idisNoneandfile_nameisnotNoneandsize['width']isnotNone:#print(file_name,"===",image_set)iffile_namenotinimage_set:current_image_id=addImgItem(file_name,size)print('addimagewith{}and{}'.format(file_name,size))else:pass#raiseException('duplicatedimage:{}'.format(file_name))#subelemis<width>,<height>,<depth>,<name>,<bndbox>forsubeleminelem:bndbox['xmin']=Nonebndbox['xmax']=Nonebndbox['ymin']=Nonebndbox['ymax']=Nonecurrent_sub=subelem.tagifcurrent_parent=='object'andsubelem.tag=='name':object_name=subelem.textifobject_namenotincategory_set:current_category_id=addCatItem(object_name)else:current_category_id=category_set[object_name]elifcurrent_parent=='size':ifsize[subelem.tag]isnotNone:raiseException('xmlstructurebrokenatsizetag.')size[subelem.tag]=int(subelem.text)#optionis<xmin>,<ymin>,<xmax>,<ymax>,whensubelemis<bndbox>foroptioninsubelem:ifcurrent_sub=='bndbox':ifbndbox[option.tag]isnotNone:raiseException('xmlstructurecorruptedatbndboxtag.')bndbox[option.tag]=int(option.text)#onlyafterparsethe<object>tagifbndbox['xmin']isnotNone:ifobject_nameisNone:raiseException('xmlstructurebrokenatbndboxtag')ifcurrent_image_idisNone:raiseException('xmlstructurebrokenatbndboxtag')ifcurrent_category_idisNone:raiseException('xmlstructurebrokenatbndboxtag')bbox=[]#xbbox.append(bndbox['xmin'])#ybbox.append(bndbox['ymin'])#wbbox.append(bndbox['xmax']-bndbox['xmin'])#hbbox.append(bndbox['ymax']-bndbox['ymin'])print('addannotationwith{},{},{},{}'.format(object_name,current_image_id,current_category_id,bbox))addAnnoItem(object_name,current_image_id,current_category_id,bbox)if__name__=='__main__':xml_path='./annotations/test'json_file='./pascal_test2020.json'#'./pascal_trainval0712.json'parseXmlFiles(xml_path)json.dump(coco,open(json_file,'w')) 注意这里json文件的命名要通过datasets/pascal.py中第44到48行的内容确定的。 self.data_dir=os.path.join(data_dir,'voc')self.img_dir=os.path.join(self.data_dir,'images')_ann_name={'train':'trainval0712','val':'test2007'}self.annot_path=os.path.join(self.data_dir,'annotations','pascal_%s.json'%_ann_name[split]) 这里笔者为了方便命名对这些字段进行了修改: self.data_dir=os.path.join(data_dir,'voc')#./data/vocself.img_dir=os.path.join(self.data_dir,'images')#./data/voc/images_ann_name={'train':'train2020','val':'test2020'}#意思是需要json格式数据集self.annot_path=os.path.join(self.data_dir,'annotations','pascal_%s.json'%_ann_name[split]) 所以要求json的命名可以按照以下格式准备: # ./data/voc/annotations# - pascal_train2020# - pascal_test2020 数据集总体格式为: -data-voc-annotations-pascal_train2020.json-pascal_test2020.json-images-*.jpg-VOCdevkit(这个文件夹主要是用于测评)-VOC2007-Annotations-*.xml-JPEGImages-*.jpg-ImageSets-Main-train.txt-val.txt-trainval.txt-test.txt 2.3 其他 在datasets/pascal.py中21-22行,标准差和方差最好替换为自己的数据集的标准差和方差。 VOC_MEAN=[0.485,0.456,0.406]VOC_STD=[0.229,0.224,0.225] 3. 训练和测试 3.1 训练命令 训练命令比较多,可以写一个shell脚本来完成。 pythontrain.py--log_namepascal_resdcn18_384_dp\--datasetpascal\--archresdcn_18\--img_size384\--lr1.25e-4\--lr_step45,60\--batch_size32\--num_epochs70\--num_workers10 log name代表记录的日志的名称。 dataset设置pascal代表使用的是pascal voc格式。 arch代表选择的backbone的类型,有以下几种: large_hourglass small_hourglass resdcn_18 resdcn_34 resdcn_50 resdcn_101 resdcn_152 img size控制图片长和宽。 lr和lr_step控制学习率大小及变化。 batch size是一个批次处理的图片个数。 num epochs代表学习数据集的总次数。 num workers代表开启多少个线程加载数据集。 3.2 测试命令 测试命令很简单,需要注意的是img size要和训练的时候设置的一致。 pythontest.py--log_namepascal_resdcn18_384_dp\--datasetpascal\--archresdcn_18\--img_size384 flip test属于TTA(Test Time Augmentation),可以一定程度上提高mAP。 #fliptestpythontest.py--log_namepascal_resdcn18_384_dp\--datasetpascal\--archresdcn_18\--img_size384\--test_flip 4. 结果 以下是作者在COCO和VOC数据集上以不同的图片分辨率和TTA方法得到的结果。 COCO: Model Training image size mAP Hourglass-104 (DP) 512 39.9/42.3/45.0 Hourglass-104 (DDP) 512 40.5/42.6/45.3 PascalVOC: Model Training image size mAP ResDCN-18 (DDP) 384 71.19/72.99 ResDCN-18 (DDP) 512 72.76/75.69 笔者在自己的数据集上进行了训练,训练log如下: 每隔5个epoch将进行一次eval,在自己的数据集上最终可以得到90%左右的mAP。 笔者将已经改好的单类的CenterNet放在Github上:https://github.com/pprp/SimpleCVReproduction/tree/master/Simple_CenterNet 5. 参考 https://github.com/pprp/SimpleCVReproduction/tree/master/Simple_CenterNet https://github.com/zzzxxxttt/pytorch_simple_CenterNet_45 欢迎关注GiantPandaCV公众号,对文章有问题或者想加群交流的朋友也可以添加笔者微信。 为了方便读者获取资源,公众号也成立了QQ群,欢迎加群获取资料或者分享资源,二维码在下方。 本文分享自微信公众号 - GiantPandaCV(BBuf233)。如有侵权,请联系 support@oschina.cn 删除。本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

优秀的个人博客,低调大师

极致性能 sqltoy-orm-4.13.1 发版

开源地址: github:https://github.com/chenrenfei/sagacity-sqltoy gitee:https://gitee.com/sagacity/sagacity-sqltoy idea 插件(可直接在idea中检索安装): https://github.com/threefish/sqltoy-idea-plugins 更新内容 1、增强外部如报表平台通过xml集成sqltoy的处理兼容性,尤其xml的命名空间前缀名称的处理 如下面的报表中关于数据提取的部分引入了sqltoy的schema和命名空间为s: <sql id="rpt_datasql1"> <s:sharding-datasource strategy="skylineStrategy" /> <s:translate cache="staffIdName" columns="CREATE_BY" uncached-template=""/> <s:filters> <s:eq params="*" value="-1"/> </s:filters> <s:value> <![CDATA[ ]]> </s:value> </sql> 2、增强quickvo增加nvarchar、money等类型默认处理 3、优化loadAll 查询,按每批次1000分批执行加载,规避sql in 参数不能超过1000的问题 快速了解 sqltoy-orm: sqltoy是全新一代的ORM框架,兼顾jpa对象式操作的优势,同时极大增强了查询功能,辅以科学的sql编写模式、巧妙的缓存翻译集成、极致的分页优化以及针对大规模数据下的分库分表、超复杂场景下的mongodb、elastic、clickhouse组合应用! sqltoy给你带来了多种主键策略,除常规的UUID、sequence、identity外,还包含雪花算法和基于redis产生有规则的业务主键等。 sqltoy还提供了针对统计分析的:数据旋转、无限级分组计算、同比环比等来减少开发者写复杂sql。 sqltoy在很多方面提供了极为实用的方法,如:树形表处理、isUnique、findTop、getRandomResult、updateFetch等等 sqltoy不走jooq全对象式、mybatis全sql式这种不是天就是地的极端路子,紧贴项目实战发展起来的框架,让各自技术以合理的方式应用于合理的地方! 简要举例介绍(因篇幅问题部分举例): JPA式的CRUD,但规避了其不足,提供了默认的SqlToyCRUDService(简单的则无需写service方法) 和 SqlToyLazyDao(开发无需自己写Dao,只需要写Service业务逻辑),可以了解类似于update、updateAll、saveOrUpdate等内在逻辑,减少了数据库交互,考虑了高并发和业务对象变更的特征! @Autowired private SqlToyCRUDService sqlToyCRUDService; //基于对象保存 sqlToyCRUDService.save(staffInfo); //基于对象更新(字段值为null的不会参与变更) sqlToyCRUDService.update(staffInfo); //深度变更,全部字段都参与变更 sqlToyCRUDService.updateDeeply(staffInfo); //基于对象更新(制定强制修改的字段) sqlToyCRUDService.update(staffInfo,new String[]{"staffName","onDuty"}); //基于对象更新 sqlToyCRUDService.saveOrUpdate(staffInfo); //加载对象 sqlToyCRUDService.load(new StaffInfoVO("S190715009")); //加锁获取对象 sqlToyCRUDService.load(new StaffInfoVO("S190715009"),LockMode.UPGRADE); //判断对象是否唯一 sqlToyCRUDService.isUnique(staffInfo, "staffCode"); //delete\deleteAll\updateAll\loadAll 等等不一一写完 单表等简单的查询和变更操作,提供了链式操作 //单表对象查询,直接传参模式 List<StaffInfoVO> staffVOs = sqlToyLazyDao.findEntity(StaffInfoVO.class, EntityQuery.create().where("#[staffName like ?] #[ and status=?]").values("陈", 1).lock(LockMode.UPGRADE) .orderBy("staffName").orderByDesc("createTime")); //单表查询,对象传参模式 List<StaffInfoVO> staffVOs = sqlToyLazyDao.findEntity(StaffInfoVO.class, EntityQuery.create().where("#[staffName like :staffName] #[ and status=:status]") .values(new StaffInfoVO().setStatus(1).setEmail("test3@aliyun.com"))); //代码中链式查询并删除 Long deleteCount = sqlToyLazyDao.deleteByQuery(StaffInfoVO.class, EntityQuery.create().where("status=:status").values(new StaffInfoVO().setStatus(1))); //链式变更 Long updateCount = sqlToyLazyDao.updateByQuery(StaffInfoVO.class, EntityUpdate.create().set("staffName", "张三").where("staffName like ? and status=?").values("陈", 1)); 更强大的查询,sqltoy强调复杂查询建议放置于xml中跟代码分离,为什么是xml?因为xml具有强格式校验和输入提示,更重要的是可以扩展更多有趣的功能! //sqltoy统一的规则就是直接传递sql语句或者对应的sqlId,并不是说sql只能写在xml中(推荐但不绝对) findBySql(final String sqlOrSqlId, final String[] paramsNamed, final Object[] paramsValue, final Class<T> voClass) //嫌弃上面的格式化传参也可以使用这样链式查询 sqlToyLazyDao.findByQuery(new QueryExecutor("sqltoy_order_search").names("orderId", "authedOrganIds") .values(null, authedOrgans).resultType(DeviceOrderInfoVO.class)); sqltoy提供了最简洁的动态sql编写 我们对比一下mybatis的实现(这种写法是很多人反对xml的原因吧!): 缓存翻译,利用缓存减少关联查询,简化sql同时大幅提升效率 极致分页优化 旋转数据并进行环比计算

优秀的个人博客,低调大师

极致性能 sqltoy-orm-4.12.14 发版

开源地址: github:https://github.com/chenrenfei/sagacity-sqltoy gitee:https://gitee.com/sagacity/sagacity-sqltoy idea 插件(可直接在idea中检索安装): https://github.com/threefish/sqltoy-idea-plugins 更新内容 1、增强sqltoy提供的工具类的兼容性,兼容外部调用时的各种场景情况 快速了解 sqltoy-orm: sqltoy是全新一代的ORM框架,兼顾jpa对象式操作的优势,同时极大增强了查询功能,辅以科学的sql编写模式、巧妙的缓存翻译集成、极致的分页优化以及针对大规模数据下的分库分表、超复杂场景下的mongodb、elastic、clickhouse组合应用! sqltoy给你带来了多种主键策略,除常规的UUID、sequence、identity外,还包含雪花算法和基于redis产生有规则的业务主键等。 sqltoy还提供了针对统计分析的:数据旋转、无限级分组计算、同比环比等来减少开发者写复杂sql。 sqltoy在很多方面提供了极为实用的方法,如:树形表处理、isUnique、findTop、getRandomResult、updateFetch等等 sqltoy不走jooq全对象式、mybatis全sql式这种不是天就是地的极端路子,紧贴项目实战发展起来的框架,让各自技术以合理的方式应用于合理的地方! 简要举例介绍(因篇幅问题部分举例): JPA式的CRUD,但规避了其不足,提供了默认的SqlToyCRUDService(简单的则无需写service方法) 和 SqlToyLazyDao(开发无需自己写Dao,只需要写Service业务逻辑),可以了解类似于update、updateAll、saveOrUpdate等内在逻辑,减少了数据库交互,考虑了高并发和业务对象变更的特征! @Autowired private SqlToyCRUDService sqlToyCRUDService; //基于对象保存 sqlToyCRUDService.save(staffInfo); //基于对象更新(字段值为null的不会参与变更) sqlToyCRUDService.update(staffInfo); //深度变更,全部字段都参与变更 sqlToyCRUDService.updateDeeply(staffInfo); //基于对象更新(制定强制修改的字段) sqlToyCRUDService.update(staffInfo,new String[]{"staffName","onDuty"}); //基于对象更新 sqlToyCRUDService.saveOrUpdate(staffInfo); //加载对象 sqlToyCRUDService.load(new StaffInfoVO("S190715009")); //加锁获取对象 sqlToyCRUDService.load(new StaffInfoVO("S190715009"),LockMode.UPGRADE); //判断对象是否唯一 sqlToyCRUDService.isUnique(staffInfo, "staffCode"); //delete\deleteAll\updateAll\loadAll 等等不一一写完 单表等简单的查询和变更操作,提供了链式操作 //单表对象查询,直接传参模式 List<StaffInfoVO> staffVOs = sqlToyLazyDao.findEntity(StaffInfoVO.class, EntityQuery.create().where("#[staffName like ?] #[ and status=?]").values("陈", 1).lock(LockMode.UPGRADE) .orderBy("staffName").orderByDesc("createTime")); //单表查询,对象传参模式 List<StaffInfoVO> staffVOs = sqlToyLazyDao.findEntity(StaffInfoVO.class, EntityQuery.create().where("#[staffName like :staffName] #[ and status=:status]") .values(new StaffInfoVO().setStatus(1).setEmail("test3@aliyun.com"))); //代码中链式查询并删除 Long deleteCount = sqlToyLazyDao.deleteByQuery(StaffInfoVO.class, EntityQuery.create().where("status=:status").values(new StaffInfoVO().setStatus(1))); //链式变更 Long updateCount = sqlToyLazyDao.updateByQuery(StaffInfoVO.class, EntityUpdate.create().set("staffName", "张三").where("staffName like ? and status=?").values("陈", 1)); 更强大的查询,sqltoy强调复杂查询建议放置于xml中跟代码分离(但是可以写在代码中的),不要见xml就反,请深入了解之后再反! //sqltoy统一的规则就是直接传递sql语句或者对应的sqlId,并不是说sql只能写在xml中(推荐但不绝对) findBySql(final String sqlOrSqlId, final String[] paramsNamed, final Object[] paramsValue, final Class<T> voClass) //嫌弃上面的格式化传参也可以使用这样链式查询 sqlToyLazyDao.findByQuery(new QueryExecutor("sqltoy_order_search").names("orderId", "authedOrganIds") .values(null, authedOrgans).resultType(DeviceOrderInfoVO.class)); sqltoy提供了最简洁的动态sql编写 我们对比一下mybatis的实现(很简单的sql写的如此让人不愿意写!): 缓存翻译,利用缓存减少关联查询,简化sql同时大幅提升效率 极致分页优化 旋转数据并进行环比计算

优秀的个人博客,低调大师

极致性能 sqltoy-orm-4.12.12 发版

开源地址: github:https://github.com/chenrenfei/sagacity-sqltoy gitee:https://gitee.com/sagacity/sagacity-sqltoy idea 插件(可直接在idea中检索安装): https://github.com/threefish/sqltoy-idea-plugins 更新内容 1、增强sql输出,将条件参数带入到sql中便于开发和调试 2、完善schema,给用户更多提升。 快速了解 sqltoy-orm: sqltoy是全新一代的ORM框架,兼顾jpa对象式操作的优势,同时极大增强了查询功能,辅以科学的sql编写模式、巧妙的缓存翻译集成、极致的分页优化以及针对大规模数据下的分库分表、超复杂场景下的mongodb、elastic、clickhouse组合应用! sqltoy给你带来了多种主键策略,除常规的UUID、sequence、identity外,还包含雪花算法和基于redis产生有规则的业务主键等。 sqltoy还提供了针对统计分析的:数据旋转、无限级分组计算、同比环比等来减少开发者写复杂sql。 sqltoy在很多方面提供了极为实用的方法,如:树形表处理、isUnique、findTop、getRandomResult、updateFetch等等 sqltoy不走jooq全对象式、mybatis全sql式不是天就是地的极端路子,让各自技术以合理的方式应用于合理的地方! 简要举例介绍(因篇幅问题部分举例): JPA式的CRUD,但规避了其不足,提供了默认的SqlToyCRUDService(简单的则无需写service方法) 和 SqlToyLazyDao(开发无需自己写Dao,只需要写Service业务逻辑),可以了解类似于update、updateAll、saveOrUpdate等内在逻辑,减少了数据库交互,考虑了高并发和业务对象变更的特征! @Autowired private SqlToyCRUDService sqlToyCRUDService; //基于对象保存 sqlToyCRUDService.save(staffInfo); //基于对象更新(字段值为null的不会参与变更) sqlToyCRUDService.update(staffInfo); //深度变更,全部字段都参与变更 sqlToyCRUDService.updateDeeply(staffInfo); //基于对象更新(制定强制修改的字段) sqlToyCRUDService.update(staffInfo,new String[]{"staffName","onDuty"}); //基于对象更新 sqlToyCRUDService.saveOrUpdate(staffInfo); //加载对象 sqlToyCRUDService.load(new StaffInfoVO("S190715009")); //加锁获取对象 sqlToyCRUDService.load(new StaffInfoVO("S190715009"),LockMode.UPGRADE); //判断对象是否唯一 sqlToyCRUDService.isUnique(staffInfo, "staffCode"); //delete\deleteAll\updateAll\loadAll 等等不一一写完 单表等简单的查询和变更操作,提供了链式操作 //单表对象查询,直接传参模式 List<StaffInfoVO> staffVOs = sqlToyLazyDao.findEntity(StaffInfoVO.class, EntityQuery.create().where("#[staffName like ?] #[ and status=?]").values("陈", 1).lock(LockMode.UPGRADE) .orderBy("staffName").orderByDesc("createTime")); //单表查询,对象传参模式 List<StaffInfoVO> staffVOs = sqlToyLazyDao.findEntity(StaffInfoVO.class, EntityQuery.create().where("#[staffName like :staffName] #[ and status=:status]") .values(new StaffInfoVO().setStatus(1).setEmail("test3@aliyun.com"))); //代码中链式查询并删除 Long deleteCount = sqlToyLazyDao.deleteByQuery(StaffInfoVO.class, EntityQuery.create().where("status=:status").values(new StaffInfoVO().setStatus(1))); //链式变更 Long updateCount = sqlToyLazyDao.updateByQuery(StaffInfoVO.class, EntityUpdate.create().set("staffName", "张三").where("staffName like ? and status=?").values("陈", 1)); 更强大的查询,sqltoy强调复杂查询建议放置于xml中跟代码分离,不要见xml就反,反而忽视了xml的schema提示、格式校验和可扩展性! //sqltoy统一的规则就是直接传递sql语句或者对应的sqlId,并不是说sql只能写在xml中(推荐但不绝对) findBySql(final String sqlOrSqlId, final String[] paramsNamed, final Object[] paramsValue, final Class<T> voClass) //嫌弃上面的格式化传参也可以使用这样链式查询 sqlToyLazyDao.findByQuery(new QueryExecutor("sqltoy_order_search").names("orderId", "authedOrganIds") .values(null, authedOrgans).resultType(DeviceOrderInfoVO.class)); sqltoy提供了最简洁的动态sql编写 我们对比一下mybatis的实现(很简单的sql写的如此让人不愿意写!): 缓存翻译,利用缓存减少关联查询,简化sql同时大幅提升效率 极致分页优化 旋转数据并进行环比计算

优秀的个人博客,低调大师

极致性能 sqltoy-orm-4.12.10 发版

新内容 支持postgresql10+之后增加的 identity 主键策略 修复postgresql bytea类型转换错误 优化quickvo增加postgresql类型默认匹配 开源地址: github:https://github.com/chenrenfei/sagacity-sqltoy gitee:https://gitee.com/sagacity/sagacity-sqltoy idea 插件(可在market直接检索sqltoy安装): https://gitee.com/threefish/sqltoy-idea-plugins sqltoy特点说明: 支持mysql、postgresql、db2、oracle、sqlserver、sqlite、clickhouse、elasticsearch、mongodb等 具有JPA模式的CRUD功能(即CRUD无需写sql),无需写Dao,sqltoy提供了SqlToyLazyDao,同时提供了quickvo从数据库生成POJO。 根本上杜绝了sql注入问题 最科学的sql编写方式 * sqltoy的sql编写(支持嵌套) select * from sqltoy_device_order_info t where #[t.ORDER_ID=:orderId] #[and t.ORGAN_ID in (:authedOrganIds)] #[and t.STAFF_ID in (:staffIds)] #[and t.TRANS_DATE>=:beginDate] #[and t.TRANS_DATE<:endDate] * mybatis同样功能实现 select * from sqltoy_device_order_info t <where> <if test="orderId!=null"> and t.ORDER_ID=#{orderId} </if> <if test="authedOrganIds!=null"> and t.ORGAN_ID in <foreach collection="authedOrganIds" item="order_id" separator="," open="(" close=")"> #{order_id} </foreach> </if> <if test="staffIds!=null"> and t.STAFF_ID in <foreach collection="staffIds" item="staff_id" separator="," open="(" close=")"> #{staff_id} </foreach> </if> <if test="beginDate!=null"> and t.TRANS_DATE>=#{beginDate} </if> <if test="endDate!=null"> and t.TRANS_DATE<#{endDate} </if> </where> 缓存翻译大幅提升性能,减少多表关联,让sql直观可维护 最高等级的分页优化 支持用算法代替sql实现行列转换、同比环比、分组汇总等 支持分库分表 sqltoy支持跨数据库函数自适应:一套sql可以自适应多种数据库 提供了5种默认的非数据库相关的主键策略 1、shortNanoTime 22位有序安全ID,格式: 13位当前毫秒+6位纳秒+3位主机ID 2、nanoTimeId 26位有序安全ID,格式:15位:yyMMddHHmmssSSS+6位纳秒+2位(线程Id+随机数)+3位主机ID 3、uuid:32 位uuid 4、SnowflakeId 雪花算法ID 5、redisId 基于redis 来产生规则的ID主键 提供了通用字段赋值处理 提供了树形表的统一处理机制 sql文件更新自动重载,便于开发阶段无需重启应用 慢sql统计功能 便于跟其他拓展平台集成,如报表平台、配置化服务平台 ```java public class SqlToyContext implements ApplicationContextAware { // 省略其他代码 /** * @todo 提供可以动态增加解析sql片段配置的接口,并返回具体id,用于第三方平台集成,如报表平台等 * @param sqlSegment * @return * @throws Exception */ public synchronized SqlToyConfig parseSqlSegment(Object sqlSegment) throws Exception { return scriptLoader.parseSqlSagment(sqlSegment); } } ``` 开源地址: github:https://github.com/chenrenfei/sagacity-sqltoy gitee:https://gitee.com/sagacity/sagacity-sqltoy idea 插件(可在market直接检索sqltoy安装): https://gitee.com/threefish/sqltoy-idea-plugins 更新内容 1、升级spring、elasticsearch、mongo依赖包的版本 2、优化对mongodb查询支持、改为直接通过mongoTemplate集成(原先是通过mongoDbFactory模式), 完善范例 参考范例: https://github.com/chenrenfei/sqltoy-showcase/tree/master/trunk/sqltoy-nosql 见test下面MongoTest.java sqltoy特点说明: 支持mysql、postgresql、db2、oracle、sqlserver、sqlite、clickhouse、elasticsearch、mongodb等 具有JPA模式的CRUD功能(即CRUD无需写sql),无需写Dao,sqltoy提供了SqlToyLazyDao,同时提供了quickvo从数据库生成POJO。 根本上杜绝了sql注入问题 最科学的sql编写方式 * sqltoy的sql编写(支持嵌套) select * from sqltoy_device_order_info t where #[t.ORDER_ID=:orderId] #[and t.ORGAN_ID in (:authedOrganIds)] #[and t.STAFF_ID in (:staffIds)] #[and t.TRANS_DATE>=:beginDate] #[and t.TRANS_DATE<:endDate] * mybatis同样功能实现 select * from sqltoy_device_order_info t <where> <if test="orderId!=null"> and t.ORDER_ID=#{orderId} </if> <if test="authedOrganIds!=null"> and t.ORGAN_ID in <foreach collection="authedOrganIds" item="order_id" separator="," open="(" close=")"> #{order_id} </foreach> </if> <if test="staffIds!=null"> and t.STAFF_ID in <foreach collection="staffIds" item="staff_id" separator="," open="(" close=")"> #{staff_id} </foreach> </if> <if test="beginDate!=null"> and t.TRANS_DATE>=#{beginDate} </if> <if test="endDate!=null"> and t.TRANS_DATE<#{endDate} </if> </where> 缓存翻译大幅提升性能,减少多表关联,让sql直观可维护 最高等级的分页优化 支持用算法代替sql实现行列转换、同比环比、分组汇总等 支持分库分表 sqltoy支持跨数据库函数自适应:一套sql可以自适应多种数据库 提供了5种默认的非数据库相关的主键策略 1、shortNanoTime 22位有序安全ID,格式: 13位当前毫秒+6位纳秒+3位主机ID 2、nanoTimeId 26位有序安全ID,格式:15位:yyMMddHHmmssSSS+6位纳秒+2位(线程Id+随机数)+3位主机ID 3、uuid:32 位uuid 4、SnowflakeId 雪花算法ID 5、redisId 基于redis 来产生规则的ID主键 提供了通用字段赋值处理 提供了树形表的统一处理机制 sql文件更新自动重载,便于开发阶段无需重启应用 慢sql统计功能 便于跟其他拓展平台集成,如报表平台、配置化服务平台 ```java public class SqlToyContext implements ApplicationContextAware { // 省略其他代码 /** * @todo 提供可以动态增加解析sql片段配置的接口,并返回具体id,用于第三方平台集成,如报表平台等 * @param sqlSegment * @return * @throws Exception */ public synchronized SqlToyConfig parseSqlSegment(Object sqlSegment) throws Exception { return scriptLoader.parseSqlSagment(sqlSegment); } } ```

优秀的个人博客,低调大师

ORM 框架 sqltoy-orm 4.12.2 发版

开源地址: github:https://github.com/chenrenfei/sagacity-sqltoy gitee:https://gitee.com/sagacity/sagacity-sqltoy 感谢热心朋友开发了idea 针对sqltoy的插件,快速定位sql https://gitee.com/threefish/sqltoy-idea-plugins 更新内容 1、增强直接写sql查询时自动根据情况补齐select c1,c2,.. from table where 2、优化quickvo,剔除对log4j的依赖改用jdk自带log,大幅减小jar的大小 3、增加三个单表查询、修改、删除方法,更加简化单表操作,便于内部逻辑快捷处理 /** * findEntity 模式,简化sql编写模式,面向接口服务层提供快捷数据查询和处理 * 1、通过where指定条件 * 2、支持lock * 3、支持order by (order by 在接口服务 层意义不大) * 4、自动将对象属性映射成表字段 */ @Test public void findEntity() { //条件利用sqltoy特有的#[]充当动态条件判断,#[]是支持嵌套的 List<StaffInfoVO> staffVOs = sqlToyLazyDao.findEntity(StaffInfoVO.class, EntityQuery.create().where("#[staffName like ?] #[ and status=?]") .lock(LockMode.UPGRADE).orderBy("staffName").orderByDesc("createTime") .values("陈", 1)); System.err.println(JSON.toJSONString(staffVOs)); } /** * 指定where 条件并提供对象传参 */ @Test public void findEntityByVO() { List<StaffInfoVO> staffVOs = sqlToyLazyDao.findEntity(StaffInfoVO.class, EntityQuery.create().where("#[staffName like :staffName] #[ and status=:status]") .values(new StaffInfoVO().setStatus(1).setEmail("test3@aliyun.com"))); System.err.println(JSON.toJSONString(staffVOs)); } /** * 通过参数传值进行删除,where必须有值(后端会校验),delete操作属于危险操作 */ @Test public void deleteEntity() { Long deleteCount = sqlToyLazyDao.deleteByQuery(StaffInfoVO.class, EntityQuery.create().where("status=:status").values(new StaffInfoVO().setStatus(1))); System.err.println(deleteCount); } /** * update 操作where也必须有值,以防危险操作 */ @Test public void updateEntity() { Long updateCount = sqlToyLazyDao.updateByQuery(StaffInfoVO.class, EntityUpdate.create().set("staffName", "张三").where("staffName like ? and status=?").values("陈", 1)); System.err.println(updateCount); } sqltoy特点说明: 支持mysql、postgresql、db2、oracle、sqlserver、sqlite、clickhouse、elasticsearch等 具有JPA模式的CRUD功能(即CRUD无需写sql),无需写Dao,sqltoy提供了SqlToyLazyDao,同时提供了quickvo从数据库生成POJO。 根本上杜绝了sql注入问题 最科学的sql编写方式 * sqltoy的sql编写(支持嵌套) select * from sqltoy_device_order_info t where #[t.ORDER_ID=:orderId] #[and t.ORGAN_ID in (:authedOrganIds)] #[and t.STAFF_ID in (:staffIds)] #[and t.TRANS_DATE>=:beginDate] #[and t.TRANS_DATE<:endDate] * mybatis同样功能实现 select * from sqltoy_device_order_info t <where> <if test="orderId!=null"> and t.ORDER_ID=#{orderId} </if> <if test="authedOrganIds!=null"> and t.ORGAN_ID in <foreach collection="authedOrganIds" item="order_id" separator="," open="(" close=")"> #{order_id} </foreach> </if> <if test="staffIds!=null"> and t.STAFF_ID in <foreach collection="staffIds" item="staff_id" separator="," open="(" close=")"> #{staff_id} </foreach> </if> <if test="beginDate!=null"> and t.TRANS_DATE>=#{beginDate} </if> <if test="endDate!=null"> and t.TRANS_DATE<#{endDate} </if> </where> 缓存翻译大幅提升性能,减少多表关联,让sql直观可维护 最高等级的分页优化 支持用算法代替sql实现行列转换、同比环比、分组汇总等 支持分库分表 sqltoy支持跨数据库函数自适应:一套sql可以自适应多种数据库 提供了5种默认的非数据库相关的主键策略 1、shortNanoTime 22位有序安全ID,格式: 13位当前毫秒+6位纳秒+3位主机ID 2、nanoTimeId 26位有序安全ID,格式:15位:yyMMddHHmmssSSS+6位纳秒+2位(线程Id+随机数)+3位主机ID 3、uuid:32 位uuid 4、SnowflakeId 雪花算法ID 5、redisId 基于redis 来产生规则的ID主键 提供了通用字段赋值处理 提供了树形表的统一处理机制 sql文件更新自动重载,便于开发阶段无需重启应用 慢sql统计功能

资源下载

更多资源
Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册