一种面向对象的Java Bean查询方法的实现

目前正在赶一个.NET项目,考虑持久层查询的封装尽量做到面向对象,看了一下这篇文章,觉得作者思路不错,故想拿来重构成.NET版本。

摘 要:为了克服在Java Bean方法中编写许多SQL语句实现数据查询的缺点,通过查询条件进行了对象化的封装,提出了一种针对Java Bean的面向对象的查询方法. 通过设置查询条件对象,使用文中所提出的查询方法能方便地实现不同条件的数据查询,可以有效地提高系统的开发效率.关键词:反射机制;持久化; Java Bean

基于Java的数据库应用开发一般采用将JDBC封装到不同的Java Bean中,实现数据库表到业务对象映射,通过调用这些Java Bean以完成对数据库访问. [ 1, 2 ]这种设计方式的主要缺陷,一是增加了工作的重复性,间接增加了开发工作量;二是修改和维护工作量大. 利用Java的反射和标注机制, [ 3 ]笔者提出了一种针对Java Bean持久化的支持类(Persister). 本文主要阐述Persister类的面向对象查询方法的设计与实现.1 持久化支持类针对同时要封装数据库表和操作方法而造成Java Bean设计复杂的问题,将业务数据的新增、修改、删除、加载以及查询等持久化方法从Java Bean中剥离,改由持久化类( Persister)完成, Java Bean主要负责对数据库表的封装和对数据合法性的验证,从而降低了Java Bean的实现复杂度. Persister类对传入的JavaBean的实例对象bean Instance,利用反射机制对其字段名和字段值进行动态访问,并生成相应的SQL 语句,通过执行SQL语句完成对数据库表的查询或更新操作,实现对Java Bean持久化操作的支持. Persister类的主要字段属性和方法定义如下.

2 查询条件类的设计将由字段( field) 、关系运算符(operator) 、查询值( value)直接确定的查询条件定义为单项条件表达式. 通过对单项条件表达式进行与、或、非三种方式组合可得到复杂的复合条件表达式. 由于数据库字段的值域都是有限的,对于“非”运算总可找到它相应的值域,从而可将“非”运算用“不等于”进行等价处理.因此,对于条件组合方式只考虑逻辑“与”和逻辑“或”两种方式. 为了能使用更简便的表达方式来定义查询条件,可对单项条件表达式和条件组合方式进行对象化封装,实现一种面向对象的数据查询方式.(1) 单项条件表达式类. 按关系运算符的不同共分10种:Equal类     对应SQL中的“field = value”表达式NotEqual类对应SQL中的“field < > value”表达式GreaterThan类对应SQL中的“field > value”表达式LessThan类对应SQL中的“field < value”表达式GreaterEqual类对应SQL中的“field > = value”表达式LessEqua类对应SQL中的“field < = value”表达式IsNull类对应SQL中的“field isNull”表达式IsNotNull类对应SQL中的“field is notNull”表达式L ike类对应SQL中的“field like value”表达式NotL ike类对应SQL中的“field not like value”表达式(2) 条件组合方式类. 包含“与(And) ”和“或(OR) ”两个对象类. 负责封装单项条件表达式或复合条件表达式进行组合以实现更复杂的复合条件表达式.基于(1) 、(2) ,容易实现对诸如InL ist(在??中) 、Between (在??之间)等查询条件表达式的描述.单项条件表达式类与条件组合方式类的共同特点是封装查询条件表达式,并能产生对应的SQL where子句. 为统一SQL where子句的生成操作接口,引入查询条件接口类Condition:public interface Condition { public void generateSql( StringBuffer sbSql, List values) ; }Condition接口类的唯一方法generateSql根据对象所封装的查询条件表达式,生成对应的带占位符的SQL where子句并附加在传入参数( SQL 语句) sbSql之后. 同时将封装的查询值添加到对应的参数列表values中. 要求所有单项条件表达式类与条件组合方式类均实现Condition接口类. 以下仅以L ike类和And类为例说明.2. 1 单项条件表达式类L ike用于封装“field like value”字符串匹配条件,并生成对应的带L ike条件子句.

2. 2 条件组合方式类And用于封装对单项条件或复合条件表达式按“与”逻辑进行组合而得到更复杂的复合条件表达式,并生成“( ?and ?) ”格式的where子句,其中“?”表示任一单项条件或复合条件表达式. 定义如下:

2. 3 结果集排序类OrderOrder类封装查询结果集的排序规则,支持多属性升降序的组合排序方式,调用generateSql生成“order by ?”格式的SQL排序子句.

2. 4 查询容器类Cond itionHolderConditionHolder本身只是一个查询容器, 具体的查询条件要通过setCondition 方法添加到ConditionHolder实例中,并利用setCondition方法指定结果集排序规则. 调用generateSql生成where和orderby子句并附加在传入参数( SQL语句) sbSql之后,并将查询值添加到参数列表values中.

3 通用查询方法query的实现通过解析ConditionHolder对象中所封装的查询条件,生成对应的where和order by子句. 最终执行类似“select 3 from?where?order by ?”的sql语句,获得结果集之后通过读取结果集元数据(Metadata ofResultSet)进行逆向的自动生成Java Bean过程,最终得到符合条件的Java Bean对象列表. 为了避免生成赋值语句时针对不同类型的字段要采取不同的处理方式而带来的实现复杂性,通过将字段值存入查询数组values中,利用PreparedStatement接口对象的setObject方法(自动进行类型转换)为各参数赋值. 由于字

段属性为p rivate (对外是不可访问) ,对其赋值前应调用setAccessible ( ture)方法设置字段属性为可访问. [ 4, 5 ]本文假定Java Bean的属性与其封装的数据库表字段同名.

4 应用实例以表1所给出的数据库表t_book为例,其对应的Java Bean定义如下:表1 t_book的表结构设计字段名字段类型主键book Id VarChar (20) Ytitle VarChar (50)amount Numeric (6, 0)p rice Numeric (6, 2)? ?import Id; / / 引用包含ID_annotation定义的类包import Table; / / 引用包含Table_annotation定义的类包@ Id ( { ” book Id ” } ) / / 标注数据库表的主键字段名@Table ( { ” t_book” } ) / / 标注数据库表名

通过对查询条件进行了对象化的封装,用户不必再拼接SQL查询字符串,而是使用设置查询条件对象来定义查询条件,对查询操作变得更自然和方便. Hibernate、Top link等开源框架虽然也提供了类似功能,但都比较复杂且需要外部配置文件,因此本文的查询方法更合适于中小型项目的开发.

即使爬到最高的山上,一次也只能脚踏实地地迈一步。

一种面向对象的Java Bean查询方法的实现

相关文章:

你感兴趣的文章:

标签云: