sqltoy-orm-4.16.1 发版,深度对比 mybatis!

栏目: 软件资讯 · 发布时间: 3年前

内容简介:致谢: 1、首先要特别感谢大家的积极反馈,提出了非常好的意见,比如通过sqlId组合dialect实现sql跨数据库、@loop循环组织sql 等等,很多东西虽然是极端场景,但充实了sqltoy面对极端场景的应对能力! 开源地址:...

致谢:

1、首先要特别感谢大家的积极反馈,提出了非常好的意见,比如通过sqlId组合dialect实现 sql 跨数据库、@loop循环组织sql 等等,很多东西虽然是极端场景,但充实了sqltoy面对极端场景的应对能力!

开源地址:

更新内容

1、增强产品跨库执行能力,支持sql id=dialect_id或id_dialect ,以id调用优先结合当前数据库dialect组合,如 mysql 则优先找mysql_id和id_mysql的sql,找不到则执行id对应的sql,从而在函数自适配的基础上进一步增强了跨库能力。
2、增加@loop(loopParam,loopContent,linkSign) 宏嵌入sql,便于极端场景下灵活组合动态sql

<sql id="qstart_loop_sql">
<value>
	<![CDATA[
	 select ORDER_ID
	        @loop(:fields,",:fields[i]")
	 from sqltoy_device_order t 
	 where #[t.ORDER_ID=:orderId]
		   #[@if(size(:staffIds)>0) and (@loop(:staffIds," t.STAFF_ID=':staffIds[i]' "," or ","1","100"))]
		   #[@blank(:startDates) 
		         and ( @loop(:startDates,
				             " t.TRANS_DATE between STR_TO_DATE(':startDates[i]','%Y-%m-%d') 
				               and STR_TO_DATE(':endDates[i]','%Y-%m-%d') " ,
				              " or "))]
	]]>
	</value>
</sql>

3、增强@if() 功能,提供获取size和判断其中包含某个值的功能,@if(size(:statusAry)>0) 和 @if(:statusAry include 1)
4、改进saveOrUpdate 功能,将全主键和无主键进行了区分处理,全主键返回继续做saveAllIgnoreExist操作
5、优化执行日志输出,以一个执行报告形式统一输出
6、进一步改进TranslateManager,简化二次扩展,便于开发者通过扩展实现近实时的缓存更新管理
7、增加树结构List排序,便于页面快速输出

为什么写sqltoy?

  • sqltoy是在2008年使用hibernate jpa的基础上发现了一个极致的动态sql组织模式(sqltoy的发明专利)

    可以看这篇文章: https://blog.csdn.net/iteye_2252/article/details/81683940

  • 2010年又巧妙的结合缓存,实现了缓存翻译,大幅简化了sql并提升了sql的性能(sqltoy的发明专利)
  • 2011~2015年发现了快速分页和分页优化,让特定场景下分页性能大幅提升(sqltoy的发明专利)
  • 2012年,sqltoy实现了类似于hibernate jpa的功能,当然在update、saveOrUpdate等很多方面做了大幅优化,规避了hibernate的缺陷,从而形成了完整的ORM功能体系。
  • 2013年:sqltoy作为sagacity-nebula星云报表框架的底层,为快速配置化在线化实现报表功能发挥了极大的作用。
  • 2015~2018年,sqltoy作为拉卡拉数据平台的底层,实现了分库分表、mongo、elasticsearch等支持,满足了日均千万级、总数据规模达30亿的数据ETL和数据OLAP诉求。
  • 2018~至今:sqltoy作为目前公司ERP、电商、CRM、数据平台的底层,可靠性和质量得到了长足的发展。

基于上述事实:

1、如果放弃sqltoy而使用mybatis等,面对复杂查询将失去很多便捷的手段,建立在其基础上的很多框架和产品就必须重新选择!

2、sqltoy的三个专利体现的功能mybatis和其他框架是无法拥有的,而这三点又对查询极为关键!

3、sqltoy具有良好的特性,非刻意而为,完全可以打造一个属于中国人的ORM框架,而ORM又极为底层和基础!

开始进入深度对比:

  • 平手点: sql热加载、分库分表、保存/批量保存、删除、依据主键加载 
  • 剩下的都比mybatis(plus)强

sqltoy的crud:sqltoy 是类似于jpa式的crud,是无需写sql的,sqltoy提供了SqlToyLazyDao\SqlToyCRUDService,开发者无需写dao。

