游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

基于java语言,打造比mybatis更实用的orm框架开源

  1。前言1。1sqltoyorm是什么
  sqltoyorm是比hibernatemyBatis(plus)更加贴合项目的orm框架(依赖spring),具有jpa式的对象CRUD的同时具有比myBatis(plus)更直观简洁性能强大的查询功能。支持以下数据库:oracle11gdb29。5,建议从10。5开始mysql(mariadbinnosql)支持5。6、5。7、8。0版本postgresql(greenplum)支持9。5以及以上版本sqlserver2012sqliteDM达梦数据库elasticsearch只支持查询,版本支持5。7版本,建议使用7。3以上版本clickhousedorisdboceanBaseguassdbtidbkingbasemongodb(只支持查询)sybaseiq支持15。4以上版本,建议使用16版本1。2jdk版本要求1。82。快速特点说明2。1对象操作跟jpa类似并有针对性加强(包括级联)无需写任何sql,通过quickvo工具从数据库生成对应的POJOStaffInfoVOstaffInfonewStaffInfoVO();保存sqlToyLazyDao。save(staffInfo);删除sqlToyLazyDao。delete(newStaffInfoVO(S2007));publicLongupdate(Serializableentity,String。。。forceUpdateProps);这里对photo属性进行强制修改,其他为null自动会跳过sqlToyLazyDao。update(staffInfo,photo);深度修改,不管是否null全部字段修改sqlToyLazyDao。updateDeeply(staffInfo);ListStaffInfoVOstaffListnewArrayListStaffInfoVO();StaffInfoVOstaffInfonewStaffInfoVO();StaffInfoVOstaffInfo1newStaffInfoVO();staffList。add(staffInfo);staffList。add(staffInfo1);批量保存或修改sqlToyLazyDao。saveOrUpdateAll(staffList);批量保存sqlToyLazyDao。saveAll(staffList);。。。。。。。。。。。。。。。sqlToyLazyDao。loadByIds(StaffInfoVO。class,S2007)唯一性验证sqlToyLazyDao。isUnique(staffInfo,staffCode);2。2支持代码中对象查询sqltoy中统一的规则是代码中可以直接传sql也可以是对应xml文件中的sqlIdtodo通过对象传参数,简化paramName〔〕,paramValue〔〕模式传参paramTparamsqlOrNamedSql可以是具体sql也可以是对应xml中的sqlIdparamentity通过对象传参数,并按对象类型返回结果publicTextendsSerializableListTfindBySql(finalStringsqlOrNamedSql,finalTentity);基于对象单表查询,并带缓存翻译publicPaginationModelStaffInfoVOfindStaff(PaginationModelStaffInfoVOpageModel,StaffInfoVOstaffInfoVO){sql可以直接在代码中编写,复杂sql建议在xml中定义单表entity查询场景下sql字段可以写成java类的属性名称returnfindEntity(StaffInfoVO。class,pageModel,EntityQuery。create()。where(〔staffNamelike:staffName〕〔andcreateTime:beginDate〕〔andcreateTime:endDate〕)。values(staffInfoVO)字典缓存必须要设置cacheType单表对象查询需设置keyColumn构成selectkeyColumnascolumn模式。translates(newTranslate(dictKeyName)。setColumn(sexTypeName)。setCacheType(SEXTYPE)。setKeyColumn(sexType))。translates(newTranslate(organIdName)。setColumn(organName)。setKeyColumn(organId)));}对象式查询后修改或删除演示代码中非直接sql模式设置条件模式进行记录修改publicLongupdateByQuery(){returnsqlToyLazyDao。updateByQuery(StaffInfoVO。class,EntityUpdate。create()。set(createBy,S0001)。where(staffNamelike?)。values(张));}代码中非直接sql模式设置条件模式进行记录删除sqlToyLazyDao。deleteByQuery(StaffInfoVO。class,EntityQuery。create()。where(status?)。values(0));2。3极致朴素的sql编写方式sqltoy的写法(一眼就看明白sql的本意,后面变更调整也非常便捷,copy到数据库客户端里稍做出来即可执行)sqltoy条件组织原理很简单:如〔orderid:orderId〕等于if(:orderIdnull)sql。append(orderid:orderId);〔〕内只要有一个参数为null即剔除支持多层嵌套:如〔andt。orderid:orderId〔andt。ordertype:orderType〕〕条件判断保留〔if(:paramxx:paramxx1)sql语句〕这种if()高度灵活模式,为特殊复杂场景下提供便利1、条件值处理跟具体sql分离2、将条件值前置通过filters定义的通用方法加工规整(大多数是不需要额外处理的)sqlidshowcasefilters!参数statusAry只要包含1(代表全部)则将statusAry设置为null不参与条件检索eqparamsstatusAryvalue1filtersvalue!〔CDATA〔selectfromsqltoydeviceorderinfotwhere〔t。statusin(:statusAry)〕〔andt。ORDERID:orderId〕〔andt。ORGANIDin(:authedOrganIds)〕〔andt。STAFFIDin(:staffIds)〕〔andt。TRANSDATE:beginDate〕〔andt。TRANSDATE:endDate〕〕〕valuesql2。4天然防止sql注入,执行过程:假设sql语句如下selectfromsqltoydeviceorderinfotwhere〔t。ORGANIDin(:authedOrganIds)〕〔andt。TRANSDATE:beginDate〕〔andt。TRANSDATE:endDate〕java调用过程sqlToyLazyDao。findBySql(sql,newString〔〕{authedOrganIds,beginDate,endDate},newObject〔〕{authedOrganIdAry,beginDate,null},DeviceOrderInfoVO。class);最终执行的sql是这样的:selectfromsqltoydeviceorderinfotwheret。ORDERID?andt。ORGANIDin(?,?,?)andt。TRANSDATE?然后通过:pst。set(index,value)设置条件值2。5最为极致的分页2。5。1分页特点说明1、快速分页:fast()实现先取单页数据然后再关联查询,极大提升速度。2、分页优化器:pageoptimize让分页查询由两次变成1。31。5次(用缓存实现相同查询条件的总记录数量在一定周期内无需重复查询)3、sqltoy的分页取总记录的过程不是简单的selectcount(1)from(原始sql);而是智能判断是否变成:selectcount(1)fromfrom后语句,并自动剔除最外层的orderby4、sqltoy支持并行查询:paralleltrue,同时查询总记录数和单页数据,大幅提升性能5、在极特殊情况下sqltoy分页考虑是最优化的,如:witht1as(),t2asfast(selectfromtable1)selectfromxxx这种复杂查询的分页的处理,sqltoy的count查询会是:witht1as()selectcount(1)fromtable1,如果是:witht1asfast(selectfromtable1)selectfromt1,countsql就是:selectcount(1)fromtable12。5。2分页sql示例!快速分页和分页优化演示sqlidsqltoyfastPage!分页优化器,通过缓存实现查询条件一致的情况下在一定时间周期内缓存总记录数量,从而无需每次查询总记录数量!parallel:是否并行查询总记录数和单页数据,当alivemax1时关闭缓存优化!alivemax:最大存放多少个不同查询条件的总记录量;aliveseconds:查询条件记录量存活时长(比如120秒,超过阀值则重新查询)pageoptimizeparalleltruealivemax100aliveseconds120value!〔CDATA〔selectt1。,t2。ORGANNAMEfast()实现先分页取10条(具体数量由pageSize确定),然后再关联fromfast(selectt。fromsqltoystaffinfotwheret。STATUS1〔andt。STAFFNAMElike:staffName〕orderbyt。ENTRYDATEdesc)t1leftjoinsqltoyorganinfot2ont1。organidt2。ORGANID〕〕value!这里为极特殊情况下提供了自定义countsql来实现极致性能优化!countsqlcountsqlsql2。5。3分页java代码调用基于对象传参数模式publicvoidfindPageByEntity(){PaginationModelpageModelnewPaginationModel();StaffInfoVOstaffVOnewStaffInfoVO();作为查询条件传参数staffVO。setStaffName(陈);使用了分页优化器第一次调用:执行count和取记录两次查询第二次调用:在特定时效范围内count将从缓存获取,只会执行取单页记录查询PaginationModelresultsqlToyLazyDao。findPageBySql(pageModel,sqltoyfastPage,staffVO);}2。6极为巧妙的缓存翻译,将多表关联查询尽量变成单表1、通过缓存翻译:将代码转化为名称,避免关联查询,极大简化sql并提升查询效率2、通过缓存名称模糊匹配:获取精准的编码作为条件,避免关联like模糊查询sqlidsqltoyordersearch!缓存翻译设备类型cache:具体的缓存定义的名称,cachetype:一般针对数据字典,提供一个分类条件过滤columns:sql中的查询字段名称,可以逗号分隔对多个字段进行翻译cacheindexs:缓存数据名称对应的列,不填则默认为第二列(从0开始,1则表示第二列),例如缓存的数据结构是:key、name、fullName,则第三列表示全称translatecachedictKeyNamecachetypeDEVICETYPEcolumnsdeviceTypeNamecacheindexs1!员工名称翻译,如果同一个缓存则可以同时对几个字段进行翻译translatecachestaffIdNamecolumnsstaffName,createNamefilters!反向利用缓存通过名称匹配出id用于精确查询cacheargcachenamestaffIdNameCacheparamstaffNamealiasnamestaffIdsfiltersvalue!〔CDATA〔selectORDERID,DEVICETYPE,DEVICETYPEdeviceTypeName,设备分类名称STAFFID,STAFFIDstaffName,员工姓名ORGANID,CREATEBY,CREATEBYcreateName创建人名称fromsqltoydeviceorderinfotwhere〔t。ORDERID:orderId〕〔andt。STAFFIDin(:staffIds)〕〕〕valuesql2。7并行查询接口规范parallQuery面向查询(不要用于事务操作过程中),sqltoy提供强大的方法,但是否恰当使用需要使用者做合理的判断TODO并行查询并返回一维List,有几个查询List中就包含几个结果对象,paramNames和paramValues是全部sql的条件参数的合集paramparallQueryListparamparamNamesparamparamValuespublicTListQueryResultTparallQuery(ListParallQueryparallQueryList,String〔〕paramNames,Object〔〕paramValues);使用范例定义参数String〔〕paramNamesnewString〔〕{userId,defaultRoles,deployId,authObjType};Object〔〕paramValuesnewObject〔〕{userId,defaultRoles,GlobalConstants。DEPLOYID,SagacityConstants。TempAuthObjType。GROUP};使用并行查询同时执行2个sql,条件参数是2个查询的合集ListQueryResultTreeModellistsuper。parallQuery(Arrays。asList(ParallQuery。create()。sql(webframesearchAllModuleMenus)。resultType(TreeModel。class),ParallQuery。create()。sql(webframesearchAllUserReports)。resultType(TreeModel。class)),paramNames,paramValues);2。8跨数据库支持1、提供类似hibernate性质的对象操作,自动生成相应数据库的方言。2、提供了常用的:分页、取top、取随机记录等查询,避免了各自不同数据库不同的写法。3、提供了树形结构表的标准钻取查询方式,代替以往的递归查询,一种方式适配所有数据库。4、sqltoy提供了大量基于算法的辅助实现,较大程度上用算法代替了以往的sql,实现了跨数据库5、sqltoy提供了函数替换功能,比如可以让oracle的语句在mysql或sqlserver上执行(sql加载时将函数替换成了mysql的函数),较大程度上实现了代码的产品化。default:SubStrTrimInstrConcatNvl函数;可以参见org。sagacity。sqltoy。plugins。function。Nvl代码实现!跨数据库函数自动替换(非必须项),适用于跨数据库软件产品,如mysql开发,oracle部署propertynamefunctionConvertsvaluedefault!也可以这样自行根据需要进行定义和扩展propertynamefunctionConvertslistvalueorg。sagacity。sqltoy。plugins。function。Nvlvaluevalueorg。sagacity。sqltoy。plugins。function。SubStrvaluevalueorg。sagacity。sqltoy。plugins。function。Nowvaluevalueorg。sagacity。sqltoy。plugins。function。Lengthvaluelistproperty6、通过sqlIddialect模式,可针对特定数据库写sql,sqltoy根据数据库类型获取实际执行sql,顺序为:dialectsqlIdsqlIddialectsqlId,如数据库为mysql,调用sqlId:sqltoyshowcase,则实际执行:sqltoyshowcasemysqlsqlidsqltoyshowcasevalue!〔CDATA〔selectfromsqltoyuserlogtwheret。userid:userId〕〕valuesql!sqlId数据库方言(小写)sqlidsqltoyshowcasemysqlvalue!〔CDATA〔selectfromsqltoyuserlogtwheret。userid:userId〕〕valuesql2。9提供行列转换、分组汇总、同比环比等水果销售记录表
  品类
  销售月份
  销售笔数
  销售数量(吨)
  销售金额(万元)
  苹果
  2019年5月
  12hr2000hr2400hr苹果
  2019年4月
  11hr1900hr2600hr苹果
  2019年3月
  13hr2000hr2500hr香蕉
  2019年5月
  10hr2000hr2000hr香蕉
  2019年4月
  12hr2400hr2700hr香蕉
  2019年3月
  13hr2300hr27002。9。1行转列(列转行也支持)!行转列sqlidpivotcasevalue!〔CDATA〔selectt。fruitname,t。ordermonth,t。salecount,t。salequantity,t。totalamtfromsqltoyfruitordertorderbyt。fruitname,t。ordermonth〕〕value!行转列,将ordermonth作为分类横向标题,从salecount列到totalamt三个指标旋转成行pivotstartcolumnsalecountendcolumntotalamtgroupcolumnsfruitnamecategorycolumnsordermonthsql效果
  品类
  2019年3月
  2019年4月
  2019年5月
  笔数
  数量
  总金额
  笔数
  数量
  总金额
  笔数
  数量
  总金额
  香蕉
  13hr2300hr2700hr12hr2400hr2700hr10hr2000hr2000hr苹果
  13hr2000hr2500hr11hr1900hr2600hr12hr2000hr24002。9。2分组汇总、求平均(可任意层级)sqlidgroupsummarycasevalue!〔CDATA〔selectt。fruitname,t。ordermonth,t。salecount,t。salequantity,t。totalamtfromsqltoyfruitordertorderbyt。fruitname,t。ordermonth〕〕value!reverse是否反向summarycolumnssalecount,salequantity,totalamtreversetrue!层级顺序保持从高到低globalsumlabel总计labelcolumnfruitnamegroupgroupcolumnfruitnamesumlabel小计labelcolumnfruitnamesummarysql效果
  品类
  销售月份
  销售笔数
  销售数量(吨)
  销售金额(万元)
  总计
  71hr12600hr14900hr小计
  36hr5900hr7500hr苹果
  2019年5月
  12hr2000hr2400hr苹果
  2019年4月
  11hr1900hr2600hr苹果
  2019年3月
  13hr2000hr2500hr小计
  35hr6700hr7400hr香蕉
  2019年5月
  10hr2000hr2000hr香蕉
  2019年4月
  12hr2400hr2700hr香蕉
  2019年3月
  13hr2300hr27002。9。3先行转列再环比计算!列与列环比演示sqlidcolsrelativecasevalue!〔CDATA〔selectt。fruitname,t。ordermonth,t。salecount,t。saleamt,t。totalamtfromsqltoyfruitordertorderbyt。fruitname,t。ordermonth〕〕value!数据旋转,行转列,将ordermonth按列显示,每个月份下面有三个指标pivotstartcolumnsalecountendcolumntotalamtgroupcolumnsfruitnamecategorycolumnsordermonth!列与列之间进行环比计算colschainrelativegroupsize3relativeindexs1,2startcolumn1format。00sql效果
  品类
  2019年3月
  2019年4月
  2019年5月
  笔数
  数量
  比上月
  总金额
  比上月
  笔数
  数量
  比上月
  总金额
  比上月
  笔数
  数量
  比上月
  总金额
  比上月
  香蕉
  13hr2300hr2700hr12hr2400hr4。30
  2700hr0。00
  10hr2000hr16。70
  2000hr26。00
  苹果
  13hr2000hr2500hr11hr1900hr5。10
  2600hr4。00
  12hr2000hr5。20
  2400hr7。702。10分库分表2。10。1查询分库分表(分库和分表策略可以同时使用)sql参见quickstart项目:comsqltoyquickstartsqltoyquickstart。sql。xml文件!演示分库sqlidqstartdbshardingcaseshardingdatasourcestrategyhashDataSourceparamsuserIdvalue!〔CDATA〔selectfromsqltoyuserlogtuserId作为分库关键字段属于必备条件wheret。userid:userId〔andt。logdate:beginDate〕〔andt。logdate:endDate〕〕〕valuesql!演示分表sqlidqstartshardingtablecaseshardingtabletablessqltoytransinfo15dstrategyrealHisTableparamsbeginDatevalue!〔CDATA〔selectfromsqltoytransinfo15dtwheret。transdate:beginDate〔andt。transdate:endDate〕〕〕valuesql2。10。2操作分库分表(vo对象由quickvo工具自动根据数据库生成,且自定义的注解不会被覆盖)
  Sharding在对象上通过注解来实现分库分表的策略配置
  参见:com。sqltoy。quickstart。ShardingSearchTest进行演示packagecom。sqltoy。showcase。vo;importjava。time。LocalDate;importjava。time。LocalDateTime;importorg。sagacity。sqltoy。config。annotation。Sharding;importorg。sagacity。sqltoy。config。annotation。SqlToyEntity;importorg。sagacity。sqltoy。config。annotation。Strategy;importcom。sagframe。sqltoy。showcase。vo。base。AbstractUserLogVO;db则是分库策略配置,table则是分表策略配置,可以同时配置也可以独立配置策略name要跟spring中的bean定义name一致,fields表示要以对象的哪几个字段值作为判断依据,可以一个或多个字段maxConcurrents:可选配置,表示最大并行数maxWaitSeconds:可选配置,表示最大等待秒数Sharding(dbStrategy(namehashBalanceDBSharding,fields{userId}),tableStrategy(namehashBalanceSharding,fields{userId}),maxConcurrents10,maxWaitSeconds1800)SqlToyEntitypublicclassUserLogVOextendsAbstractUserLogVO{privatestaticfinallongserialVersionUID1296922598783858512L;defaultconstructorpublicUserLogVO(){super();}}2。11五种非数据库相关主键生成策略主键策略除了数据库自带的sequenceidentity外包含以下数据库无关的主键策略。通过quickvo配置,自动生成在VO对象中。2。11。1shortNanoTime22位有序安全ID,格式:13位当前毫秒6位纳秒3位主机ID2。11。2nanoTimeId26位有序安全ID,格式:15位:yyMMddHHmmssSSS6位纳秒2位(线程Id随机数)3位主机ID2。11。3uuid:32位uuid2。11。4SnowflakeId雪花算法ID2。11。5redisId基于redis来产生规则的ID主键
  根据对象属性值,产生规则有序的ID,比如:订单类型为采购:P销售:S,贸易类型:I内贸;O外贸;订单号生成规则为:1位订单类型1位贸易类型yyMMdd3位流水(超过3位自动扩展)最终会生成单号为:SI1911200012。12elastic原生查询支持2。13elasticsearchsql插件模式sql模式支持2。14sql文件变更自动重载,方便开发和调试2。15公共字段统一赋值,针对创建人、创建时间、修改人、修改时间等2。16提供了查询结果日期、数字格式化、安全脱敏处理,让复杂的事情变得简单3。集成说明3。1参见trunk下面的quickstart,并阅读readme。md进行上手packagecom。sqltoy。quickstart;importorg。springframework。boot。SpringApplication;importorg。springframework。boot。autoconfigure。SpringBootApplication;importorg。springframework。context。annotation。ComponentScan;importorg。springframework。transaction。annotation。EnableTransactionManagement;projectsqltoyquickstartdescriptionquickstart主程序入口authorzhongxuchenversionv1。0,Date:2020年7月17日modify2020年7月17日,修改说明SpringBootApplicationComponentScan(basePackages{com。sqltoy。config,com。sqltoy。quickstart})EnableTransactionManagementpublicclassSqlToyApplication{paramargspublicstaticvoidmain(String〔〕args){SpringApplication。run(SqlToyApplication。class,args);}}3。2application。propertiessqltoy部分配置sqltoyconfigspring。sqltoy。sqlResourcesDirclasspath:comsqltoyquickstartspring。sqltoy。translateConfigclasspath:sqltoytranslate。xmlspring。sqltoy。debugtruespring。sqltoy。reservedWordsstatus,sextypeobtainDataSource:org。sagacity。sqltoy。plugins。datasource。impl。DefaultObtainDataSourcspring。sqltoy。defaultDataSourcedataSource提供统一公共字段赋值(源码参见quickstart)spring。sqltoy。unifyFieldsHandlercom。sqltoy。plugins。SqlToyUnifyFieldsHandlerspring。sqltoy。printSqlTimeoutMillis2000003。3缓存翻译的配置文件sqltoytranslate。xmllt;?xmlversion1。0encodingUTF8?sagacityxmlnshttp:www。sagframe。comschemasqltoytranslatexmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。sagframe。comschemasqltoytranslatehttp:www。sagframe。comschemasqltoysqltoytranslate。xsd!缓存有默认失效时间,默认为1小时,因此只有较为频繁的缓存才需要及时检测cachetranslates!基于sql直接查询的方式获取缓存sqltranslatecachedictKeyNamedatasourcedataSourcesql!〔CDATA〔selectt。DICTKEY,t。DICTNAME,t。STATUSfromSQLTOYDICTDETAILtwheret。DICTTYPE:dictTypeorderbyt。SHOWINDEX〕〕sqlsqltranslate!员工ID和姓名的缓存sqltranslatecachestaffIdNamedatasourcedataSourcesql!〔CDATA〔selectSTAFFID,STAFFNAME,STATUSfromSQLTOYSTAFFINFO〕〕sqlsqltranslate!机构号和机构名称的缓存sqltranslatecacheorganIdNamedatasourcedataSourcesql!〔CDATA〔selectORGANID,ORGANNAMEfromSQLTOYORGANINFOorderbySHOWINDEX〕〕sqlsqltranslatecachetranslates!缓存刷新检测,可以提供多个基于sql、service、rest服务检测cacheupdatecheckers!基于sql的缓存更新检测sqlincrementcheckercacheorganIdNamecheckfrequency60datasourcedataSourcesql!〔CDATA〔notdebugselectORGANID,ORGANNAMEfromSQLTOYORGANINFOwhereUPDATETIME:lastUpdateTime〕〕sqlsqlincrementchecker!增量更新,检测到变化直接更新缓存sqlincrementcheckercachestaffIdNamecheckfrequency30datasourcedataSourcesql!〔CDATA〔notdebugselectSTAFFID,STAFFNAME,STATUSfromSQLTOYSTAFFINFOwhereUPDATETIME:lastUpdateTime〕〕sqlsqlincrementchecker!增量更新,带有内部分类的查询结果第一列是分类sqlincrementcheckercachedictKeyNamecheckfrequency15hasinsidegrouptruedatasourcedataSourcesql!〔CDATA〔notdebugselectt。DICTTYPE,t。DICTKEY,t。DICTNAME,t。STATUSfromSQLTOYDICTDETAILtwheret。UPDATETIME:lastUpdateTime〕〕sqlsqlincrementcheckercacheupdatecheckerssagacity实际业务开发使用,直接利用SqlToyCRUDService就可以进行常规的操作,避免简单的对象操作自己写service,另外针对复杂逻辑则自己写service直接通过调用sqltoy提供的:SqlToyLazyDao完成数据库交互操作!RunWith(SpringRunner。class)SpringBootTest(classesSqlToyApplication。class)publicclassCrudCaseServiceTest{AutowiredprivateSqlToyCRUDServicesqlToyCRUDService;创建一条员工记录TestpublicvoidsaveStaffInfo(){StaffInfoVOstaffInfonewStaffInfoVO();staffInfo。setStaffId(S190715005);staffInfo。setStaffCode(S190715005);staffInfo。setStaffName(测试员工4);staffInfo。setSexType(M);staffInfo。setEmail(test3aliyun。com);staffInfo。setEntryDate(LocalDate。now());staffInfo。setStatus(1);staffInfo。setOrganId(C0001);staffInfo。setPhoto(FileUtil。readAsBytes(classpath:mockstaffphoto。jpg));staffInfo。setCountry(86);sqlToyCRUDService。save(staffInfo);}}4。sqltoysql关键说明4。1sqltoysql最简单规则〔〕对称符号〔〕等于if(中间语句参数是否有null)?true:剔除〔〕整块代码,false:拿掉〔和〕,将中间的sql作为执行的一部分。〔〕支持嵌套,如〔t。status:status〔andt。createDate:createDate〕〕会先从内而外执行if(null)逻辑利用filters条件值预处理实现判断null的统一,下面是sqltoy完整提供的条件过滤器和其他函数不要被大段的说明吓一跳,99都用不上,正常filters里面只会用到eq和todatesqlidshowcase!通过filters里面的逻辑将查询条件转为null,部分逻辑则对参数进行二次转换默认条件参数为空白、空集合、空数组都转为nullparmas表示可以用逗号写多个参数,param表示只支持单个参数filters!等于,如机构类别前端传负一就转为null不参与条件过滤eqparamsorganTypevalue1!条件值在某个区间则转为nullbetweenparamsstartvalue0endvalue9999!将参数条件值转换为日期格式,format可以是yyyyMMdd这种自定义格式也可以是:firstofday:月的第一天;lastofday:月的最后一天,firstofyear:年的第一天,lastofyear年的最后一天,incrementunit默认为daystodateparamsformatyyyyMMddincrementtime1incrementunitdays!将参数转为数字tonumberparamsdatatypedecimal!将前端传过来的字符串切割成数组splitdatatypestringparamsstaffAuthOrgssplitsign,!小于等于lteparamsvalue!小于ltparamsvalue!大于等于gteparamsvalue!大于gtparamsvalue!字符替换,默认根据正则表达进行全部替换,isfirst为true时只替换首个replaceparamsregexvalueisfirstfalse!首要参数,即当某个参数不为null时,excludes是指被排除之外的参数全部为nullprimaryparamorderIdexcludesorganIds!排他性参数,当某个参数是xxx值时,将其他参数设置为特定值exclusiveparamcomparetypeeqcomparevaluessetparamssetvalue!通过缓存进行文字模糊匹配获取精确的代码值参与精确查询cacheargcachenamecachetypeparamcachemappingindexesaliasname!将数组转化成in的参数条件并增加单引号toinargparamsfilters!缓存翻译,可以多个,uncachedtemplate是针对未能匹配时显示的补充,{value}表示显示key值,可以key〔{value}未定义这种写法translatecachedictKeyNamecachetypePOSTTYPEcolumnsPOSTTYPEcacheindexs1uncachedtemplate!安全掩码:tel姓名地址卡号!最简单用法:securemaskcolumnstypetelsecuremaskcolumnstypenameheadsize3tailsize4maskcodemaskrate50!分库策略shardingdatasourcestrategy!分表策略shardingtabletablesstrategyparams!分页优化,缓存相同查询条件的分页总记录数量,alivemax:表示相同的一个sql保留100个不同条件查询aliveseconds:相同的查询条件分页总记录数保留时长(单位秒)pageoptimizealivemax100aliveseconds600!日期格式化dateformatcolumnsformatyyyyMMddHH:mm:ss!数字格式numberformatcolumnsformatvalue!〔CDATA〔selectt1。,t2。ORGANNAMEfromfast(selectfromsysstaffinfotwhere〔t。sexType:sexType〕〔andt。JOINDATE:beginDate〕〔andt。STAFFNAMElike:staffName〕是否虚拟员工if()做逻辑判断〔if(:isVirtualtrue:isVirtual0)andt。ISVIRTUAL1〕)t1,sysorganinfot2wheret1。ORGANIDt2。ORGANID〕〕value!为极致分页提供自定义写sqlcountsql!〔CDATA〔〕〕countsql!汇总和求平均,通过算法实现复杂的sql,同时可以变成数据库无关summarycolumnsradixsize2reversefalsesumsiteleftglobalsumlabellabelcolumngroupsumlabellabelcolumngroupcolumnsummary!拼接某列,mysql中等同于groupconcatoracle中的WMSYS。WMCONCAT功能linksign,column!行转列(跟unpivot互斥),算法实现数据库无关pivotcategorycolumnsgroupcolumnsstartcolumnendcolumndefaultvalue0!列转行unpivotcolumnsvaluesascolumnsql5。sqltoy关键代码说明5。1sqltoyorm主要分以下几个部分:SqlToyDaoSupport:提供给开发者Dao继承的基本Dao,集成了所有对数据库操作的方法。SqlToyLazyDao:提供给开发者快捷使用的Dao,等同于开发者自己写的Dao,用于在简单场景下开发者可以不用写Dao,而直接写Service。SqltoyCRUDService:简单Service的封装,一些简单的对象增删改开发者写Service也是简单的调用Dao,针对这种场景提供一个简单功能的Service调用,开发者自己的Service用于封装相对复杂的业务逻辑。DialectFactory:数据库方言工厂类,sqltoy根据当前连接的方言调用不同数据库的实现封装。SqlToyContext:sqltoy上下文配置,是整个框架的核心配置和交换区,spring配置主要是配置sqltoyContext。EntityManager:封装于SqlToyContext,用于托管POJO对象,建立对象跟数据库表的关系。sqltoy通过SqlToyEntity注解扫描加载对象。ScriptLoader:sql配置文件加载解析器,封装于SqlToyContext中。sql文件严格按照。sql。xml规则命名。TranslateManager:缓存翻译管理器,用于加载缓存翻译的xml配置文件和缓存实现类,sqltoy提供了接口并提供了默认基于ehcache的实现,缓存翻译最好是使用ehcache本地缓存(或ehcachermi模式的分布式缓存),这样效率是最高的,而redis这种分布式缓存IO开销太大,缓存翻译是一个高频度的调用,一般会缓存注入员工、机构、数据字典、产品品类、地区等相对变化不频繁的稳定数据。ShardingStragety:分库分表策略管理器,4。x版本之后策略管理器并不需要显式定义,只有通过spring定义,sqltoy会在使用时动态管理。5。2快速阅读理解sqltoy:从BaseDaoSupport(或SqlToyDaoSupport)作为入口,你会看到sqltoy的所有提供的功能,通过LinkDaoSupport则可以按照不同分类视角看到sqltoy的功能组织形式。从DialectFactory会进入不同数据库方言的实现入口。可以跟踪看到具体数据库的实现逻辑。你会看到oracle、mysql等分页、取随机记录、快速分页的封装等。EntityManager:你会找到如何扫描POJO并构造成模型,知道通过POJO操作数据库实质会变成相应的sql进行交互。ParallelUtils:对象分库分表并行执行器,通过这个类你会看到分库分表批量操作时如何将集合分组到不同的库不同的表并进行并行调度的。SqlToyContext:sqltoy配置的上下文,通过这个类可以看到sqltoy全貌。PageOptimizeUtils:可以看到分页优化默认实现原理。

