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

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

内容简介:致谢: 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!


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

查看所有标签

猜你喜欢:

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

Design systems

Design systems

Not all design systems are equally effective. Some can generate coherent user experiences, others produce confusing patchwork designs. Some inspire teams to contribute to them, others are neglected. S......一起来看看 《Design systems》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具