//保存对象
StaffInfoVO staffInfo = new StaffInfoVO();
staffInfo.setStaffId("S2007")
         .setStaffCode("S2007")
 		 .setPhoto(FileUtil.readAsBytes("classpath:/mock/staff_photo.jpg"))
         .setCountry("86");
sqlToyCRUDService.save(staffInfo);

//可以了解一下sqltoy的update,会自动忽视掉null属性,但可以通过forceUpdateProps来指定强制修改字段
//Long update(Serializable entity, String... forceUpdateProps);
StaffInfoVO staffInfo = new StaffInfoVO();
staffInfo.setStaffId("S2007");
staffInfo.setEmail("test07@139.com");
// 这里对照片进行强制修改
sqlToyCRUDService.update(staffInfo, "photo");


//唯一性验证
StaffInfoVO staffInfo = new StaffInfoVO();
staffInfo.setStaffId("S0006");
staffInfo.setStaffCode("S0006");
Boolean result = sqlToyCRUDService.isUnique(staffInfo, "staffCode");

//还有updateFetch、load(entity,lock)等等

代码中实现查询(纠正一下:sqltoy only xml、only sql的片面认识,sqltoy的参数是sql或者sqlId,jdk15文本块后可以将部分短sql写在代码中)

// @todo 通过对象传参数,简化paramName[],paramValue[] 模式传参
// @param <T>
// @param sqlOrNamedSql 可以是具体sql也可以是对应xml中的sqlId
// @param entity        通过对象传参数,并按对象类型返回结果
public <T extends Serializable> List<T> findBySql(final String sqlOrNamedSql, final T entity);



// 动态条件查询,基于对象传参,一个具有分页、缓存翻译、分页优化的代码比mybatis plus会复杂吗?
PaginationModel<StaffInfoVO> result = sqlToyLazyDao.findEntity(StaffInfoVO.class, new PaginationModel(),
		EntityQuery.create().where("#[status=:status] #[and staffName like :staffName]")
				.orderByDesc("ENTRY_DATE").values(new StaffInfoVO().setStaffName("陈"))
				// 设置rlike
				.filters(new ParamsFilter("staffName").rlike())
				// 设置缓存翻译
				.translates(new Translate("organIdName").setKeyColumn("organId").setColumn("organName"))
				// 设置分页优化
				.pageOptimize(new PageOptimize().aliveSeconds(120)));

// 在代码中实现单表查询
// 1、可指定特定字段
// 2、提供了分页和非分页两种
// 3、可以排序
// 4、可以进行缓存翻译
// 5、可以做分页优化
PaginationModel<StaffInfoVO> result = sqlToyLazyDao.findEntity(StaffInfoVO.class, new PaginationModel(),
	// 支持三种方式指定字段:
	// 1、用一个字符串写多个字段
	// EntityQuery.create().select("staffId,staffCode, staffName, organId,sexType")
	// 2、按数组形式提供字段
	// EntityQuery.create().select("staffId", "staffCode", "staffName",
	// "organId","sexType")
	// 3、采用链式模式提供字段
			EntityQuery.create().select(StaffInfoVO.select().staffId().staffCode().staffName().organId().sexType())
// 支持动态条件
.where("#[status=?] #[and staffName like ?]").orderByDesc("entryDate").values(1, "陈")
// 支持缓存翻译
.translates(new Translate("organIdName").setKeyColumn("organId").setColumn("organName"))
// 支持分页优化
.pageOptimize(new PageOptimize().aliveSeconds(120))
// 开关空白转null
.blankNotNull());

下面进入正题

  • 公共属性赋值
# 提供统一字段:createBy createTime updateBy updateTime 等字段补漏性(为空时)赋值(可选配置)
spring.sqltoy.unifyFieldsHandler=com.sqltoy.plugins.SqlToyUnifyFieldsHandler
  • 跨数据库支持:帮助实现一套代码多个数据库适用,函数自适配转换、优先执行dialect_id或id_dialect 对应的sql
# 提供跨数据库函数自适应转换,如mysql的函数在oracle下自动被替换
spring.sqltoy.functionConverts=default,com.xxxx.functions.GroupConcat
<sql id="qstart_cols_relative_case">
	<value>
	<![CDATA[
	select t.fruit_name,t.order_month,t.sale_count,t.sale_price,t.total_amt 
	from sqltoy_fruit_order t
	order by t.fruit_name ,t.order_month
	]]>
	</value>