大疆又搞事了?9月8日大疆精灵5或将发布作为航拍器、云台等产品的绝对行业龙头,大疆的一举一动都能吸引众多专业用户。日前,大疆在微博的一条预告更是让人浮想联翩,预告海报内容是一个冰封的数字5,或许代表着沉寂多年的大疆精……他是国内第一家比特币交易平台的创始人,区块链行业的先行者他是国内第一家比特币交易平台创始人,区块链行业的先行者在区块链领域,虚拟数字货币交易永远都是一个绕不开的话题,而且,自从币市出现了许多百倍币,一度迎来大牛市之后,也有越来……东航MU5735的初步报告,告诉了我们什么,可能是什么原因导距离主撞击点12公里以外发现的右翼尖小翼后缘应该是这次初步报告的重点,为何这个部件出现在主撞击点12公里以外的地方,是不是飞机在空中就已经开始部件解体了?事故现场翘……低调的百度老板娘马东敏15岁进中科大少年班,向母校捐1亿这个女人不简单,裸婚嫁给相爱不到三个月的恋人,几年时间从身无分文到资产上亿,她帮助丈夫从程序员到公司老总,捐款一亿给母校。马东敏女士被誉为百度背后的女人,李彦宏直言没有妻子就没……农村电商人才之困引不来留不住难培养《经济参考报》记者近日在宁夏、广西、新疆、云南、江西等地走访发现,农村信息基础设施与城镇的差距日益缩小,但缺少信息化人才造成新的城乡数字鸿沟,农村电商发展受限。基层干部建议,增……我家波轮洗衣机坏了,换了一台滚筒洗衣机,用了半年,说一说感受我家里买过几台洗衣机,坏了一台,就再买一台,一直用的都是波轮洗衣机,原因是波轮洗衣机性价比高,一千元不到就能买到一台。早半年前,我家里的波轮洗衣机又坏了,原本商家建议我再买一台……用科技描绘上古神力,华为设计师讲述神兽主题背后的故事麒麟芯片、鲲鹏处理器、泰山服务器、鸿蒙操作系统以古书中的意象为产品命名已经成了华为的传统,日前华为刚刚上线了一套山海经神兽主题,将六只上古神兽搬进了手机等智能终端。华为为……亚马逊华裔女高管即将离职曾任贝索斯影子顾问8月17日消息,亚马逊于美国当地时间周一证实,其杂货店业务女高管WeiGao即将离职。她曾担任过亚马逊创始人杰夫贝索斯(JeffBezos)的影子顾问。WeiGao最近担……安卓手机性价比榜,红米杀疯了,多个价位登顶7月已经过去了半个月时间,最近安兔兔才发布了7月安卓手机的性价比榜单。根据安兔兔公布的数据来看,一共分为五大区间,分别是01999元、20002999元、30003999元、4……腾讯的明天会怎么样?腾讯面临多重利空,股价持续下挫。相关利空主要有:1。教培行业遭受毁灭性打击对腾讯投资收益的负面影响;长期乐观,短期承压(我相当于啥都没说〔捂脸〕〔捂脸〕)2。……新修订科技进步法迎来哪些重大变化?专家解析来源:科技日报新修订科技进步法迎来哪些重大变化专家解析时隔十四年修法背后的意义和亮点(下)本报记者刘垠作为我国科技领域的基本法,施行28年后,科学技术进步法(……Win10电脑怎么给硬盘分区?Win10电脑怎么给硬盘分区?其实借助易我分区大师工具,分区就变得非常简单,怎么分都不会有错!当我们的电脑安装好后,里面只有一个或者两个分区,这样就很不方便管理电脑里面的……
海信x天猫超级品牌日震撼来袭,VIDAA电视当潮不让新年换新正当时,换上一年好运气!海信集团x天猫超级品牌日1月1315日即将登陆天猫商城。超品日碰上年货期,海信携手天猫组成海天CP,开启寻家环游记;邀你一起以AI为家,为新家加……数字驱动智慧领航,2018云栖新零售峰会,论实践,探未来9月21日,2018年云栖大会第三天,新零售峰会在云栖小镇盛大举办。本届峰会以新零售为主题,邀请了天猫、阿里零售通、淘宝、盒马、阿里供应链平台,吸引了来自零售、快消、电子、制造……AMD不稳定的认知到底怪谁?英特尔究竟有多厉害?提到英特尔这三个字,各位首先想到的是什么?一家独大连续好几年戏弄消费者的挤牙膏,永远的14nm加加加,还是一有风吹草动,就涨价的光荣传统,事实上,Intel是全球最大的个人计算……传统主业净利持续下滑云南能投拟再度加码风电项目谋突围财联社(成都,记者熊嘉楠)讯,转型风电刚刚两年的云南能投(002053。SZ)如今宣布将筹建大姚县涧水塘梁子风电场风电项目,再度加码风电项目。大姚县涧水塘梁子风电场项目也是继曲……理解交易中最值得信赖和可靠的理论之一威科夫交易法在传奇技术分析师的神殿中,或许没有人比理查德威科夫(RichardWyckoff)更高。威科夫在20世纪初观察市场时,首创了一种技术分析方法,至今仍被交易员广泛使用。威科夫理论……安装壁挂式广告机时需要留意哪些问题?液晶广告机就安装方式而言目前仅分为壁挂式液晶广告机和立式液晶广告机,立式广告机的安装。比较简单,只需要轻轻抬放到指定的位置、通上电即可使用。而壁挂式液晶广告机安装就相对复杂点,……全球变速箱质量最好的6大品牌,你知道几个?日本品牌占据两席作为汽车三大件之一的变速箱,在汽车工业的发展历程中有着举足轻重的地位。全球汽车品牌浩如烟海,但是变速箱的品牌却屈指可数,其中质量最好的6大品牌更是占据了市场八成以上的份额。你知……电路板焊接注意事项(一)看实物画电路图,关键是在看图,图看不明白,就无法作好图,中考有个内部规定,混联作图是不要求的,那么你心里应该明白实物图实际上只有两种电路,一种串联,另一种是并联,串联电路……一文带你了解自动驾驶传感器随着汽车电动化、智能化、网联化、共享化发展,自动驾驶的雏形也逐渐出现,虽然自动驾驶汽车还未完全商用化,但很多车企已经开始布局L3甚至L4级别的自动驾驶汽车。美国国家公路交通安全……290元英特尔神秘处理器一夜爆红!背后隐藏的故事有几人知道?290元的英特尔笔记本神U的文章,魔改君也写过很多了。但是之间都是购买于淘宝水晶家,配合魔改君自创的方法,用着很舒服,不需要工具,跟普通处理器安装方法完全一样,也有……高考延迟1个月,这次微信还是迟到了2020年不平凡的一年,就在昨日,国家通知高考延迟1个月。疫情之间社交APP的下载量一直稳定的微信却被钉钉超越,钉钉是阿里巴巴旗下的一个商务办公软件,这让马化腾万万没想到……如今AI有多强?软体机器人能钻进身体做手术,小爱还能隔空传话其实如今也有不少机器人运用于手术领域,之前就有能做骨科手术的机器人投入使用,但今天要说的同样已经投入手术中使用的软体机器人,着实让小编大为惊叹。据悉,最近来自哈佛大学和波……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网