简介


AnyLine的核心是一个基于spring-jdbc生态的(No-ORM)数据库操作工具
其重点是:

  • 以最简单、快速的方式操作数据库
  • 针对结果集的数据二次处理能力

简单来说主要作了两方面的工作:

  • 对查询条件的封装
    拼接个查询条件不再需要各种空判断、遍历、类型转换了,机械繁琐的工作交给机器

  • 返回的结果集中处理了开发中能遇到到的各种情况
    为前端或第三方应用提供数据不再需要各种遍历、各种判断、各种计算了,尽量作到一键...

同时摒弃了各种繁琐呆板的Service/Dao/Entity/*O/Mapper 没有mybatis 没有各种配置 各种O
没有需要自动生成的代码,没有模板文件(自动生成的都是程序员的负担)



Anyline一的切都是面向动态、面向运行时环境
适合于抽象设计阶段(实体概念还不明确或者设计不限于某个特别的实体)
常用于需要大量复杂动态的查询,以及查询的结果集需要经过深度处理的场景 如:

  • 可视化数据源
  • 低代码后台
  • 物联网数据处理
  • 数据清洗、数据批量处理
  • 报表输出,特别是自定义报表
  • 运行时自定义表单/查询条件/数据结构
  • 网络爬虫数据解析
  • 还有一种很实现的场景是 许多项目到了交付的那一天 实体也没有设计完成

什么情况下说明你的应该考虑换工具了

  • 非常简单的增删改查,Entity中大部分只用到了get/set方法,很少需要计算
    这一般都是些hello world 或 练习作业
    这样的直接利用默认的service查出数据返回给前端就可以收工了
    不要再生成一堆重复的模板,简单改个属性也要层层修改,从头改个遍。

  • 代码中出现了大量的List,Map结构 或者 针对查询结果集需要大量的二次计算
    这种情况应该非常多见
    随着系统的增强完善和高度的抽象,同一份数据源将为各种不同的业务场景提供数据支持
    每个场景需要的数据结构各不雷同
    这时经常是为每类场景订制视图或SQL
    但数据支持部门不可能针对每种场景每个视图、每个SQL 生成不同的Entity
    更也不可能生成一个大而全的Entity以应万变

无论是Map还是Entity计算能力都非常有限,通过需要开发人员各种遍历、计算、格式化
而这种大量的机械的计算应该占用开发人员的时间
Anyline提供的默认数据结构DataSet/DataRow已经实现了常用的数据二次处理功能,如:
排序、维度转换、截取、去重、方差、偏差、交集合集差集、分组、忽略大小写对比、行列转换、类SQL过滤筛选(like,eq,in,less,between...)、JSON、XML格式转换等



  • http参数到jdbc参数的转换

    在实际开发中、业务开发人员经常需要大量的时间,不厌其烦的从http/rpc中提取参数,判断验证,生成jdbc要求格式的参数,再把参数依次传到service、dao,最后返回一个实现bean。这整个过程中经常有各种小细节容易忽略而导致异常,如空值处理,IN条件生成等。
    而在整个项目中这些过程又是大量重复或类似的。这不但影响开发速度与代码质量,更影响心情。
    所以AnyLine提供了一个统一约定格式来实现这些繁琐的操作,格式大致如下

      参数值⇢
    约定格式⇣
    1 2 3 4 5 6 7
      code=0 code= code=0&code=1&cd=2&user=5 code=0,1&cd=2&user=5
    cd=2&cd=3 code=0(密文) cd=2(密文)&cd=3(密文)
    1 CODE:code CODE = 0 忽略 CODE = 0
    CODE = 0 忽略 忽略 忽略
    2 CODE:%code% CODE LIKE '%0%' 忽略 CODE LIKE '%0%'
    CODE LIKE '%0%'
    忽略 忽略 忽略
    3 CODE:%code CODE LIKE '%0' 忽略 CODE LIKE '%0'
    CODE LIKE '%0' 忽略 忽略 忽略
    4 CODE:code% CODE LIKE '0%' 忽略 CODE LIKE '0%'
    CODE LIKE '0%' 忽略 忽略 忽略
    5 CODE:%code:cd% CODE LIKE '%0%' 忽略 CODE LIKE '%0%'
    CODE LIKE '%0%' CODE LIKE '%2%' 忽略 忽略
    6 CODE:%code:cd:${9}% CODE LIKE '%0%' CODE LIKE '%9%' CODE LIKE '%0%'
    CODE LIKE '%0%' CODE LIKE '%2%' 忽略 忽略
    7 CODE:%code:cd CODE LIKE '%0' 忽略 CODE LIKE '%0'
    CODE LIKE '%0' CODE LIKE '%2' 忽略 忽略
    8 CODE:%code:cd:${9} CODE LIKE '%0' CODE LIKE '%9' CODE LIKE '%0'
    CODE LIKE '%0' CODE LIKE '%2' 忽略 忽略
    9 CODE:[code] CODE = 0 忽略 CODE IN(0,1)
    CODE IN(0,1) 忽略 忽略 忽略
    10 CODE:[split(code)] CODE = 1 忽略
    CODE IN(0,1)
    CODE IN(0,1)
    忽略
    忽略
    忽略
    11 CODE:[org.ClassA.split(code)] CODE = 1 忽略
    CODE IN(0,1)
    CODE IN(0,1)
    忽略
    忽略
    忽略
    12 CODE:[code:cd] CODE = 0 忽略 CODE IN(0,1)
    CODE IN(0,1) CODE IN(2,3) 忽略 忽略
    13 CODE:[cd+] 忽略
    忽略
    CODE = 2
    CODE = 2 CODE IN(2,3) 忽略
    CODE IN(2,3)
    14 CODE:[code:cd:${[6,7,8]}] CODE = 0 CODE IN(6,7,8) CODE IN(0,1)
    CODE IN(0,1) CODE IN(2,3) 忽略 忽略
    15 CODE:[code:cd:${6,7,8}]
    CODE = 0 CODE IN(6,7,8) CODE IN(0,1)
    CODE IN(0,1) CODE IN(2,3) 忽略 忽略
    16 +CODE:code CODE = 0 CODE IS NULL CODE = 0
    CODE = 0 CODE IS NULL 忽略 忽略
    17 ++CODE:code CODE = 0 不执行 CODE = 0
    CODE = 0 不执行 忽略 忽略
    18 CODE:>code CODE > 0 忽略 CODE > 0
    CODE > 0 忽略 忽略 忽略
    19 CODE:>code:cd CODE > 0 忽略 CODE > 0
    CODE > 0 CODE > 2 忽略 忽略
    20 CODE:>code:${9} CODE > 0 CODE > 9 CODE > 0
    CODE >0 CODE > 9 CODE > 9 CODE > 9
    21 CODE:code:cd CODE = 0 忽略 CODE = 2
    CODE = 2 CODE = 2 忽略 忽略
    22 CODE:code:cd:${9} CODE = 0 CODE = 9 CODE = 0
    CODE = 0 CODE = 2 忽略 忽略
    23 CODE:code|cd 只有code取值成功,当前条件才生效,注意与下一条的区别 CODE = 0 忽略 CODE =0 OR CODE = 2
    CODE =0 OR CODE = 2 忽略 忽略 忽略
    24 CODE:code|{NULL} CODE = 0 OR CODE IS NULL 忽略 CODE = 0 OR CODE IS NULL
    CODE = 0 OR CODE IS NULL 忽略
    忽略
    忽略
    25 CODE:code|CODE:cd code与cd不相干,哪个有值取哪个 CODE = 0 忽略 CODE = 0 OR CODE = 1
    CODE = 0 OR CODE = 1 CODE = 2 忽略 忽略
    26 CODE:code|CD:cd 与上一条规则相同 CODE = 0 忽略 CODE = 0 OR CD = 2
    CODE = 0 OR CD = 2 CD = 2 忽略 忽略
    27 CODE:code:cd|user
    CODE = 0 忽略 CODE = 0 OR CODE = 5
    CODE = 0 OR CODE = 5 CODE = 2 忽略 忽略
    28 CODE:code:cd|{9}
    CODE = 0
    忽略 CODE = 0 OR CODE = 9
    CODE = 0 OR CODE = 9 CODE = 2 OR CODE = 9 CODE = 9 CODE = 9
    29 CODE:code+:${9} http参数值实际应该是密文 CODE = 9 CODE = 9 CODE = 9
    CODE = 9 CODE = 9 CODE = 0 CODE = 9
    30 CODE:code+:cd:${9}code需要密文,cd需要明文 CODE = 9 CODE = 9 CODE = 2
    CODE = 2 CODE = 2 CODE = 0 CODE = 9
    31 CODE:code+:cd+ 忽略
    忽略
    忽略
    忽略
    忽略
    CODE = 0 CODE = 2
    32 CODE:code|CODE:cd|CD:cd|CD:code CODE = 0 OR CD = 0 忽略 CODE =0 OR CODE = 2 OR ID =0 OR ID = 2
    CODE =0 OR CODE = 2 OR ID =0 OR ID = 2 CODE =2 OR CD =2 忽略 忽略
    33 CODE:code:${9}|CD:cd:${9} CODE = 0 OR CD = 9 CODE = 9 OR CD = 9 CODE = 0 OR CD = 2
    CODE = 0 OR CD = 2 CODE = 9 OR CD = 2 CODE = 9 OR CD = 9 CODE = 9 OR CD = 9

    以上SQL在实际运行中以占位符?生成,类似CODE > '0'的条件实际是CODE > ?,java中通过 preapreStatement赋值,最终执行结果与数据类型有

    忽略:表示合成SQL时不拼接当前查询条件

    不执行:表示整个SQL不执行,querys返回长度为0的DataSet,query返回null

    "+"开头表示必须条件,如果没有值传则生成CODE IS NULL的条件(仅"="时有效,其他IN,>时,当前条件忽略)

    “++”开头时,如果没有传值则整个SQL不执行,返回长度为零的DataSet

  • 常规数据库操作

    AnyLine提供了一对基础的service/dao。通过接收上一步约定好格式的参数,只需要在项目中注入AnylineService即可完成绝大部分的数据库操作。(AnylineService已通过@Service("anyline.service")的形式注册到Spring上下文中)
    在实际开发过程中,通常是用项目的BaseController继承tAnylineController(适用于springmvc框架,如果是Struts2框架则继承AnylineAction)
    AnylineController中已经注入AnylineService serive,并重载了大量condition函数。
     

    Controller层操作过程大致如下:

    DataSet set = service.querys("HR_USER(ID,NM)"
    	, condition(true,"TYPE_CODE:[type]","NM:nm%","+ZIP_CODE:zip:","++DEPT_CODE:dept","POST_CODE:post:pt:{101}")
    	, "IS_PUB:1");

    实现功能:
        根据TYPE_CODE,NM,IS_PUB列查询HR_USER表,并根据http参数自动分页
    生成的SQL(以mysql为例):

    SELECT 
    	ID,NM
    FROM HR_USER  
    WHERE 
    	TYPE_CODE IN (?,?,?)  
    	AND NM LIKE CONCAT(?,'%')
    	AND ZIP_CODE = ?
    	AND DEPT_CODE = ?
    	AND POST_CODE = ?
    	AND IS_PUB = ?
    LIMIT 0,10

    以SQL根据http参数传递情况动态生成,如果http/rpc中没有相关的参数则相应的查询条件不生成。
    IS_PUB值不是来自http
    TYPE_CODE IN(?,?,?)中的占位符数量根据http中type参数数量生成
    如果http中没有提供zip则生成ZIP_CODE IS NULL的查询条件
    如果http中没有提供dept则整个SQL将不执行,当前querys函数返回长度为0的DataSet
    如果http中没有提供post,则取根据pt取值,如果没有提供pt,则使用默认值101,其中的{}表示常量,而不是http中的参数key
    注意IS_PUB的值是一个固定值1,也不是通过http参数中取值,所以不需要放在condition函数中转换

相关分类 其他文档