1. Torque介绍
Torque
是一个持久
层
框架,也是
jakarta
的一个子
项
目,原来包括在
Turbine
框架中,从
Turbine2.2
开
始
Torque
被分离出来作
为
一个
单
独的子
项
目。目前最高版本是
3.3。
2. 对持久层以及持久层框架的理解
所
谓
持久
层
就是在整个系
统
中与持久
存储
介
质
如
Database,LDAP Server,XML
等打交道的部分。持久
层
框架的作用就是使持久
层访问
持久介
质
更加方便。如果是
为
了
访问
Database
而建立的持久
层
框架那
么
就又有一个
O/R Mapping
的概念。
O/R Mapping
就是建立
对
象
(Object)
与
关
系数据
库
(R)
中的表
(
不一定是一
对
一
)
的映射。
Torque
就是
这样
一
种
起到
O/R Mapping
作用的持久
层
框架。他使
java
程序
员
可以方便地通
过
操作普通
java
对
象的方式来
访问
数据
库
,甚至不用了解数据
库
的相
关
知
识
(
最好是了解
)
,另一个好
处
是屏蔽数据
库类
型即可任意更
换
持久
层
框架支持的
Database
。
3. Torque的工作原理
一般在利用
O/R Mapping
框架
进
行
开发
的
时
候,有三个基本的
单
元即
关
系数据
库
中的表
(Table)
,
Java
中的持久
对
象
(PO),
定
义
PO
到
Table
映射的
xml
文件
(Schema)
。
首先,
Torque
包含一个
generator
用来根据由
开发
者配置好的
Schema
来自
动
生成
PO
和
Table
,
这
就意味着
开发
者只要定
义
好
Schema
,
PO
和
Table
就可以自
动
生成了。
在生成好的
PO
和
Table
以后,
开发
者就可以利用
PO
来
进
行
对
Table
的
访问
了。
为
了达到
这
个目的
Torque
提供了一个运行
时环
境来保
证
代
码
的正确运行。在工程中引入了
torque
相
关
的
.jar
就可以
拥
有
这
个运行
环
境了。
4. Torque中的包,类和接口
Torque
的源
码
提供的是运行
环
境,基于
Torque
开发关
心的是生成的
PO
的使用方法即怎
样
使用生成的
PO
来操作
Table
。下面会通
过
Torque
导
学上
带
的例子来
详细说
明。
5. 导学中的例子
5.1利用generator生成PO和Table
首先,要通
过
generator
来生成
PO
和
Table
要定
义
Schema
和
进
行
generator
的配置。
Schema
的定
义
如下:
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE database SYSTEM
"http://db.apache.org/torque/dtd/database_3_1.dtd">
<database
name="torque"
defaultIdMethod="idbroker">
<table name="book" description="Book Table">
<column
name="book_id"
required="true"
primaryKey="true"
type="INTEGER"
description="Book Id"/>
<column
name="title"
required="true"
type="VARCHAR"
size="255"
description="Book Title"/>
<column
name="isbn"
required="true"
type="VARCHAR"
size="24"
javaName="ISBN"
description="ISBN Number"/>
<column
name="publisher_id"
required="true"
type="INTEGER"
description="Foreign Key Publisher"/>
<column
name="author_id"
required="true"
type="INTEGER"
description="Foreign Key Author"/>
<foreign-key foreignTable="publisher" onDelete="cascade">
<reference
local="publisher_id"
foreign="publisher_id"/>
</foreign-key>
<foreign-key foreignTable="author" onDelete="cascade">
<reference
local="author_id"
foreign="author_id"/>
</foreign-key>
</table>
<table name="publisher" description="Publisher Table">
<column
name="publisher_id"
required="true"
primaryKey="true"
type="INTEGER"
description="Publisher Id"/>
<column
name="name"
required="true"
type="VARCHAR"
size="128"
description="Publisher Name"/>
</table>
<table name="author" description="Author Table">
<column
name="author_id"
required="true"
primaryKey="true"
type="INTEGER"
description="Author Id"/>
<column
name="first_name"
required="true"
type="VARCHAR"
size="128"
description="First Name"/>
<column
name="last_name"
required="true"
type="VARCHAR"
size="128"
description="Last Name"/>
</table>
</database>
在
这
个
schema
里定
义
了
Table
的
结
构,生成的
PO
在会按照一定
规则
与
Table
进
行
对应
。
然后修改
build.properties
文件加入如下部分:
torque.database = mysql
torque.project = torque
torque.addGetByNameMethod = true
torque.addIntakeRetrievable = false
torque.addSaveMethod = true
torque.addTimeStamp = true
torque.basePrefix = Base
torque.complexObjectModel = true
torque.useClasspath = false
torque.useManagers = false
torque.targetPackage=org.together.om
torque.database.createUrl = jdbc:mysql://127.0.0.1/mysql
torque.database.buildUrl = jdbc:mysql://127.0.0.1/torque
torque.database.url = jdbc:mysql://127.0.0.1/torque
torque.database.driver = org.gjt.mm.mysql.Driver
torque.database.user = root
torque.database.password = haohao
torque.database.host = 127.0.0.1
torque.sameJavaName = false
关键
是
绿
色
标记
的部分,表明是
连
接的
mysql
数据
库
,并将生成的
PO
放到
org.together.om
包中。
最后利用
ant
执
行
generator
,
这样
就可以在数据
库
中生成相
应
的
Table
,并生成于
Table
对应
的
PO(
放在定
义
好的
org.together.om
下
)
。拿
schema
中定
义
的
Author
为
例,运行
generator
后可以在
mysql
数据
库
中生成一
张
Author
表,
DDL
如下:
CREATE TABLE `author` (
`author_id` int(11) NOT NULL default '0',
`first_name` varchar(128) NOT NULL default '',
`last_name` varchar(128) NOT NULL default '',
PRIMARY KEY (`author_id`)
) TYPE=MyISAM
在
org.together.om
包下会有一个
BaseAuthor
类
(
由于生成的
PO
比
较
多在下面会
详细
介
绍
)
,
这
个
类
中会有如下的属性与
Table
中的字段
进
行
对应
。
/** The value for the authorId field */
private int authorId;
/** The value for the firstName field */
private String firstName;
/** The value for the lastName field */
private String lastName;
5.2 由generator生成的PO的结构
在org.together.om下有若干类和一个子包map。map包下的也是运行环境相关的不用考虑。在org.together.om下会为schema中定义的每一个表生成四个相关的类。拿Book来说,有四个类和他对应,分别为:BaseAuthorPeer, AuthorPeer,BaseAuthor, Author。BaseAuthorPeer和BaseAuthor分别是AuthorPeer和Author的基类,在基类里是由generator生成的代码,注意不要修改基类的代码,因为每次利用generator生成时都会覆盖基类的代码(AuthorPeer和Author类不会被覆盖)。
5.3 PO的使用方法
BaseAuthorPeer和BaseAuthor这两个基类是用来提供底层功能的,我们只要操作AuthorPeer和Author类就可以完成对数据库中的表author的操作如增加,删除,更新和查询等。
对author进行增加操作的代码如下:
Author na = new Author();
na.setFirstName("a");
na.setLastName("b");
na.save(); // 或用AuthorPeer的静态方法替代AuthorPeer.doInsert(na);
对author进行更新操作的代码如下:
na.setLastName("c");
na.save(); //或用AuthorPeer的静态方法替代AuthorPeer.doUpdate(na);
对author进行删除操作的代码如下:
AuthorPeer.doDelete(na); //进行delete时只能使用AuthorPeer的静态方法
对author进行查询,查询出author表中的author_id字段的值在1和10000之间的所有数据
Criteria testCriteria = new Criteria();
testCriteria.add(AuthorPeer.AUTHOR_ID,1,Criteria.GREATER_THAN);
testCriteria.add(AuthorPeer.AUTHOR_ID,10000,Criteria.LESS_THAN);
List tList = AuthorPeer.doSelect(testCriteria);
log.debug("all size:" + tList.size());
for (int i = 0; i < tList.size(); i++) {
Author o = (Author) tList.get(i);
System.out.println("Author" + i + " : " + o.toString());
}
以上介绍了PO的基本用法,在实际的应用中往往比上述要复杂的多,但是掌握了基本的方法,其他的用法就可以在实际使用时查看手册即可。Torque的doc上附带的Toturial上面有使用generator的详细说明和怎样使用Torque进行开发的例子。
6. Torque在ACI中的应用
看了一下
ACI
的源码,
torque
自动生成的部分没有任何改动,即都是直接使用生成的
PO
。但在
TorqueACIStorage.java
中关于
Torque
的用法要比上述的例子中多了一个事务处理情况,以下给出使用
Torque
进行事务处理的例子。
//
创建
JDBC
连接用于控制事务
java.sql.
Conn
ection conn = null;
try{
//
开始事务
conn=Transaction.begin(BaseAuthorPeer.getMapBuilder().getDatabaseMap().getName());
Author ta = new Author();
ta.setFirstName("t");
ta.setLastName("t");
AuthorPeer.doInsert(ta,conn);
//String ab = null; //
人为制造异常使事务回滚
//ab.toLowerCase();
Publisher tp = new Publisher();
tp.setName("t");
PublisherPeer.doInsert(tp,conn);
//
提交事务,会自动释放连接
Transaction.commit(conn);
} catch (Exception ex) {
//
回滚事务
Transaction.safeRollback(conn);
log.error(ex);
}
ACI
中也有一些复杂一点的查询条件
(Criteria
)
的构造,在
Torque
的
docs
中的
criteria-howto.html
文件中都应该能够找到。