目录
ordb其中一个主要思想是将数据库表抽象为对象,这个抽象的内容包括:
例如:数据库中存在一张数据表Test,创建表的sql语句如下:
CREATE TABLE Test ( ID int IDENTITY (1, 1), FIELD_STRING varchar(50) )
这张表对应的Bean对象为:
public class Test2 {
public int ID;
public String FIELD_STRING;
}
注:为了访问的方便性,通常为其增加setter,getter方法。
表的其它元素不会在对象中体现,比如主键,外键,字段是否为自增字段(在MsSql中自增字段就是设置为标识的字段;MySql中指设置为AutoInc的字段;在Oracle中指插入为序列对象的字段)。当表与对象相应关系确定后,就可以使用ordb直接操作对象来实现对数据库的访问。
ordb在使用前需要对ordbconfig.xml进行配置数据库连接和连接池。ordbconfig.xml可以设置多个数据库连接,在使用ordb可以指定其中一个连接进行操作。如果不指定,将使用默认连接。可以下面是一个设置例子:
<datasource default="true"> <id>mssql_1</id> <dbtype>MSSQL</dbtype> <driver>net.sourceforge.jtds.jdbc.Driver</driver> <url>jdbc:jtds:sqlserver://127.0.0.1:1433/test</url> <user>sa</user> <password>admin</password> </datasource> <datasource > <id>mysql_1</id> <dbtype>MYSQL</dbtype> <driver>com.mysql.jdbc.Driver</driver> <url>jdbc:mysql://127.0.0.1/test</url> <user>root</user> <password>root</password> </datasource>
ordb当前支持c3p0数据连接池,当使用c3p0时,设置如下:
<!-- 数据库连接池设置为使用c3p0,如果不使用数据库连接池,值设置为none --> <pool>c3p0</pool> <c3p0> <minPoolSize>0</minPoolSize> <maxPoolSize>50</maxPoolSize> <maxStatementsPerConnection>10</maxStatementsPerConnection> <maxStatements>500</maxStatements> <maxIdleTime>5</maxIdleTime> <idleConnectionTestPeriod>10</idleConnectionTestPeriod> <acquireIncrement>1</acquireIncrement> <checkoutTimeout>30000</checkoutTimeout> </c3p0>
由于数据库的实现不同,对不同数据库表进行插入数据时有不同的操作。这主要表现在自增字段的处理上。在Oracle中常常使用序列插入到一个字段中,来实现字段的自增效果;MSSQL则将字段设置为标识字段;MySql则将字段AutoInc属性设置为true。根据不同情况,以下将分别说明。
数据库表中不包含自增字段。比如存在数据库表test2,往表中插入数据代码如下:
Test2 test2 = new Test2();//数据库表对应的Bean对象
test2.setF1(111);//对象中的每个属性对应表中的一个字段
test2.setF2("222");
test2.setF3("3333");
Ordb o = new Ordb();//创建Ordb对象
try {
int res = o.create(test2);//插入数据;返回受影响记录行数
} catch (OrdbException e) {
e.printStackTrace();//异常处理
}
在MsSql和MySql数据库中,当表中包含自增字段时,需要指定自增字段名称,代码如下:
Test test= new Test();
test.setFIELD_DATE(new Date(System.currentTimeMillis()));
test.setFIELD_DECIMAL(new BigDecimal(3.3));
test.setFIELD_DOUBLE(34.34);
test.setFIELD_FLOAT(234.1f);
test.setFIELD_INT(234);
test.setFIELD_LONG(1111);
test.setFIELD_STRING("string222");
test.setFIELD_TIMESTAMP(new Timestamp(System.currentTimeMillis()));
Ordb o = new Ordb();//创建Ordb对象
try {
AutoInc autoinc = new AutoInc();//创建设置自增字段对象
//MsSql,MySql只需要指定自增字段的名称;这里ID为自增字段名称
autoinc.addAutoIncColumn("ID");
int res = o.create(test,autoinc);//插入数据;返回受影响记录行数
} catch (OrdbException e) {
e.printStackTrace();
}
在Oracle中,当表中包含自增字段时,需要指定自增字段名称和该字段对应的序列,代码如下:
Ordb o = new Ordb();//创建Ordb对象
try {
AutoInc autoinc = new AutoInc();//创建设置自增字段对象
//Oracle需要指定自增字段的名称及该字段对应的值;
//这里ID为自增字段名称,值为序列seq_test.nextval
autoinc.addAutoIncColumn("ID","seq_test.nextval");
int res = o.create(test,autoinc); //插入数据;返回受影响记录行数
} catch (OrdbException e) {
e.printStackTrace();
}
批量插入数据是指同时向数据库插入多条记录。使用4.1或4.2的方法,配合事务循环操作记录也可以实现批量插入的效果。这种操作实际是创建一个数据库连接,多次向服务器提交数据,效率也非常低。如下面的代码例子:
Ordb o = new Ordb();//创建Ordb对象
try {
o.setAutoCommit(false);//将ordb设置为非自动提交
for(int i=0;i<100;i++) {
Test2 test2 = new Test2();//数据库表对应的Bean对象
o.create(test2);//插入数据;返回受影响记录行数
}
o.commit();//提交数据,提交后ordb将自动关闭数据库连接
} catch (OrdbException e) {
o.rollback();//如果这个过程发生异常,则回滚
e.printStackTrace();//异常处理
}
ordb提供了批量插入记录的接口,使用这个接口可以实现一次创建连接,向服务器提交一次数据,这样就可以提高插入效率。如下代码:
Ordb o = new Ordb();
try {
List list = new ArrayList();//将记录对象保存在List
for(int i=0;i<1000;i++) {
TEST_NOINC testnoinc = getObject1();
list.add(testnoinc);
}
o.create(list); //批量插入数据
} catch (OrdbException e) {
e.printStackTrace();
}
修改记录时,常常需要设定条件进行修改,比如在表中,要修改ID>10的所有记录。在MsSql和MySql中,实现代码如下:
Test test= new Test();//设置每个字段修改的值
test.setFIELD_DATE(new Date(System.currentTimeMillis()));
test.setFIELD_DECIMAL(new BigDecimal(3.3));
test.setFIELD_DOUBLE(23.34);
test.setFIELD_FLOAT(234.1f);
test.setFIELD_INT(1);
test.setFIELD_LONG(1111);
test.setFIELD_STRING("string222");
test.setFIELD_TIMESTAMP(new java.sql.Timestamp(System.currentTimeMillis()));
Ordb o = new Ordb();
try {
AutoInc autoinc = new AutoInc();//修改全部记录时需要设定自增字段
autoinc.addAutoIncColumn("ID");//设定ID字段为自增字段
Criteria c = new Criteria();//条件构造器
c.setGreater("ID", 10);//设置条件为ID>10
//执行修改,此时修改的值将保存在test中;返回受影响记录行数
int res = o.update(test,autoinc, c);
} catch (OrdbException e) {
e.printStackTrace();
}
在Oracle中,实现代码如下:
Ordb o = new Ordb();
try {
AutoInc autoinc = new AutoInc();//修改全部记录时需要设定自增字段
//Oracle需要指定自增字段的名称,
//这里ID为自增字段名称,修改时不需要设置该字段的值;
autoinc.addAutoIncColumn("ID");
Criteria c = new Criteria();//条件构造器
c.setGreater("ID", 10);//设置条件为ID>10
//执行修改,此时修改的值将保存在test中;返回受影响记录行数
int res = o.update(test,autoinc, c);
} catch (OrdbException e) {
e.printStackTrace();
}
注:此操作是修改表中的所有字段的数值。在实际开发中,通常会先读取当前表中数据,然后在程序中设定需要修改的列的数值,之后再执行修改操作。
如果在实际开发过程中,需要直接修改指定列的数据,比如执行sql:update test set FIELD_LONG = 111 where ID > 1。实现代码如下:
UpdateSetter updateSetter = new UpdateSetter();
updateSetter.setTableName("test");//设置修改的数据库表名
updateSetter.setUpdate("FIELD_LONG",111);//设置修改的字段及值
Criteria c = new Criteria();
c.setGreater("ID", 1);//设置查询条件ID>1
Ordb o = new Ordb();
try {
//根据条件修改指定字段;返回受收影响记录行数
int res = o.update(updateSetter,c);
} catch (OrdbException e) {
e.printStackTrace();
}
实现代码如下:
Ordb o = new Ordb();
try {
Criteria criteria = new Criteria();
criteria.setEqual("f3", "2");//设置删除条件
//根据条件删除记录,相当于sql:delete from test where f3 = ‘2’
o.delete("test2", criteria);
//无条件删除所有记录,相当于sql:delete from test2
//返回结果为被删除行数
int res = o.delete("test2");
} catch (OrdbException e) {
e.printStackTrace();
}
实现代码如下:
Test2 test2= new Test2();
Ordb o = new Ordb();//创建ordb对象
try {
Criteria criteria = new Criteria();
criteria.setGreater("ID", "10");//设置查询条件
//根据条件查询记录个数;通过对象确定数据库表名
//相当于sql:select count(*) from test2 where ID>10
int count1 = o.queryCount(test2,criteria);
//查询所有记录个数;通过对象确定数据库表名
//相当于sql:select count(*) from test2
int count1 = o.queryCount(test2);
//查询所有记录个数, 字符串指定数据库表名
//相当于sql:select count(*) from test
int count1 = o.queryCount("test");
//根据条件查询记录个数;字符串数据库表名
//相当于sql:select count(*) from test where ID>10
int count1 = o.queryCount("test", criteria);
} catch (OrdbException e) {
e.printStackTrace();
}
查询记录列表是指,查询到符合条件的一条或多条记录,这些记录保存在一个列表中。实现代码如下:
Test test= new Test();
Ordb o = new Ordb();
try {
Criteria criteria = new Criteria();//创建条件设置对象
criteria.setGreater("ID", "10");//设定条件
List list1 = o.queryList(test, criteria); //根据条件查询
//以下将处理查询结果
int num = 0;
if(list1!=null) {num = list1.size();}
for(int i=0;i < num;i++) {
Test testvo = (Test)list1.get(i);
//以下将直接从对象中获得数据进行处理
}
List list2 = o.queryList(test); //查询所有记录
//以下将处理查询结果
int num = (list2==null)?0:list2.size();
for(int i=0;i < num;i++) {
Test testvo = (Test)list2.get(i);
//以下将直接从对象中获得数据进行处理
}
} catch (OrdbException e) {
e.printStackTrace();
}
分页查询记录是指将符合条件的所有记录分成若干页查询,每次只查询其中一页。分页查询时,需要指定每页包含的记录个数,需要查询的页码。如下代码:
Ordb o = new Ordb();
try {
Criteria c = new Criteria();
c.setPageSize(10);//设置分页查询,每页记录个数为10
c.setCurPage(1);//设置查询第一页记录
c.setGreater("ID", 10);//设置条件为ID>10
c.addOrderAsc("ID");//设置查询结果以ID字段作升序排列
//根据条件对表test作分页查询,将查询结果保存PageResult对象中
ResultData rd = o.queryPageList(new Test(),c);
System.out.println(rd.getCurPage());//当前查询页码
System.out.println(rd.getPageSize());//每页记录个数
System.out.println(rd.getTotalCount());//总记录个数
System.out.println(rd.getTotalPage());//总页码数
//查询数据结果将以数组形式保存,下面将转换成Bean对象形式保存
List list = rd.getBeanList(new Test());
int num = (list==null)?0:list.size();
for(int i=0;i < num;i++) {
Test test = (Test)list.get(i);//获得每条记录数据
}
} catch (OrdbException e) {
e.printStackTrace();
}
无返回的存储过程是指,在执行完存储过程之后没有返回结果或者不需要处理返回结果。实现代码如下:
Ordb o = new Ordb();
try {
//存储过程参数,这里表示有2个参数,值分别为1,2
String[] p = {"1","2"};
//执行存储过程testexecproc,参数保存在数组中;执行成功时返回true
boolean res1 = o.executeProcedure("testexecproc", p);
//执行存储过程testexecproc2,没有参数
boolean res2 = o.executeProcedure("testexecproc2");
} catch (Exception e) {
e.printStackTrace();
}
返回一个数据的存储过程是指,执行存储过程后,返回结果是一个数值。这个数值可能是一个字符串或整型数或者是其他类型。这里把返回结果统一字符串数值。 如下代码:
Ordb o = new Ordb();
try {
//存储过程参数,这里表示有2个参数,值分别为1,2
String[] p = {"1","2"};
//执行存储过程testqueryproc,返回数值保存为字符串
String res3 = o.queryFromProcedure("testqueryproc", p);//执行存储过程testqueryproc2,返回数值保存为字符串
String res4 = o.queryFromProcedure("testqueryproc2");
} catch (Exception e) {
e.printStackTrace();
}
返回列表的存储过程是指执行完存储过程之后,返回结果是一个数据集。Ordb将这个数据集封装在Data对象中。实现如下代码:
Ordb o = new Ordb();
try {
//存储过程参数,这里表示有2个参数,值分别为1,2
String[] p = {"1","2"};
//执行存储过程testquerylistproc,返回查询结果为列表保存在Data对象中
ResultData rd =o.queryListFromProcedure("testquerylistproc", p);
//执行存储过程testquerylistproc,返回查询结果为列表保存在Data对象中
ResultData rd2 = o.queryListFromProcedure("testquerylistproc2");
//以下进行处理数据
List list = rd.getArrayList();
for(int i=0;i < list.size();i++) {
Object[] obj = (Object[])list.get(i);
for(int j=0;j < obj.length;j++) {
System.out.println(obj[j]);
}
}
} catch (Exception e) {
e.printStackTrace();
}
ordb允许直接输入sql语句,将执行结果返回。下面将分别说明其各种实现方式
执行sql操作是指通过执行sql语句完成对数据库表的新增,修改,删除三种操作。如下代码:
Ordb o = new Ordb();
try {
//sql语句
String sql = "update test set field_long = 111 where id>100";
//执行sql语句,返回表中受影响的记录个数
int res = o.executeBySql(sql);
} catch (Exception e) {
e.printStackTrace();
}
ordb还可以直接通过sql语句获得查询结果,ordb将这些查询结果封装在Data对象中。实现请参考如下代码:
Ordb o = new Ordb();
try {
//设定sql语句
String sql = "select count(*) from test a inner join dic b on a.field_int = b.id";
//执行查询,将结果保存Data中
ResultData rd = o.queryBySql(sql);
//以下进行处理数据
List list = rd.getArrayList();
for(int i=0;i < list.size();i++) {
Object[] obj = (Object[])list.get(i);
for(int j=0;j < obj.length;j++) {
System.out.println(obj[j]);
}
}
} catch (Exception e) {
e.printStackTrace();
}
使用sql语句查询到数据集,有时候这个数据集非常大,客户端程序需要对它进行作分页查询某一页数据。这个时候就需要使用这个功能。
这里指定的sql可以理解为一个视图,这个功能将对这个视图再进行一次分页查询。具体实现过程请参考如下代码:
Ordb o = new Ordb();
try {
Criteria c = new Criteria();//创建查询条件
c.setPageSize(10);//每页记录10条
c.setCurPage(1);//查询第一页
c.setGreater("ID", 10);//条件为ID>10
c.addOrderAsc("ID");//对ID字段作升序排列
//查询sql
String sql = "select a.id,field_int,b.value from test a inner join dic b on a.field_int = b.id";
//分页查询,将数据保存在Data对象中
Result rd = o.queryPageListBySql(sql,c);
//以下进行处理数据
int totalcount = rd.getTotalCount();//总记录数
int totalpage = rd.getTotalPage();//总页数
int pagesize = rd.getPageSize();//每页最大记录数
int curpage = rd.getCurPage();//当前页码
List list = rd.getArrayList();
for(int i=0;i < list.size();i++) {
Object[] obj = (Object[])list.get(i);
for(int j=0;j < obj.length;j++) {
System.out.println(obj[j]);
}
}
} catch (Exception e) {
e.printStackTrace();
}
ordb在操作数据库时,支持事务操作,如果其中某个过程发生异常,数据库将进行回滚。实现过程请参考如下代码:
Ordb o = new Ordb();//创建ordb对象
try {
o.setAutoCommit(false);//将ordb设置为非自动提交
AutoInc autoinc = new AutoInc();
autoinc.addAutoIncColumn("ID");//设置自增字段
o.create(test,autoinc);//在test表中插入记录
o.create(test2);//在test2表中记录
o.commit();//提交数据,提交后ordb将自动关闭数据库连接
} catch (Exception e) {
o.rollback();//如果这个过程发生异常,则回滚
e.printStackTrace();
}
多连接之间的事务是指,同时创建多个数据库连接,这些连接可能指向同一个数据库服务器的不同数据库,也可能指向不同数据库服务器的不同数据库对象。对这些连接进行操作,并使其具有事务功能,当其中一个连接操作发生异常,则进行回滚,取消所有连接的操作。
具体实现过程请参考如下代码:
Ordb o = new Ordb();//创建ordb对象
try {
o.setAutoCommit(false);//将自动提交方式设置为false
AutoInc autoinc = new AutoInc();//自增字段
autoinc.addAutoIncColumn("ID","seq_test.nextval");
o.create(test,autoinc);//默认连接为oracle数据库,在test插入记录
o.setDefaultDbId("mysql_1");//将数据库连接设置为mysql数据库
o.create(test2);//在mysql数据库的test2表插入记录
o.commit();//提交数据
} catch (Exception e) {
o.rollback();//如果发生异常,则回滚
e.printStackTrace();
}