CN111259042B - 一种动态查询方法及系统 - Google Patents

一种动态查询方法及系统 Download PDF

Info

Publication number
CN111259042B
CN111259042B CN202010017244.6A CN202010017244A CN111259042B CN 111259042 B CN111259042 B CN 111259042B CN 202010017244 A CN202010017244 A CN 202010017244A CN 111259042 B CN111259042 B CN 111259042B
Authority
CN
China
Prior art keywords
dynamic
sql
parameter
variable
class
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Active
Application number
CN202010017244.6A
Other languages
English (en)
Other versions
CN111259042A (zh
Inventor
蔡志聪
丘斌
江智明
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
XIAMEN ZHIYE SOFTWARE ENGINEERING CO LTD
Original Assignee
XIAMEN ZHIYE SOFTWARE ENGINEERING CO LTD
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by XIAMEN ZHIYE SOFTWARE ENGINEERING CO LTD filed Critical XIAMEN ZHIYE SOFTWARE ENGINEERING CO LTD
Priority to CN202010017244.6A priority Critical patent/CN111259042B/zh
Publication of CN111259042A publication Critical patent/CN111259042A/zh
Application granted granted Critical
Publication of CN111259042B publication Critical patent/CN111259042B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/20Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
    • G06F16/24Querying
    • G06F16/242Query formulation
    • G06F16/2433Query languages
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F16/00Information retrieval; Database structures therefor; File system structures therefor
    • G06F16/20Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
    • G06F16/24Querying
    • G06F16/245Query processing
    • G06F16/2453Query optimisation

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Physics & Mathematics (AREA)
  • Computational Linguistics (AREA)
  • Data Mining & Analysis (AREA)
  • Databases & Information Systems (AREA)
  • General Engineering & Computer Science (AREA)
  • General Physics & Mathematics (AREA)
  • Mathematical Physics (AREA)
  • Information Retrieval, Db Structures And Fs Structures Therefor (AREA)

Abstract

本发明涉及软件开发技术领域,具体地说,涉及一种动态查询方法及系统。其方法包括如下步骤:动态SQL配置,MyBatis 3基于OGNL表达式通过在Mapper.xml中使用if、choose、trim、foreach动态SQL元素来编写包含逻辑判断的SQL语句;Groovy动态脚本配置,基于Groovy实现动态脚本执行工具类,进行动态脚本的执行并返回查询结果;Groovy、SQL脚本执行引擎;返回结果。该动态查询方法及系统,目的是避免编写重复性接口,通过配置的方式增加开发的灵活度,提高开发效率,缩短开发时间。大部分需求都可以系统在线直接配置处理,省去功能开发及系统发布操作。

Description

一种动态查询方法及系统
技术领域
本发明涉及软件开发技术领域,具体地说,涉及一种动态查询方法及系统。
背景技术
在中小平台系统中存在很多需要进行数据查询和 Excel 导出的功能,客户需求多而且变化快。之前的做法是将相关的查询 SQL 语句放到数据库中进行存储,然后编写相关接口, 调用配置在数据库中的 SQL 语句执行后返回执行结果。按之前做法,在客户提出新的需求时,需要先配置 SQL 语句,再编写接口,最后调用接口返回数据,这样无法快速响应客户需求,涉及后端代码更新的还需要重新发布系统,较为繁琐。
发明内容
本发明的目的在于提供一种动态查询方法及系统,以解决上述背景技术中提出的问题。
为实现上述技术问题的解决,本发明的目的之一在于,提供一种动态查询方法,其方
法包括如下步骤:
S1、动态 SQL 配置,MyBatis 3 基于 OGNL 表达式通过在 Mapper.xml 中使用if、choose、 trim、foreach 动态 SQL 元素来编写包含逻辑判断的 SQL 语句,在执行过程中可根据用户提供的参数,动态决定最终执行的 SQL 语句;解决了手动拼接 SQL 语句麻烦且容易出错的问题;
S2、Groovy 动态脚本配置,基于 Groovy 实现动态脚本执行工具类(GroovyExecutor),使用复合 SQL 语句配置中 script 节点的内容和相关参数输入到GroovyExecutor 的evaluate 方法,进行动态脚本的执行并返回查询结果,GroovyExecutor 的类图如图 3 所示,可以跟 Spring 无缝集成,可直接调用相关的Spring Bean;
S3、Groovy、SQL 脚本执行引擎;
S4、返回结果;
所述 S1 中,动态 SQL 配置的方法包括如下步骤:
S1.1、动态 SQL 注册,将动态 SQL 语句注册到 MyBatis 的配置对象。目前有 1个接口
SqlConfig , 1 个基类 SqlConfigBase 和 2 个具体的实现类SimpleSqlConfig 、
ComplexSqlConfig 模块类图关系如图 1 所示;
S1.2、动态 SQL 执行,动态 SQL 执行类集成了动态 SQL 注册类(SqlConfig),对外提供了 executeSelectList、executeSelect、executeSelectPage 3 个 SQL 语句执行方法,动态 SQL 执行类(SqlExecutor)根据传入的 xmlType 参数来创建哪个动态 SQL注册类(SqlConfig);类图关系如图 2 所示。
所述 S1.1 中,动态 SQL 注册的方法包括如下步骤:
S1.1.1、SqlConfigBase 类构造函数,构造函数包含 2 个参数,分别是: 参数1,字符串变量 xmlId,该参数为动态 SQL 的 xml 配置的唯一 id; 参数 2,字符串变量xmlContent,该参数为动态 SQL 的文本内容; S1.1.2、getXmlId 方法返回私有字段xmlId 的值;
S1.1.3、getXmlContent 方法返回私有字段 xmlContent 的值;
S1.1.4、getSelectId 方法返回私有字段 namespace 的值拼接上点号“.”和方法入参字符串变量 id 的值;
S1.1.5、执行 parseDocument 方法;
S1.1.6、执行 registerXml 方法实现注册动态 SQL 语句。
SimpleSqlConfig 实现类主要实现了单条 SQL 语句注册。单条 SQL 语句的示例如图 4
所示,SimpleSqlConfig 类说明如下:
SimpleSqlConfig 覆写了父类方法 getXmlContent,将传入的 SQL 语句内容包装成 MyBatis Xml Mapper 的格式,使用 mapper 根元素及 select 子节点包裹getXmlContent 方法的返回值(单条 SQL 语句的内容),并将 select 的 id 属性设置为方法 getXmlId 的值。
ComplexSqlConfig 实现类主要实现了复合 SQL 语句注册,一般包含一条及以上的动态
SQL 配置和一个包含业务逻辑的 script 节点,script 的内容使用 groovy 脚本编写。在script 节点中直接调用动态 SQL 执行类的实体对象 sqlExecutor 执行复合配置中的动态SQL 语句,最终得出需要的返回结果。复合 SQL 语句的示例如图 5 所示:
ComplexSqlConfig 类说明如下:
1) 、覆写父类方法 parseDocument,具体步骤如下:
a、调用父类的 parseDocument 方法返回 Document 赋值到变量 document;
b、调用 document 的 getRootElement 方法获取文档的根元素对象,赋值给Element
类型的变量 rootElement;
c、ootElement 的 selectSingleNode 方法并传入参数/mapper/script,返回当调用 r
前根元素对象下的 script 子节点到 Node 类型的变量 scriptNode;
d、判断 scriptNode 是否为 null,如果是则抛出运行时异常:缺少 script 节点;
e、调用 rootElement 的 remove 方法并传入参数 scriptNode,移除 script节点;
f、将 scriptNode 变量强制转换为 Element 类型并调用 getTextTrim 方法获取配置的
groovy 脚本内容并赋值给类中的私有字符串变量 scriptContent; g、返回方法中的变量 document;
、getScriptContent 方法返回私有字段 scriptContent 的值;
所述 S1.1.6 中,执行 registerXml 方法实现注册动态 SQL 语句的步骤如下:
S1.1.6.1、将字符串变量 xml 赋值为配置单条 SQL 语句或者复合 SQL 语句的xml 文本;
S1.1.6.2、将字符串变量 namespace 赋值为 SqlConfigBase 的类名和 SQL 语句配置的唯一 ID 进行字符串拼接作为当前 xml 配置的命名空间;
S1.1.6.3 、 将 字 节 数 组 输 入 流 对 象 ( ByteArrayInputStream ) 变量byteArrayInputStream 赋值为 S1.1.6.1 的 xml 变量的 UTF8 编码字节数组,作为参数传入java 的字节数组输入流对象(ByteArrayInputStream)的实例化对象;
S1.1.6.4 、将 Configuration 类型变 量 configuration 赋值为 MyBatis 的
Configuration 实例对象;
S1.1.6.5、调用 configuration 变量的 isResourceLoaded 方法,传入参数为S1.1.6.2 的 namespace,判断是否已经加载过当前 xml 文本,如果已经加载过当前 xml文本,则获取 configuration 的 loadedResources 变量,并使用 namespace 参数调用其remove 方法进行删除,以便重新注册 xml;
S1.1.6.6、使用 byteArrayInputStream, configuration,namespace 参数实例化
MyBatis 的 XMLMapperBuilder 对象,赋值给变量 mapperBuilder;
S1.1.6.7、调用 S1.1.6.6 的 mapperBuilder 变量的 parse 方法解析当前xml,完成SQL 语句的注册工作。
作为优选,所述 S1.1.1 中,构造函数的执行操作包括如下步骤: S1.1.1.1、将参数 xmlId 赋值给私有字段 xmlId;
S1.1.1.2、将参数 xmlContent 赋值给私有字段 xmlContent;
S1.1.1.3、将当前类全名拼接上点号“.”和xmlId 参数,并赋值给私有字段namespace,作为当前动态 SQL 配置类的命名空间;
S1.1.1.4、调用当前类的 parseDocument 方法进行 xml 的内容解析操作。作为优选,所述 S1.1.5 中,执行 parseDocument 方法的步骤如下:
S1.1.5.1、使用 java 类库 dom4j 的 DocumentHelper 类的 parseText 方法,将getXmlContent 方法的返回值作为入参传入,进行 xml 文档解析操作,返回 xml 文档的Document 对象 document;
S1.1.5.2、判断 document 的 getDocType 方法的返回值是否为 null,如果是则为document 添加 MyBatis XML Mapper 的 docType;
S1.1.5.3、调用 document 的 getRootElement 方法获取文档的根元素对象,赋值给
Element 类型的变量 rootElement;
S1.1.5.4、调用 rootElement 变量的 addAttribute 方法设置根元素的namespace 属性为当前类的私有字段 namespace;
S1.1.5.5、调用 rootElement 的 selectNodes 方法并传入参数/mapper/select,返回当前根元素对象下的 select 子节点到 List 类型的变量 selectNodes;
S1.1.5.6、使用 for 循环 selectNodes,判断迭代对象的 resultType 属性值是否为空,如果为空则设置为 map;
S1.1.5.7、返回方法中的变量 document。
作为优选,所述 S1.2 中,动态 SQL 执行的方法包括第一个executeSelect 方法和
第二个executeSelect 方法:
所述 第一个executeSelect 方法(只有一个 Map<String, Object>类型的入参params)执行方法:调用 executeSelect 方法,传入参数:sqlConfig 对象的 getXmlId 方法作为 selectId参数,当前方法的入参 params 作为第二个参数;
所述 第二个executeSelect 方法(包含一个字符串类型的入参 selectId 和一个Map<String,Object>类型的入参 params)执行内容说明:调用 MyBatis 的SqlSessionUtils工具类的 getSqlSession 方法并传入参数 sqlSessionFactory,将返回的 SqlSession 对象赋值给方法内的临时变量 sqlSession;使用 try·finally 包裹代码,try 块中执行sqlSession 的 selectList 方法,其中调用 sqlConfig 类变量的getSelectId 方法并入参selectId 的返回结果作为 selectList 的第一个参数,方法入参 params 作为 selectList 的第二个参数,最后将 selectList 执行后方法的 List 对象作为本方法的返回值,finally 块中执行调用 SqlSessionUtils 工具类的closeSqlSession 方法并传入参数 sqlSession 和 sqlSessionFactory 以关闭 MyBatis的 session 连接释放连接资源。
动态 SQL 执行的 SqlExecutor 类说明如下: 类构造函数包含 3 个参数,分别是:
参数 1,字符串变量 xmlId,该参数为动态 SQL 的 xml 配置的唯一 id;
参数 2,字符串变量 xmlType,该参数为动态 SQL 的类型,有 2 个可选值,“1”表示单条 SQL 语句,“2”表示复合 SQL 语句;
参数 3,字符串变量 xmlContent,该参数为动态 SQL 的文本内容。构造函数执行的操作如下步骤:
a、判断字符串“1”是否等于 xmlType,如果是则使用 xmlId 和 xmlContent 参数初始化 SimpleSqlConfig 对象并赋值给类的 SqlConfig 类型的私有字段 sqlConfig;
b、判断字符串“2”是否等于 xmlType,如果是则使用 xmlId 和 xmlContent 参数初始化 ComplexSqlConfig 对象并赋值给类的 SqlConfig 类型的私有字段sqlConfig;
c、如果 xmlType 为其他值,则抛出运行时异常:无效的参数:xmlType;
d、调用类变量 sqlConfig 的 registerXml 方法完成动态 SQL 语句注册到MyBatis 的操作;
e、调用获取 Spring Bean 实例的工具类 BeanFactory 的 getBean 方法获取MyBatis 的 SqlSessionFactory 类型实例并赋值给类的 SqlSessionFactory 类型私有字段sqlSessionFactory。
本发明的目的之二在于,提供一种动态查询系统,包括:
动态 SQL 配置模块,用于根据用户提供的参数,动态决定最终执行的 SQL 语句;
Groovy 动态脚本配置模块,用于基于 Groovy 实现动态脚本执行工具类
(GroovyExecutor);
脚本执行模块,用于 Groovy、SQL 脚本的执行。
本发明的目的之三在于,提供一种动态查询装置,包括处理器、存储器以及存储在所述存储器中并在所述处理器上运行的计算机程序,所述处理器执行上述的计算机程序时实现如上述中任一所述的动态查询方法的步骤。
本发明的目的之四在于,一种计算机可读存储介质,所述存储介质中存储有至少一段程序,所述至少一段程序由上述的处理器执行以实现如上述中任一所述的动态查询方法的步骤。
与现有技术相比,本发明的有益效果:
1、该动态查询方法及系统中,通过动态 SQL 注册模块实现 SQL 语句的动态注册,并可将配置内容持久化到数据库中,实现自由修改。
2、该动态查询方法及系统中,动态 SQL 执行类实现对已注册的动态 SQL 的执行功能;
3、通过引入 Groovy 动态语言,动态执行复合 SQL 配置中的脚本内容,提高业务逻辑的可定制性。
附图说明
图 1 为本发明的动态 SQL 注册模块类图;
图 2 为本发明的 SqlExecutor 与 SqlConfig 的聚合关系图;
图 3 为本发明的 GroovyExecutor 的类图;
图 4 为本发明的单条 SQL 语句的示例图; 图 5 为本发明的复合 SQL 语句的示例图; 图 6 为本发明的动态查询装置结构示意图。
具体实施方式
下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
请参阅图 1-图 6 所示,本发明提供一种技术方案:
本发明提供一种动态查询方法,其方法包括如下步骤:
S1、动态 SQL 配置,MyBatis 3 基于 OGNL 表达式通过在 Mapper.xml 中使用if、choose、 trim、foreach 动态 SQL 元素来编写包含逻辑判断的 SQL 语句,在执行过程中可根据用户提供的参数,动态决定最终执行的 SQL 语句;解决了手动拼接 SQL 语句麻烦且容易出错的问题;
S2、Groovy 动态脚本配置,基于 Groovy 实现动态脚本执行工具类(GroovyExecutor),使用复合 SQL 语句配置中 script 节点的内容和相关参数输入到GroovyExecutor 的evaluate 方法,进行动态脚本的执行并返回查询结果,GroovyExecutor 的类图如图 3 所示,可以跟 Spring 无缝集成,可直接调用相关的Spring Bean;
S3、Groovy、SQL 脚本执行引擎;
S4、返回结果。
本实施例中,S1 中,动态 SQL 配置的方法包括如下步骤:
S1.1、动态 SQL 注册,将动态 SQL 语句注册到 MyBatis 的配置对象。目前有 1个接口SqlConfig , 1 个基类 SqlConfigBase 和 2 个具体的实现类 SimpleSqlConfig、ComplexSqlConfig 模块类图关系如图 1 所示;
S1.2、动态 SQL 执行,动态 SQL 执行类集成了动态 SQL 注册类(SqlConfig),对外提供了 executeSelectList、executeSelect、executeSelectPage 3 个 SQL 语句执行方法,动态 SQL 执行类(SqlExecutor)根据传入的 xmlType 参数来创建哪个动态 SQL 注册类(SqlConfig);类图关系如图 2 所示。
进一步的,S1.1 中,动态 SQL 注册的方法包括如下步骤:
S1.1.1、SqlConfigBase 类构造函数,构造函数包含 2 个参数,分别是: 参数1,字符串变量 xmlId,该参数为动态 SQL 的 xml 配置的唯一 id; 参数 2,字符串变量xmlContent,该参数为动态 SQL 的文本内容; S1.1.2、getXmlId 方法返回私有字段xmlId 的值;
S1.1.3、getXmlContent 方法返回私有字段 xmlContent 的值;
S1.1.4、getSelectId 方法返回私有字段 namespace 的值拼接上点号“.”和方法入参字符串变量 id 的值;
S1.1.5、执行 parseDocument 方法;
S1.1.6、执行 registerXml 方法实现注册动态 SQL 语句。
本实施例中,SimpleSqlConfig 实现类主要实现了单条 SQL 语句注册。单条SQL 语句的示例如图 4 所示,SimpleSqlConfig 类说明如下:
其中,SimpleSqlConfig 覆写了父类方法 getXmlContent,将传入的 SQL 语句内容包装成 MyBatis Xml Mapper 的格式,使用 mapper 根元素及 select 子节点包裹getXmlContent 方法的返回值(单条 SQL 语句的内容),并将 select 的 id 属性设置为方法 getXmlId 的值。
此外,ComplexSqlConfig 实现类主要实现了复合 SQL 语句注册,一般包含一条及以上的动态SQL 配置和一个包含业务逻辑的script 节点,script 的内容使用groovy脚本编写。
在 script 节点中直接调用动态 SQL 执行类的实体对象 sqlExecutor 执行复合配置中的动态 SQL 语句,最终得出需要的返回结果。复合 SQL 语句的示例如图 5 所示:
除此之外,ComplexSqlConfig 类说明如下:
1) 、覆写父类方法 parseDocument,具体步骤如下:
a、调用父类的 parseDocument 方法返回 Document 赋值到变量 document;
b、调用 document 的 getRootElement 方法获取文档的根元素对象,赋值给Element
类型的变量 rootElement;
c、ootElement 的 selectSingleNode 方法并传入参数/mapper/script,返回当调用 r
前根元素对象下的 script 子节点到 Node 类型的变量 scriptNode;
d、判断 scriptNode 是否为 null,如果是则抛出运行时异常:缺少 script 节点;
e、调用 rootElement 的 remove 方法并传入参数 scriptNode,移除 script节点;
f、将 scriptNode 变量强制转换为 Element 类型并调用 getTextTrim 方法获取配置的
groovy 脚本内容并赋值给类中的私有字符串变量 scriptContent; g、返回方法中的变量 document;
2) 、getScriptContent 方法返回私有字段 scriptContent 的值。具体的,S1.1.1 中,构造函数的执行操作包括如下步骤: S1.1.1.1、将参数 xmlId 赋值给私有字段 xmlId;
S1.1.1.2、将参数 xmlContent 赋值给私有字段 xmlContent;
S1.1.1.3、将当前类全名拼接上点号“.”和xmlId 参数,并赋值给私有字段namespace,作为当前动态 SQL 配置类的命名空间;
S1.1.1.4、调用当前类的 parseDocument 方法进行 xml 的内容解析操作。再进一步的,S1.1.5 中,执行 parseDocument 方法的步骤如下:
S1.1.5.1、使用 java 类库 dom4j 的 DocumentHelper 类的 parseText 方法,将getXmlContent 方法的返回值作为入参传入,进行 xml 文档解析操作,返回 xml 文档的Document 对象 document;
S1.1.5.2、判断 document 的 getDocType 方法的返回值是否为 null,如果是则为document 添加 MyBatis XML Mapper 的 docType;
S1.1.5.3、调用 document 的 getRootElement 方法获取文档的根元素对象,赋值给Element 类型的变量 rootElement;
S1.1.5.4、调用 rootElement 变量的 addAttribute 方法设置根元素的namespace 属性为当前类的私有字段 namespace;
S1.1.5.5、调用 rootElement 的 selectNodes 方法并传入参数/mapper/select,返回当前根元素对象下的 select 子节点到 List 类型的变量 selectNodes;
S1.1.5.6、使用 for 循环 selectNodes,判断迭代对象的 resultType 属性值是否为空,如果为空则设置为 map;
S1.1.5.7、返回方法中的变量 document。
具体的,S1.1.6 中,执行 registerXml 方法实现注册动态 SQL 语句的步骤如下: S1.1.6.1、将字符串变量 xml 赋值为配置单条 SQL 语句或者复合 SQL 语句的 xml文本; S1.1.6.2、将字符串变量 namespace 赋值为 SqlConfigBase 的类名和 SQL 语句配置的唯一 ID 进行字符串拼接作为当前 xml 配置的命名空间;
S1.1.6.3 、 将 字 节 数 组 输 入 流 对 象 ( ByteArrayInputStream ) 变量byteArrayInputStream 赋值为 S1.1.6.1 的 xml 变量的 UTF8 编码字节数组,作为参数传入java 的字节数组输入流对象(ByteArrayInputStream)的实例化对象;
S1.1.6.4 、将 Configuration 类型变 量 configuration 赋值为 MyBatis 的Configuration 实例对象;
S1.1.6.5、调用 configuration 变量的 isResourceLoaded 方法,传入参数为S1.1.6.2 的 namespace,判断是否已经加载过当前 xml 文本,如果已经加载过当前 xml文本,则获取 configuration 的 loadedResources 变量,并使用 namespace 参数调用其remove 方法进行删除,以便重新注册 xml;
S1.1.6.6、使用 byteArrayInputStream, configuration,namespace 参数实例化
MyBatis 的 XMLMapperBuilder 对象,赋值给变量 mapperBuilder;
S1.1.6.7、调用 S1.1.6.6 的 mapperBuilder 变量的 parse 方法解析当前xml,完成SQL 语句的注册工作。
值得说明的是, S1.2 中,动态 SQL 执行的方法包括 第一个executeSelect 方法和
第二个executeSelect 方法:
第一个executeSelect 方法(只有一个 Map<String, Object>类型的入参params)执行方法: 调用 executeSelect 方法,传入参数:sqlConfig 对象的 getXmlId方法作为 selectId 参数,当前方法的入参 params 作为第二个参数;
第二个executeSelect方法 (包含一个 字符 串类型的入 参selectId和一个Map<String,Object>类型的入参 params)执行内容说明:调用 MyBatis 的 SqlSessionUtils工具类的 getSqlSession 方法并传入参数 sqlSessionFactory,将返回的 SqlSession对象赋值给方法内的临时变量 sqlSession;使用 try·finally 包裹代码,try 块中执行sqlSession 的 selectList 方法,其中调用 sqlConfig 类变量的 getSelectId 方法并入参selectId 的返回结果作为 selectList 的第一个参数,方法入参 params 作为selectList 的第二个参数,最后将 selectList 执行后方法的 List 对象作为本方法的返回值,finally 块中执行调用 SqlSessionUtils 工具类的 closeSqlSession 方法并传入参数 sqlSession 和 sqlSessionFactory 以关闭 MyBatis 的 session 连接释放连接资源。
具体的,动态 SQL 执行的 SqlExecutor 类说明如下: 类构造函数包含 3 个参数,分别是:
参数 1,字符串变量 xmlId,该参数为动态 SQL 的 xml 配置的唯一 id;
参数 2,字符串变量 xmlType,该参数为动态 SQL 的类型,有 2 个可选值,“1”表示单条 SQL 语句,“2”表示复合 SQL 语句;
参数 3,字符串变量 xmlContent,该参数为动态 SQL 的文本内容。值得说明的是,构造函数执行的操作如下步骤:
a、判断字符串“1”是否等于 xmlType,如果是则使用 xmlId 和 xmlContent 参数初始
化 SimpleSqlConfig 对象并赋值给类的 SqlConfig 类型的私有字段sqlConfig;
b、判断字符串“2”是否等于 xmlType,如果是则使用 xmlId 和 xmlContent 参数初始化 ComplexSqlConfig 对象并赋值给类的 SqlConfig 类型的私有字段sqlConfig;
c、如果 xmlType 为其他值,则抛出运行时异常:无效的参数:xmlType;
d、调用类变量 sqlConfig 的 registerXml 方法完成动态 SQL 语句注册到MyBatis 的操作;
e、调用获取 Spring Bean 实例的工具类 BeanFactory 的 getBean 方法获取MyBatis 的 SqlSessionFactory 类型实例并赋值给类的 SqlSessionFactory 类型私有字段sqlSessionFactory。
具体的,S2 中,Groovy 动态脚本配置的方法如下:
S2.1、setVariable 方法,调用 binding 对象的 setVariable 方法用来设置脚本所需的变量;
S2.2、removeVariable 方法,调用 binding 对象的 getVariables 方法返回值的 remove
方法用来移除脚本变量;
S2.3、第一个 evaluate 方法只包含一个字符串类型的入参 expression,执行内容为调用第二个 evaluate 方法,并传入 expression 和 null 作为参数,表示没有需要外部传入的变量;
S2.4 、第二个 evaluate 方法包含一个字符串类型的入参 expression 和一个
Map<String, Object>类型的变量列表入参 variables。其中,GroovyExecutor类说明如下:
类中包含 3 个私有类型的变量,分别是:
SCRIPTS 变量为 ConcurrentHashMap 的实例,用来存储已经被 groovy 解析过的基本;
binding 变量为 groovy 的 Binding 对象实例;
SHELL 变量为 groovy 的 GroovyShell 实例,使用 binding 作为入参,用来执行基本。值得说明的是,S2.4 中,变量列表入参 variables 的方法包括如下步骤:
S2.4.1、初始化方法内部 groovy Script 类型变量 script,用来存储 groovy解析后的脚本对象;
S2.4.2、调用 SCRIPTS 的 containsKey 方法判断入参 expression 是否被解析过。如果是,则从SCRIPTS 的get 方法传入expression 获取解析后的Script 对象并赋值给script 变量。如果否,则调用 SHELL 对象的 parse 方法并传入 expression 进行脚本解析,并将解析后的结果 Script 对象赋值给 script 变量,同时调用 SCRIPTS 的 put方法传入expression 和 script 进行缓存操作;
S2.4.3、判断入参 variables 是否不为 null,如果是则使用 for 循环variables 的entrySet,在循环体内调用 script 的 setProperty 方法将 variables 的entry 对象的 key 和 value 作为第一和第二个参数传入,进行 groovy 脚本执行变量设置;
S2.4.4、调用 script 的 run 方法进行脚本执行,并将执行结果作为返回值。本发明的目的之二在于,提供一种动态查询系统,包括:
动态 SQL 配置模块,用于根据用户提供的参数,动态决定最终执行的 SQL 语句;
Groovy 动态脚本配置模块,用于基于 Groovy 实现动态脚本执行工具类
(GroovyExecutor);
脚本执行模块,用于 Groovy、SQL 脚本的执行。
需要说明的是,动态 SQL 配置模块、Groovy 动态脚本配置模块、脚本执行模块的功能具体参见各模块对应的方法部分的描述,这里就不再赘述。
参阅图 6,示出了本发明实施例所涉及的一种动态查询装置结构示意图,该装置包括处理器、存储器和总线。
处理器包括一个或一个以上处理核心,处理器通过总线与处理器相连,存储器用于存储程序指令,处理器执行存储器中的程序指令时实现上述的动态查询方法。
可选的,存储器可以由任何类型的易失性或非易失性存储设备或者它们的组合实现, 如静态随时存取存储器(SRAM),电可擦除可编程只读存储器(EEPROM),可擦除可编程只读存储器(EPROM),可编程只读存储器(PROM),只读存储器(ROM),磁存储器,快闪存储器,磁盘或光盘。
此外,本发明还提供一种计算机可读存储介质,存储介质中存储有至少一段程序,至少一段程序由上述的处理器执行以实现如上述中任一的动态查询方法的步骤。
可选的,本发明还提供了一种包含指令的计算机程序产品,当其在计算机上运行时, 使得计算机执行上述各方面动态查询方法的步骤。
本领域普通技术人员可以理解实现上述实施例的全部或部分步骤可以通过硬件来完成,也可以通过程序来指令相关的硬件完成,所述的程序可以存储与一种计算机可读存储介质中,上述提到的存储介质可以是只读存储器,磁盘或光盘。
以上显示和描述了本发明的基本原理、主要特征和本发明的优点。本行业的技术人员应该了解,本发明不受上述实施例的限制,上述实施例和说明书中描述的仅为本发明的优选例,并不用来限制本发明,在不脱离本发明精神和范围的前提下,本发明还会有各种变化和改进,这些变化和改进都落入要求保护的本发明范围内。本发明要求保护范围由所附的权利要求书及其等效物界定。

