`

使用XML封装数据库操作语句的实现

 
阅读更多

在项目开发的过程当中,项目组开发成员的编程风格差异和数据库操作语句SQL的灵活性给项目组带来了越来越多的操作和维护难度。
比如:
从user表中取出所有数据,有的人会写成’select*fromuser’,有的人会写成‘selectallfromuser’,虽然在操作中不会有任何的错误,但在其他人读程序的过程时就会产生不好的感觉。
如果这种程序差异在项目中的数量级很多,那么在开发的过程当中程序就会出现各种各样的风格,在维护的过程中就会拼命的挠头并诅咒那些当初写程序的人(呵呵,至少我会毫不客气的骂人的)。

为了整篇文章的举例,现在我们在数据库中建立如下表
TBL_USER
USERIDBIGINT
USERNAMEVARCHAR(20)
PASSWORDVARCHAR(20)
CREATETIMEDATE

TBL_USER_INFO
USERIDBIGINT
EMAILVARCHAR(64)
MOBILEVARCHAR(13)

一:分析

A)分析select语句

于是使用XML来封装数据库操作语句成为项目规范化操作的第一步骤。在这个步骤中,我们将举几个例子来逐步实现封装的目的。
比如“SELECTUSERNAME,PASSWORDFROMTBL_USER”这个语句,分析成XML文件时可以有各种各样的写法,我们现在使用如下的表达方式:
分析1)
1<dbtransname=”selectUser”table=”TBL_USER”method=”select”>
2<get>
3<propertyname=”username”type=”string”/>
4<propertyname=”password”type=”string”/>
5</get>
6</dbtrans>
在第一行的句子中使用dbtrans为节点名称,
属性name为这个交易的名称,这里为”selectUser”,
属性table为索取表的名称,这里为”TBL_USER”,
属性method为操作数据库的方法,这里为”select”,
子节点<get></get>意思为从数据库读取数据。
子节点<property/>为读取的数据库字段,其中:
属性name为字段的名字,
属性type为字段的类型,这里设置类型在后面的程序中可以体现出来。

对于”SELECTUSERNAME,PASSWORDFROMTBL_USERWHEREUSERID=123“语句,我们根据上诉的分析,则可将XML描绘为:
分析2)
1.<dbtransname=”selectUserByKey”table=”TBL_USER”method=”select”>
2.<key>
3<propertyname=”userid”type=”long”/>
4</key>
5<get>
6<propertyname=”username”type=”string”/>
7<propertyname=”password”type=”string”/>
8</get>
9</dbtrans>
如果使用的是like操作,我们可以将第3句描述成为
<propertyname=”username”type=”string”match=”like”/>

对于”SELECTUSERNAME,PASSWORDFROMTBL_USERORDERBYUSERNAMEDESC“这个语句,XML如下分析
分析3)
1.<dbtransname=”selectUser”table=”TBL_USER”method=”select”>
2<get>
3<propertyname=”username”type=”string”/>
4<propertyname=”password”type=”string”/>
5</get>
6<ordername="respcode"match="desc"/>
6</dbtrans>

这样的语句分析基本上可以完成了绝大部分的普通数据库的select语句的操作,但是毕竟还是会有一些我们无法预料的数据库操作语句会出现,比如
“SELECTUSERNAME,PASSWORDFROMTBL_USERWHERECREATETIME>’2003-7-16’ANDCREATETIME<’2003-9-16’时,同时出现了CREATETIME在<key>之中,这时我们可以将XML描绘成为
<key>
<propertyname=”starttime”column=”createtime”type=”date”match=”>”>
<propertyname=”endtime”column=”createtime”type=”date”match=”<”>
</key>

但即使使用了以上的变通方法,还是会有很多的特殊语句是无法完成的,比如“SELECTCOUNT(*)FROMTBL_USER“,这时的操作会出现使用XML语句无法描绘的时候,这个时候我们就可以引入了special这个属性,例如:
分析4)
1.<dbtransname=”selectUser”table=”TBL_USER”method=”select”special=”selectcount(*)fromtbl_user”>
2</dbtrans>

这个属性的意思是将所有的特殊交易都特殊表现出来。

B)分析INSERT语句

INSERT语句在关系型数据库中操作可以说是最麻烦的一条语句了,因为如果你需要在TBL_USER和TBL_USER_INFO表中建立一条对应的数据时,你需要知道插入数据库的主键的值,在JDBC3.0中可以使用Statement.RETURN_GENERATED_KEYS来获取,但是如果为了兼容性考虑,我们在操作过程之中决定采用另一种办法来实现。
我们在数据库中建立一个表,名为:TSYS_PRIMARYKEY,其中包括三个字段,如下:
TSYS_PRIMARYKEY
KEYIDBIGINT
TABLENAMEVARCHAR(64)
PRIMARYKEYVARCHAR(30)
其中TABLENAME保存表名,PRIMARYKEY保存主键的名称,KEYID保存主键的值,这样的做法目的是在insert语句操作前,先取到现在主键的值,并将该值加1,成为现有的主键,然后进行insert操作,操作完成之后我们还需要update一下TSYS_PRIMARYKEY这个表,确保数据的同步。
现在我们开始分析INSERT语句了,
INSERTINTOTBL_USER(USERID,USERNAME,PASSWORD)VALUES(100,‘test’,‘test’)
INSERTINTOTBL_USER_INFO(USERID,EMAIL,MOBILE)VALUES(100,‘test@test.com’,‘1234567890’)

描绘为XML文件时我们可以描绘如下
分析5)
1.<dbtransname=”insertUser”table=”TBL_USER”method=”insert”>
2<primarykeyname=”userid”>
3<set>
4<propertyname=”username”type=”string”/>
5<propertyname=”password”type=”string”/>
6</set>
7</dbtrans>
以及
1.<dbtransname=”insertUserInfo”table=”TBL_USER_INFO”method=”insert”>
2<set>
3<propertyname=”userid”type=”long”/>
4<propertyname=”email”type=”string”/>
5<propertyname=”mobile”type=”string”/>
6</set>
7</dbtrans>

C)分析DELETE语句

Delete语句最常用的可以分为两种,一种是按照键值删除,一种是全部删除,为此我们将此操作划分为两种类型,delete和clear
对于delete类型,举例为:
DELETEFROMTBL_USER_INFOWHEREUSERID=123
描述为:
分析6)
1.<dbtransname=”deleteUserInfo”table=”TBL_USER_INFO”method=”delete”>
2<key>
3<propertyname=”userid”type=”long”/>
4</key>
5</dbtrans>

对于clear类型,举例为:
DELETEFROMTBL_USER_INFO
描述为:
分析7)
1.<dbtransname=”clearUserInfo”table=”TBL_USER_INFO”method=”clear”>
2</dbtrans>

D)分析UPDATE语句

从update通常的操作我们可以知道使用XML表述时将会出现两种tag,包括<key>和<set>,比如:
UPDATETBL_USER_INFOSETEMAIL=’aaa@aaa.com’WHEREUSERID=123
描述称XML为:
分析8)
1.<dbtransname=”updateUserInfo”table=”TBL_USER_INFO”method=”update”>
2<key>
3<propertyname=”userid”type=”long”/>
4</key>
5<set>
6<propertyname=”email”type=”string”/>
7</set>
8</dbtrans>

二:程序设计

好的,在分析了XML文件之后需要我们进入到程序的设计上来了。从以上实现的分析我们可以清楚的看到要实现以上操作,我们必须要做到以下几步:
1:读取XML文件
2:定位相应的交易节点
3:拼SQL语句
4:数据库操作
5:取数据
6:返回数据

其中针对第一步的读取文件,我们可以封装所有的XMLparse语句以及前期的操作封装
进入一个类之中,这里我们命名为XMLLoadFile。

交易处理的过程包括2,5,6三个步骤,可以封装成XMLTransaction类中。当然返回数据这个操作可以单独抽出来作为一个相应的返回类,如果这样是为了在返回的数据报文做处理,比如可以返回XML,Vector或者Hashtable或Map等。这里暂定返回数据为Vector类型,所以将第6步封装进来。

拼装SQL语句,独立建立一个类(XMLCombine),当然也可以分为多个,比如SelectCombine,insertCombine等,这里我们进行统一封装。

数据库操作单独封装成一个类,XMLExecuteSQL。

以上所有的类统一了一个出口类,这里为XMLUtils。这个类提供的几个方法为外部数据操作的主要方法,比如select,insert,delete,update等,还有提供外部程序存取数据的几个方法,比如:setTransNode(设置交易节点),setTransValue(设置交易数据值),setTransKeyValue(设置交易键值数据值)

三:外部程序调用

对于select语句,分析1)所需编写的程序如下
XMLUtilsutil=newXMLUtils();
util.setTransNode(“selectUser”);
VectorvRtn=util.select(con);

分析2)为
XMLUtilsutil=newXMLUtils();
util.setTransNode(“selectUserByKey”);
util.setTransKeyValue(“userid”,123);
VectorvRtn=util.select(con);

对于insert语句,分析5)程序如下
XMLUtilsutil=newXMLUtils();
util.setTransNode(“insertUser”);
util.setTransValue(“username”,“test”);
util.setTransValue(“password”,“test”);
VectorvRtn=util.insert(con);//假设操作成功
longuserid=((Long)((Hashtable)vRtn.elementAt(0)).get(“userid”)).longValue();

util.setTransNode(“insertUserInfo”);
util.setTransValue(“userid”,userid);
util.setTransValue(“email”,“test@test.com”);
util.setTransValue(“mobile”,“1234567890”);
VectorvRtn=util.insert(con);

对于delete语句分析6)程序如下
XMLUtilsutil=newXMLUtils();
util.setTransNode(“deleteUser”);
util.setTransKeyValue(“userid”,100);
util.delete(con);

对于update语句,分析8)程序如下
XMLUtilsutil=newXMLUtils();
util.setTransNode(“updateUserInfo”);
util.setTransKeyValue(“userid”,123);
util.setTransValue(“email”,“aaa@aaa.com”);
util.update(con);

大家在看这些SQL的操作时,是不是觉得很工整,也很舒服呢?这样做的好处很多,程序员可以不必太多的去拼写SQL语句,封装的操作可以使所有程序员的程序都可以写的很工整,并有统一的风格。
GoodLuck,Enjoy.

Kelithisishnh@163.com


word文档放置于此http://keli.nease.net/XMLDB.doc

最新jar包放置于http://keli.nease.net/iartbean/iartbean.jar

Sample放置于http://keli.nease.net/iartbean/Sample.java
importcom.iart.DataBase.XMLControl.*;
importcom.microsoft.*;
importjava.sql.*;
importjava.util.*;
publicclassSample{

publicstaticvoidmain(String[]args){

XMLUtilsutil=newXMLUtils();
Connectioncon=null;
try{
System.out.println("[StartupServlet]begin==============================================");
util.StartupServlet();
System.out.println("[StartupServlet]end==============================================");
con=getConnection();
System.out.println("[GetConnection]"+con.toString());
//
/*util.setTransNode("clear");
util.clear(con);

util.setTransNode("setpassbyname");
util.setTransValue("logonname","keli2");
util.setTransValue("username","keli3");
util.setTransValue("password","hnh3");
util.insert(con);
*/

util.setTransNode("backemail","selectRespCode");
//util.setTransKeyValue("starttime","2003-08-2200:00:00.0");
//util.setTransKeyValue("endtime","2003-08-2223:59:59.0");
//util.setTransKeyValue("docstatusid","2");

//util.setTransValue("createtime","CURRENT_TIMESTAMP");



/*util.setTransNode("insertDocument");
util.setTransValue("doctypeid","2");
util.setTransValue("docstatusid","1");

VectorvRtn=util.insert(con);
*/
HashtablevRtn=util.select(con,0,-1);
System.out.println(vRtn.toString());
System.out.println(((Vector)vRtn.get("DATA")).size());

util.setTransNode("backemail","selectRespCode");
vRtn=util.select(con,2,20);
System.out.println(vRtn.toString());
System.out.println(((Vector)vRtn.get("DATA")).size());

vRtn=util.select(con,3,20);
System.out.println(vRtn.toString());
System.out.println(((Vector)vRtn.get("DATA")).size());
/*util.setTransNode("selectmaxdoc");
VectorvResult=util.select(con);
Longdocid=(Long)((Hashtable)vResult.elementAt(0)).get("docid");

util.setTransNode("insertEmail");
util.setTransValue("mid",docid.toString());
util.setTransValue("subject","test");
util.setTransValue("targetaddr","test@test.com");
util.setTransValue("sourceaddr","test@test.com");
util.setTransValue("content","test@test.com");

util.insert(con);


util.setTransNode("selectemail");
VectorvResult1=util.select(con);

for(inti=0;i<vResult1.size();i++)
{
HashtablevColumn=(Hashtable)vResult1.elementAt(i);
if(vColumn!=null)
System.out.println("1"+vColumn.toString());
}

*/

/*util.setTransNode("deletebyname");
util.setTransKeyValue("logonname","keli");
util.delete(con);


util.setTransNode("getpassbyname");
util.setTransKeyValue("logonname","%keli%");
VectorvResult2=util.select(con);

for(inti=0;i<vResult2.size();i++)
{
HashtablevColumn=(Hashtable)vResult2.elementAt(i);
if(vColumn!=null)
System.out.println(vColumn.toString());
}
*/
}catch(Exceptionex)
{
ex.printStackTrace();
}finally{
try{
con.close();
}catch(Exceptionex1)
{
System.out.println(ex1.getMessage());
}
}

}

publicstaticConnectiongetConnection()throwsException{
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
StringstrCon="jdbc:microsoft:sqlserver://localhost:1433;User=nlc;Password=nlc;DatabaseName=nlc";
Connectionconn=DriverManager.getConnection(strCon);
returnconn;
}

}

分享到:
评论

相关推荐

    XML封装数据库操作语句

    在项目开发的过程当中,项目组开发成员的编程风格差异和数据库操作语句SQL的灵活性给项目组带来了越来越多的操作和维护难度。

    如何使用XML封装数据库操作语句的实现

    在项目开发的过程当中,项目组开发成员的编程风格差异和数据库操作语句SQL的灵活性给项目组带来了越来越多的操作和维护难度。比如:从user表中取出所有数据,有的人会写成“select * from user”,有的人会写成...

    通用数据库访问类sql server 版本常用方法封装

    执行多条SQL语句,实现数据库事务。如果插入或者修改数据运用事务时候,其中一行报错,将事务回滚。 * 6.在执行命令文本时后,传递sql语句运用Regex re = new Regex(@"@[a-zA-Z0-9]") 则正则表达式进行配匹, * ...

    asp.net的通用数据库访问层源码

    1. 所有SQL语句都放在不同的XML檔中(一个业务类使用一个XML檔),该档可用工具维护。大大节省开发及维护时间。2. 当数据库结构改变时,只需修改SQL配置文件(用DBMap工具维护),而不用改代码(如果结构改变影响到...

    C# 公共类文档包含Sql、Excel、Xml、GDI、窗体冻结解冻、图片水印压缩编码、正则表达式、反射操作等,各辅助类封装完美

    大神封装的DotNet参考类库,值得学习借鉴----------Database--------------1.DataTable帮助类(DataTableHelper.cs)2.Access数据库文件操作辅助类(JetAccessUtil.cs)3.常用的Access数据库Sql操作辅助类库...

    mybatis-config.xml

     mybatis是对jdbc的封装,它让数据库底层操作变的透明。mybatis的操作都是围绕一个sqlSessionFactory实例展开的。mybatis通过配置文件关联到各实体类的Mapper文件,Mapper文件中配置了每个类对数据库所需进行的sql...

    jfinal插件集合demojfinal-demo.zip

    jfinal demo 程序,使用bootstrap 本人编写的多款插件,如使用coffeescript-maven-plugin编译...4.使用jfinal-sqlinxml实现在xml里管理sql语句 还有很多功能大家可以运行之后 慢慢体验 标签:jfinal

    C#基类库(苏飞版)

    使用C#实现对Sql数据库的操作,执行存储过程,Sql语句,返回影响行数,返回DateTable,DataSet,DataReader,以及表集等方法。实现多个数据库的切换功能。功能强大,希望大家喜欢 2.一个操作Sql2005数据库的类(备份...

    SqlHelper源码及使用实例

    SqlHelper源码及使用实例下载 SqlHelper 类实现详细信息 SqlHelper 类用于通过一组静态方法来封装数据访问功能。该类不能被继承或实例化,因此将其声明为包含专用构造函数的不可继承类。 在 SqlHelper 类中实现的每...

    ASP.NET3.5从入门到精通

    9.1.4 使用ExecuteXmlReader()操作数据库 9.2 ASP.NET 创建和插入记录 9.2.1 SQL INSERT 数据插入语句 9.2.2 使用Command 对象更新记录 9.2.3 使用DataSet 数据集插入记录 9.3 ASP.NET 更新数据库 9.3.1 SQL UPDATE ...

    maku-generator低代码生成器.rar

    mapper,对数据库进行数据持久化操作,它的方法语句是直接针对数据库操作的,主要实现一些增删改查操作,在 mybatis 中方法主要与与 xxx.xml 内相互一一映射; service,业务 service 层,给 controller 层的类提供...

    ASP.NET 3.5 开发大全11-15

    9.1.4 使用ExecuteXmlReader()操作数据库 9.2 ASP.NET创建和插入记录 9.2.1 SQL INSERT数据插入语句 9.2.2 使用Command对象更新记录 9.2.3 使用DataSet数据集插入记录 9.3 ASP.NET更新数据库 9.3.1 SQL UPDATE数据...

    ASP.NET 3.5 开发大全

    9.1.4 使用ExecuteXmlReader()操作数据库 9.2 ASP.NET创建和插入记录 9.2.1 SQL INSERT数据插入语句 9.2.2 使用Command对象更新记录 9.2.3 使用DataSet数据集插入记录 9.3 ASP.NET更新数据库 9.3.1 SQL UPDATE数据...

    ASP.NET 3.5 开发大全1-5

    9.1.4 使用ExecuteXmlReader()操作数据库 9.2 ASP.NET创建和插入记录 9.2.1 SQL INSERT数据插入语句 9.2.2 使用Command对象更新记录 9.2.3 使用DataSet数据集插入记录 9.3 ASP.NET更新数据库 9.3.1 SQL UPDATE数据...

    ASP.NET 3.5 开发大全word课件

    9.1.4 使用ExecuteXmlReader()操作数据库 9.2 ASP.NET创建和插入记录 9.2.1 SQL INSERT数据插入语句 9.2.2 使用Command对象更新记录 9.2.3 使用DataSet数据集插入记录 9.3 ASP.NET更新数据库 9.3.1 SQL UPDATE数据...

    ASPNET35开发大全第一章

    9.1.4 使用ExecuteXmlReader()操作数据库 9.2 ASP.NET创建和插入记录 9.2.1 SQL INSERT数据插入语句 9.2.2 使用Command对象更新记录 9.2.3 使用DataSet数据集插入记录 9.3 ASP.NET更新数据库 9.3.1 SQL UPDATE数据...

    Jive资料集

    4 Jive Forums KB合并数据库脚本(MSSQL) 5 Jive Forums KB合并数据库脚本(Oracle) 6 Jive Forums KB合并数据库脚本(MySql) 7 使用XML封装数据库操作语句的实现 8 Database Package下面的...

Global site tag (gtag.js) - Google Analytics