独立开发者的低代码-建立自己的JAVA程序框架(java开源低代码开发平台)
如果你长期从事信息管理系统的独立开发,可能会发现客户的需求大多以增删改查为主,除了数据表的内容不同以外其他基本相同,将共性代码封装到框架能减少重复劳动;浏览器端代码和服务器端代码交织,调式不便,效率低下,通过将浏览器端的常用组件封装为JAVA对象,做到大部份需求仅仅靠写JAVA代码就能满足,降低调式难度,提高开发效率。
一、独立开发者建议不采用流行框架的原因
JAVA程序开发框架可以降低JAVA程序开发难度,这是程序开发界的共识,因此,Hibernate、Strus、Spring等各种框架十分流行。但这些框架主要是为分工很细的大公司考虑,在灵活性、可扩展性方面考虑很多,对独立开发者来说太繁杂了。我用JAVA编写程序已有15年,但仍然没有使用这些框架,原因之一就是这些框架绕的弯太多,让人觉得头晕。
Hibernate是一个开源的Java数据库访问框架,其操作一个数据表的步骤分为5步:一是建立与数据库表中一行数据对应的JAVA Bean形式的持久化对象类(称为POJO);二是建立描述持久化对象和数据表之间映射关系的Hibernate配置文件;三是设置Hibernate本身的配置文件;四是根据配置文件初始化Hibernate会话的工厂类,进而得到Hibernate会话对象;五是由Hibernate会话对象得到持久化对象(对应于数据库表中的行),通过操作这些持久化对象,就可以操作数据库表中的数据。可见Hibernate真的很麻烦。
Strus也是这样,其Xml配置文件绕来绕去,难以维护。Spring的依赖注入,面向切面的编程,给人的感觉就象是恨不能将所有的JAVA类及其构造参数都移到xml配置文件中去。这些框架给我的感觉是功能强大但有90%的功能我用不上,配置灵活但内容全放在和JAVA程序风格大不相同的xml文件中。Java程序员为什么怕写JAVA程序而热衷于写xml,真是令人费解。
二、独立开发者如何建立自己的JAVA开发框架
由于数据分析应用的业务需求主要是数据处理和数据查询,因此我建立框架的目标是:尽可能只利用JAVA语言和SQL语言,直接实现全部数据处理业务需求。让Html、CSS、JavaScript、Xml、jsp等这些普遍认为开发JAVA应用程序必须掌握的技术离我们远些吧!虽然开发一个实用稳定的JAVA三层结构应用程序开发框架是一项难度较大的工作,但我通过先建立一个最简单的应用框架开始,在实际项目开发应用中发现大多数项目都要用到的功能,就逐步往框架中添加,保证了该框架的对象和对象的方法都是实际开发工作中最需要的,从而保证了框架的实用性;框架在长期的项目应用中,得到持续不断的改进,保证了框架的可靠性。
该框架的设计思路是:利用JAVA面向对象的特性,将Html、CSS、JavaScript、Xml等封装在框架层,由对JAVA程序开发技术了解深入的程序员进行开发完善,力求“辛苦我一个,幸福千万人”,使应用层程序员从纷繁复杂的技术细节中解脱出来,专注于用JAVA语言来实现业务需求,再加上现在流行的JAVA集成开发环境“自动代码完成“、“代码重构”等高级功能的辅助,使编写应用程序成为轻松愉快的工作。
在该框架设计过程中,为尽可能简化应用层难度,采取了一系列措施:一是以数据为中心,能从数据库获取的信息,就不需要应用层程序员来设置。一些以JAVA对象为中心的框架,往往在xml配置文件中来设置主键、非空字段、字段类型等信息,增加了程序设计难度。而本框架直接从数据库中获得数据表的主键、非空字段、字段类型等信息,自动将其用于数据输入校验,不需要写任何额外的程序。二是尽量减少完成一个功能所涉及的文件数量,尽可能做到一个应用功能对应一个JAVA程序文件。目前多数流行框架使用MVC设计模式,控制器一般由框架提供,完成一个数据应用功能还需要用JAVA做模型、用JSP作视图、如果采用O/R映射还需要建立一个JAVA实体Bean来放数据。而本框架一般在一个JAVA程序文件中完成这些工作,在单个业务需求变化时,涉及修改的程序代码集中在一个文件中,减轻了维护工作量。三是URL映射简单直接。流行框架通常存在一个配置URL和实际JAVA类对应关系的xml映射文件,浏览器请求的URL经过xml映射文件重定向后,变得对应关系不清晰了,在发现网页显示错误时,不易直接找出引发错误的JAVA程序文件。本框架URL直接和JAVA程序文件一一对应,如:在浏览器地址栏输入“http://127.0.0.1:8080/test/com.coyizz.pfc.userBean.class”后回车,如果网页出现错误,就立即知道是test应用项目下的JAVA类com.coyizz.pfc.userBean存在问题。
三、JAVA开发框架主要类介绍
(一)数据访问对象Sql和DataStore
数据应用的关键就是要查询和处理数据,直接用JAVA的JDBC数据访问接口提供的功能主要适用于底层数据操作,在应用层使用存在使用麻烦、中文字符集不能很好的处理等问题,业界推崇的DAO模式,要求应用程序应将数据库访问操作封装在一个对象中。我将常用的数据库访问分为两类:一类不涉及数据的输入和显示,相关功能封装到Sql对象中;另一类涉及数据的输入和显示,相关功能封装到DataStore对象中。DataStore对象内部也需要用Sql对象进行基本的数据处理。
Sql对象实现了Sql查询脚本的解析,以便在基本sql查询脚本基础上添加扩展查询条件,并解决了数据库访问的字符集问题。
例A:已知用户编码查询用户名称
String s = Sql.getResultString(“select name from usera where code = ‘0001’”, 1, AppConnItems.getConn());
例B:查询全部用户名称
Sql sql = new Sql(“select name from usera”);
Resultset rs = sql.getResultSet();
例C:在上例基础上限制只能查询单位代码(dwdm)为‘1010’的用户名称
sql.setLimitWhere(“swdm=’1010’”);
rs = sql.getResultSet();
DataStore仿照PowerBuilder中的DataStore对象开发了Java版的DataStore对象,实现了复杂的数据访问功能,和Hibernet等数据持久化方案比,不需要实体Bean来容纳数据,减少了JAVA类的的数量,增加了数据处理的灵活性;不需要配置xml文件,降低了开发难度,提高工作效率。能生成网页显示表格或表单所需的Html对象。除能方便地处理数字、字符、编码字段外,还能处理文件、图片、超链接等字段。
例A:查询全部用户名称和编码
DataStore ds = DataStore(“dsMain”, “select name,code,fj from usera”, AppConnItems.getConn());
ds.retrieve();
例B:取得结查询结果的第一行数据中的编码数据或原文数据
String s = ds.getItemStr(1, “code”); // 取得编码
s = ds.getItemStr(1, “code”); // 取得原文
例C:将查询结果第三行数据中的“名称”(name)字段设置“张三”并保存到数据库
ds.setItem(3, “name”, “张三”);
ds.update();
例D:取得查询结果的显示用Html表格对象
HtmlTable ht = ds.getHtmlTable();
例E:取得查询结果的行数
int rowCnt = ds.getRowCount();
例F:取得查询结果的列数
int colCnt = ds.getColCount();
例G:删除第1行
ds.deleteRow(1);
例H:在最后添加1行:
ds.insertRow(0);
例I:设置附件列(fj)为文件附件, 存放在Web应用目录的xxFj子目录下,附件最大限制为20M。
ds.setColIsFileLink("fj", "xxFj", "", 20000000, true);
例J:设置附件列(fj)为图片, 存放在Web应用目录的img子目录下,扩展名只能为jpg或gif,附件最大限制为4M,图片宽度为200,高不设置。
ds.setColIsImg(“fj”, “img”, “gif,jpg”, 4000000, 200, 0, true);
从以上例子来看,该数据访问对象和PowerBuilder的DataStore十分相象,使原来的PowerBuilder程序员能较快地转向JAVA程序的开发上来。
DataStore对象还有其他一些强大的功能:比如dsAdd方法可完成两个DataStore中的数据迭加或追加,setZzjgLimit方法可根据用户权限限制数据操作范围,通过DataStore的一些构造方法,可实现多个DataStore数据的内联或外联。SetHoldData方法可使数据在网页之间保持,validCheck方法可根据数据表的相关信息,对当前存放在DataStore对象中的数据,进行数据类型、非空、主键重复等有效性检查。GetSelectedRowsDs可取得用户在浏览器上选中的数据行,GetDeletedRowsDs可取得用户在浏览器上删除的数据行。Sort可对DataStore对象中的数据按多列进行排序,fillSumRow可对指定多列数据求和。总之,DataStore对象涵盖了数据应用开发中所需的大多数功能。
(二) HzBean对象
HzBean对象是响应浏览器请求,显示网页的主要对象。每个需要在网页上显示的对象,都要直接或间接地继承该对象,并且对象名一定要以“Bean”结尾。在浏览器端要调用HzBean对象的后代,可以十分直观地在Web应用URL后跟java类名即可,如“http://127.0.0.1:8080/test/com.coyizz.pfc.userBean.class”,显示网页和Java类文件对应关系清晰,方便查找程序问题,不像Strus那样,经过xml配置文件的映射后,往往不知道网页是那个Java类文件产生的了。
HzBean对象封装了常用的数据处理事件,比如onShowMain是显示主界面,onShoForm是显示表单,onSave是保存表格数据,onSubmit是提交数据等;HzBean还实现了权限控制功能:比如用setCanReadOnly(true)方法就可封锁全部添加、修改、删除数据请求,即使用户直接通过url调用也无法改动数据。
HzBean可完成网页间的数据的保持。通过getHoldParmStr(“name”)可以在取得url传递过来的name参数同时,将其保存到session变量中。
HzBean实现了多个数据访问对象的事务处理,每个Bean对象中使用的数据库连接全部记录在一个connItems对象中,在HzBean处理数据更新的方法后,若捕获到SQL异常,则在每个数据连接上进行回滚。
(三) SimpleTableDsBean和ComplexTableDsBean对象
这两个对象利用HzBean、DataStore对象,实现了数据表的增加、删除、修改、输入数据有效性检查、通用查询和排序、数据表可选列打印输出功能。其中SimpleTableDsBean一般用于记录数在50条以下的数据表列数较少的数据表,而ComplexTableDsBean记录数在50条以上列数较多的数据表。ComplexTableDsBean还适合处理比较复杂的数据,如关联数据列等。在最简情况下,只要以下几行代码,就可实现数据表的增、删、改、查、打:
public class TestBean extends ComplexTableDsBean {
public void onInit() {
regDs(new DataStore("dsMain", "select * from usera", getConnItem()));
}
}
在浏览器的地址栏输入“http://127.0.0.1:8080/zhfz/com.coyizz.test.TestBean.calss”就可运行程序。
(四) Html*对象
在需要控制浏览器端的显示细节时,大多数框架是用DrameWave等工具来设计jsp网页来满足需求,但jsp文件通常是一个Html、jsp标签、java代码混合的大杂绘,无法通过编译器进行语法检查,因此,本框架用以Html开始命名的一批对象封装了常用的Html元素,如HtmlA封装了“A”标签,HtmlTable封装了“TABLE”标签。这些对象都继承于HtmlElement,都用add方法来在本标欠内添加其它Html标签。比如要发送给浏览器内容为:“<b ></b>”则对应的Java代码为“new HtmlB()”,如果要发送给浏览器内容为:“<b ><font>Hellow</font></b>”则对应的Java代码为“new HtmlB().add(new HtmlFont(“Hellow”))”。一般情况下Html元素对象是属于底层对象,只在需要精细控制显示细节时才使用。这些Html元素要显示在网页上的方法是在HzBean后代对象中的onShowMain方法或onShowForm等方法中,用addSheet, addBar等方法显示。这样一来,用强类型的Java对象代替了弱类型的Html标签,一切都在Java的控制之中。
当然,有时某些复杂的表格或只有Front和DrameWave才能写好的页面,可先用Front和DrameWave写好纯静态的Html页面,并在需要插入动态数据的地方预留标签,在HzBean的后代对象中,用getHtmlFromFile方法将文件读到内存后,将动态数据插入其中,完成静态页面和动态数据的组合。
(五) DbConns对象
提供了通过JDBC驱动或应用服务器数据库连接池连接数据库的方法,目前可连接Tomcat数据连接池、Oracle、Sybase Adaptive Server Anywhere、PostgreSQL数据库。