Claims (6)

1.一种动态查询方法,其特征在于:其方法包括如下步骤:
S1、动态SQL 配置,MyBatis 3 基于 OGNL 表达式通过在 Mapper.xml 中使用 if、choose、trim、foreach 动态 SQL 元素来编写包含逻辑判断的 SQL 语句;
S2、Groovy 动态脚本配置,基于 Groovy 实现动态脚本执行工具类,使用复合 SQL 语句配置中 script 节点的内容和相关参数输入到 GroovyExecutor 的 evaluate 方法,进行动态脚本的执行并返回查询结果;
S3、Groovy、SQL 脚本执行引擎; S4、返回结果;
所述 S1 中,动态 SQL 配置的方法包括如下步骤:
S1.1、动态 SQL 注册,将动态 SQL 语句注册到 MyBatis 的配置对象; S1.2、动态SQL 执行,动态 SQL 执行类集成了动态 SQL 注册类;
所述 S1.1 中,动态 SQL 注册的方法包括如下步骤:
S1.1.1、SqlConfigBase 类构造函数,构造函数包含 2 个参数,分别是: 参数 1,字符串变量 xmlId,该参数为动态 SQL 的xml 配置的唯一 id; 参数 2,字符串变量xmlContent,该参数为动态 SQL 的文本内容; S1.1.2、getXmlId 方法返回私有字段xmlId 的值;
S1.1.3、getXmlContent 方法返回私有字段 xmlContent 的值;
S1.1.4、getSelectId 方法返回私有字段 namespace 的值拼接上点号“.”和方法入参字符串变量 id 的值;
S1.1.5、执行 parseDocument 方法;
S1.1.6、执行 registerXml 方法实现注册动态 SQL 语句;
所述 S1.1.6 中,执行registerXml 方法实现注册动态 SQL 语句的步骤如下:S1.1.6.1、将字符串变量 xml 赋值为配置单条 SQL 语句或者复合 SQL 语句的 xml 文本; S1.1.6.2、将字符串变量 namespace 赋值为 SqlConfigBase 的类名和 SQL 语句配置的
唯一 ID 进行字符串拼接作为当前 xml 配置的命名空间;
S1.1.6.3、将字节数组输入流对象变量 byteArrayInputStream 赋值为S1.1.6.1 的xml 变量的 UTF8 编码字节数组,作为参数传入 java 的字节数组输入流对象的实例化对象;
S1.1.6.4 、 将 Configuration 类型变 量 configuration 赋值为 MyBatis 的Configuration 实例对象;
S1.1.6.5、调用 configuration 变量的 isResourceLoaded 方法,传入参数为S1.1.6.2 的 namespace,判断是否已经加载过当前 xml 文本,如果已经加载过当前 xml文本,则获取 configuration 的 loadedResources 变量,并使用 namespace 参数调用其remove 方法进行删除,以便重新注册 xml;
S1.1.6.6、使用 byteArrayInputStream, configuration,namespace参数实例化MyBatis 的 XMLMapperBuilder 对象,赋值给变量 mapperBuilder;
S1.1.6.7、调用 S1.1.6.6 的 mapperBuilder 变量的 parse 方法解析当前 xml,完成SQL 语句的注册工作。
2.根据权利要求 1 所述的动态查询方法,其特征在于:所述 S1.1.1 中,构造函数的执行操作包括如下步骤:
S1.1.1.1、将参数 xmlId 赋值给私有字段 xmlId;
S1.1.1.2、将参数 xmlContent 赋值给私有字段 xmlContent;
S1.1.1.3、将当前类全名拼接上点号“.”和xmlId 参数,并赋值给私有字段namespace, 作为当前动态 SQL 配置类的命名空间;
S1.1.1.4、调用当前类的 parseDocument 方法进行 xml 的内容解析操作。
3.根据权利要求 2 所述的动态查询方法,其特征在于:所述 S1.1.5 中,执行parseDocument 方法的步骤如下:
S1.1.5.1、使用 java 类库 dom4j 的 DocumentHelper 类的 parseText 方法,将getXmlContent 方法的返回值作为入参传入,进行 xml 文档解析操作,返回 xml 文档的Document 对象 document;
S1.1.5.2、判断 document 的 getDocType 方法的返回值是否为 null,如果是则为
document 添加 MyBatis XML Mapper 的 docType;
S1.1.5.3、调用 document 的 getRootElement 方法获取文档的根元素对象,赋值给Element 类型的变量 rootElement;
S1.1.5.4、调用 rootElement 变量的 addAttribute 方法设置根元素的 namespace属性为当前类的私有字段 namespace;
S1.1.5.5、调用 rootElement 的selectNodes 方法并传入参数/mapper/select,返回当前根元素对象下的 select 子节点到 List 类型的变量 selectNodes;
S1.1.5.6、使用for 循环 selectNodes,判断迭代对象的 resultType 属性值是否为空, 如果为空则设置为 map;
S1.1.5.7、返回方法中的变量 document。
4.根据权利要求 3所述的动态查询方法,其特征在于:所述 S1.2 中,动态 SQL 执行的方法包括第一个executeSelect 方法和第二个executeSelect 方法:
所述第一个executeSelect 方法执行方法:调用 executeSelect 方法,传入参数:sqlConfig 对象的 getXmlId 方法作为 selectId 参数,当前方法的入参 params 作为第二个参数;
所述第二个executeSelect 方法执行内容说明:调用 MyBatis 的 SqlSessionUtils工具类的getSqlSession 方法并传入参数 sqlSessionFactory,将返回的 SqlSession 对象赋值给方法内的临时变量 sqlSession ;使用 try·finally 包裹代码, try 块中执行sqlSession 的selectList 方法,其中调用 sqlConfig 类变量的 getSelectId 方法并入参selectId 的返回结果作为 selectList 的第一个参数,方法入参 params 作为selectList 的第二个参数, 最后将 selectList 执行后方法的 List 对象作为本方法的返回值, finally 块中执行调用SqlSessionUtils 工具类的 closeSqlSession 方法并传入参数 sqlSession 和sqlSessio nFacto ry 以关闭 MyBatis 的 session 连接释放连接资源。
5.一种引用权利要求4所述的动态查询方法的动态查询系统,其特征在于:包括:
动态 SQL 配置模块,用于根据用户提供的参数,动态决定最终执行的 SQL 语句;Groovy 动态脚本配置模块,用于基于 Groovy 实现动态脚本执行工具类;
脚本执行模块,用于 Groovy、SQL 脚本的执行。
6.一种动态查询装置,其特征在于:包括处理器、存储器以及存储在所述存储器中并在所述处理器上运行的计算机程序,所述处理器执行上述的计算机程序时实现如权利要求1-4中任一所述的动态查询方法的步骤。
CN202010017244.6A 2020-01-08 2020-01-08 一种动态查询方法及系统 Active CN111259042B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202010017244.6A CN111259042B (zh) 2020-01-08 2020-01-08 一种动态查询方法及系统

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202010017244.6A CN111259042B (zh) 2020-01-08 2020-01-08 一种动态查询方法及系统

Publications (2)

Publication Number Publication Date
CN111259042A CN111259042A (zh) 2020-06-09
CN111259042B true CN111259042B (zh) 2022-05-31

Family

ID=70943826

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202010017244.6A Active CN111259042B (zh) 2020-01-08 2020-01-08 一种动态查询方法及系统

Country Status (1)

Country Link
CN (1) CN111259042B (zh)

Families Citing this family (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN112307068A (zh) * 2020-11-10 2021-02-02 天元大数据信用管理有限公司 一种动态sql查询方法
CN113760877A (zh) * 2021-03-10 2021-12-07 中科天玑数据科技股份有限公司 一种基于标准sql的流式数据清洗转换方法和系统

Citations (5)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN103902743A (zh) * 2014-04-29 2014-07-02 厦门市智业软件工程有限公司 通过业务名词操控数据的自助查询方法
CN106649630A (zh) * 2016-12-07 2017-05-10 乐视控股(北京)有限公司 数据查询方法及装置
CN109213776A (zh) * 2017-06-30 2019-01-15 北京神州泰岳软件股份有限公司 一种报表展现方法和装置
CN110019433A (zh) * 2018-01-02 2019-07-16 北京神州泰岳软件股份有限公司 一种报表查询方法和装置
CN110086827A (zh) * 2019-05-14 2019-08-02 重庆商勤科技有限公司 一种sql注入校验方法、服务器以及系统

Family Cites Families (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
GB201517732D0 (en) * 2015-10-07 2015-11-18 Ibm Processing sql statement in alternating modes

Patent Citations (5)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN103902743A (zh) * 2014-04-29 2014-07-02 厦门市智业软件工程有限公司 通过业务名词操控数据的自助查询方法
CN106649630A (zh) * 2016-12-07 2017-05-10 乐视控股(北京)有限公司 数据查询方法及装置
CN109213776A (zh) * 2017-06-30 2019-01-15 北京神州泰岳软件股份有限公司 一种报表展现方法和装置
CN110019433A (zh) * 2018-01-02 2019-07-16 北京神州泰岳软件股份有限公司 一种报表查询方法和装置
CN110086827A (zh) * 2019-05-14 2019-08-02 重庆商勤科技有限公司 一种sql注入校验方法、服务器以及系统

Also Published As

Publication number Publication date
CN111259042A (zh) 2020-06-09

Similar Documents

Publication Publication Date Title
US8959106B2 (en) Class loading using java data cartridges
US7152229B2 (en) Workflow code generator
US7013458B2 (en) Method and apparatus for associating metadata attributes with program elements
US7565364B1 (en) Annotation processor discovery
US6473893B1 (en) Information objects system, method, and computer program organization
KR101099173B1 (ko) 소프트웨어 스위트를 구축하기 위한 시스템 및 방법
US20050278697A1 (en) Object type-declaration prefix syntax
US20090222794A1 (en) Unified expression and location framework
JP7394211B2 (ja) スマートコントラクトの並行実行の方法、装置、機器、及び媒体
WO2009142716A1 (en) Notificaton-based constraint set translation to imperative execution
US7818719B2 (en) Extending expression-based syntax for creating object instances
US7703077B2 (en) Programming model to detect deadlocks in concurrent programs
EP3607432B1 (en) Flow-based scoping
CN112394942A (zh) 基于云计算的分布式软件开发编译方法及软件开发平台
CN111259042B (zh) 一种动态查询方法及系统
WO2003001373A1 (en) Java rule engine framework
US20120173575A1 (en) Record Based Code Structure
US20080127128A1 (en) Type Validation for Applications Incorporating A Weakly-Typed Language
US20030149967A1 (en) Information processing method and system
US8745605B2 (en) Execution contexts with polymorphic type implementations
US10635416B2 (en) Property filtering
CN113626001A (zh) 一种基于脚本的api动态编排方法及装置
US20150046905A1 (en) Subprocess definition and visualization in bpel
US8983984B2 (en) Methods and systems for simplifying object mapping for external interfaces
US20240135210A1 (en) Replacing lambda expressions in a rete network with corresponding code classes

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
SE01 Entry into force of request for substantive examination
SE01 Entry into force of request for substantive examination
GR01 Patent grant
GR01 Patent grant