</sql>

<!-- 当目前数据库是mysql时会优先执行mysql_开头或_mysql结尾的sql -->
<sql id="mysql_qstart_cols_relative_case">
	<value>
	<![CDATA[
	select t.fruit_name,t.order_month,t.sale_count,t.sale_price,t.total_amt 
	from sqltoy_fruit_order t
	order by t.fruit_name ,t.order_month
	]]>
	</value>
</sql>
  • 极致的动态查询(适用于代码中直接写的sql):请思考跟mybatis的对比,同时思考后期的可维护性!

    这是当初坚持写sqltoy的根本原因,因为其它一切对等的情况下,面对项目查询较多较复杂时,sqltoy的优势无与伦比!

sqltoy的机制,#[]类似于if(null)判断,同时提供了极为灵活的可能
1、简单的:#[and t.status=:status]
2、任意为null剔除:#[and t.status=:status and t.name like :name]
3、支持嵌套:#[and t.status=:status #[and t.name like :name]]
<sql id="show_case">
<filters>
   <!-- 参数statusAry只要包含-1(代表全部)则将statusAry设置为null不参与条件检索 -->
   <eq params="statusAry" value="-1" />
   <!-- 首要条件:当订单号不为空,排除其他条件(除授权机构)  -->
   <primary param="orderId" excludes="authedOrganIds"/>
</filters>
<value><![CDATA[
	select 	*
	from sqltoy_device_order_info t 
	where #[t.status in (:statusAry)]
		  #[and 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]    
	]]></value>
</sql>

同样功能mybatis的实现!如果再复杂点的呢?

<select id="show_case" resultMap="BaseResultMap">
 select *
 from sqltoy_device_order_info t 
 <where>
     <if test="statusAry!=null">
	and t.status in
	<foreach collection="status" item="statusAry" separator="," open="(" close=")">  
            #{status}  
 	</foreach>  
    </if>
    <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>
</select>

以下面的查询条件来说,mybatis如何应对?写出来的sql还能看吗?后期还能维护吗?

sqltoy-orm-4.16.1 发版,深度对比 mybatis!

  • 缓存翻译(关于缓存定义和更新机制这里篇幅原因不深入介绍),sqltoy的专利!

sqltoy-orm-4.16.1 发版,深度对比 mybatis!

  • 极致分页优化(sqltoy的专利)

sqltoy-orm-4.16.1 发版,深度对比 mybatis!

  • 并行查询(同时执行提升效率)
// 使用并行查询同时执行2个sql,条件参数是2个查询的合集
String[] paramNames = new String[] { "userId", "defaultRoles", "deployId", "authObjType" };
Object[] paramValues = new Object[] { userId, defaultRoles, DEPLOY_ID,GROUP };

List<QueryResult<TreeModel>> list = super.parallQuery(
		Arrays.asList(
            ParallQuery.create().sql("webframe_searchAllModuleMenus").resultType(TreeModel.class),	
			ParallQuery.create().sql("webframe_searchAllUserReports").resultType(TreeModel.class)
),paramNames, paramValues);
  • 数据旋转:用算法来减少复杂大sql

sqltoy-orm-4.16.1 发版,深度对比 mybatis!

  • 无限极分组统计(含汇总求平均),算法配置简单又跨数据库,谁说sqltoy喜欢强调sql的?该算法就算法,该sql就sql,不要僵化教条

sqltoy-orm-4.16.1 发版,深度对比 mybatis!

  • 同比环比

sqltoy-orm-4.16.1 发版,深度对比 mybatis!


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Django企业开发实战

Django企业开发实战

胡阳 / 人民邮电出版社 / 2019-2 / 99.00元

本书以博客系统贯穿始末,介绍了Django的方方面面。书中共分四部分,第一部分介绍了正式进入编码之前的准备工作,内容包括需求分析、基础知识和Demo系统的开发;第二部分开始实现需求,内容涉及环境配置、编码规范以及项目结构规划,编写了Model层、admin页面、Form代码和View逻辑,引入了Bootstrap框架;第三部分重点介绍xadmin、django-autocomple-light和d......一起来看看 《Django企业开发实战》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

html转js在线工具
html转js在线工具

html转js在线工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具