Apache Torque是一种object-relational mapper。Torque能让用户通过java object 访问或操作关系数据库中的数据。不同于大多数其他object-relational mappers,Torque访问用户提供的类不使用反射,而是使用由XML schema生成的必要的类(包括Data Objects)。
Torque有两个用途:一个是作为java code生成的工具;另一个是基于生成的代码,提供object-relational mapping (ORM) 访问数据库。这两个方面可以认为是不同的部分,独立对待。ORM部分包含创建数据库和读写数据。code生成部分表示如何使用Torque generator生成自定义code (O/R classes)。
步骤一:配置Torque generation process
使用Maven或者Ant配置的依赖和plugin。依赖主要有Torque runtime或者db driver (比如mysql-connector-java)。plugin主要是一些根据模版生产代码的配置
步骤二:定义数据库schema
第二个需要编辑的配置文件是database schema。Torque里面database schema是一个描述数据库结构的XML file。文件可以定义某个数据库的表,column名字和类型,表的键和索引。
步骤三:调用Torque generator
完成了maven/ant配置和database schema定义后,接下来可以生产object model和创建数据库表。object model的创建会生成代表数据库结构的java源文件。通过这些类我们可以操作数据库中的数据。此外,Torque还会生成SQL去创建数据库表。
Torque创建object model时,会为每个table生成8各类: 4个有Base前缀的和4个没有前缀的。有Base前缀的类不可修改(因为每次生成都会被覆盖掉),没有前缀的类是Base前缀类的子类,可以覆盖父类的实现。
Note: Torque会假设数据库已经存在,在执行Sql的时候,首先会drop掉相应数据。
步骤四:配置Torque runtime
配置Torque运行环境简单来讲,就是配置运行时的连接信息,比如adapter,driver,url, 用户名和密码。
一个简单的例子:
torque.database.default = bookstore
torque.database.bookstore.adapter = mysql
torque.dsfactory.bookstore.factory = org.apache.torque.dsfactory.SharedPoolDataSourceFactory
torque.dsfactory.bookstore.connection.driver = org.gjt.mm.mysql.Driver
torque.dsfactory.bookstore.connection.url = jdbc:mysql://localhost:3306/bookstore
torque.dsfactory.bookstore.connection.user = root
torque.dsfactory.bookstore.connection.password = password
步骤五: 把Torque用起来
生成完必要的class,数据库表,以及配置好了运行的连接信息。接下来就是如何用在应用程序中。
package org.apache.torque.tutorial.om;
import java.io.InputStream;
import java.util.List;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.torque.Torque;
import org.apache.torque.criteria.Criteria;
public class Bookstore
{
public static void main(String[] args)
{
try
{
// Initializing Logging
BasicConfigurator.configure();
Logger.getRootLogger().setLevel(Level.WARN);
// Initializing Torque
InputStream torqueConfigStream
= Bookstore.class.getResourceAsStream("/torque.properties");
PropertiesConfiguration torqueConfiguration
= new PropertiesConfiguration();
torqueConfiguration.load(torqueConfigStream);
Torque.init(torqueConfiguration);
/*
* Creating new objects. These will be inserted into your database
* automatically when the save method is called.
*/
Publisher addison = new Publisher();
addison.setName("Addison Wesley Professional");
addison.save();
Author bloch = new Author();
bloch.setFirstName("Joshua");
bloch.setLastName("Bloch");
bloch.save();
/*
* An alternative method to inserting rows in your database.
*/
Author stevens = new Author();
stevens.setFirstName("W.");
stevens.setLastName("Stevens");
AuthorPeer.doInsert(stevens);
/*
* Using the convenience methods to handle the foreign keys.
*/
Book effective = new Book();
effective.setTitle("Effective Java");
effective.setISBN("0-618-12902-2");
effective.setPublisher(addison);
effective.setAuthor(bloch);
effective.save();
/*
* Inserting the foreign-keys manually.
*/
Book tcpip = new Book();
tcpip.setTitle("TCP/IP Illustrated, Volume 1");
tcpip.setISBN("0-201-63346-9");
tcpip.setPublisherId(addison.getPublisherId());
tcpip.setAuthorId(stevens.getAuthorId());
tcpip.save();
/*
* Selecting all books from the database and printing the results to
* stdout using our helper method defined in BookPeer (doSelectAll).
*/
System.out.println("Full booklist:\n");
List<Book> booklist = BookPeer.doSelectAll();
printBooklist(booklist);
/*
* Selecting specific objects. Just search for objects that match
* this criteria (and print to stdout).
*/
System.out.println("Booklist (specific ISBN):\n");
Criteria crit = new Criteria();
crit.where(BookPeer.ISBN, "0-201-63346-9");
booklist = BookPeer.doSelect(crit);
printBooklist(booklist);
/*
* Updating data. These lines will swap the authors of the two
* books. The booklist is printed to stdout to verify the results.
*/
effective.setAuthor(stevens);
effective.save();
tcpip.setAuthor(bloch);
BookPeer.doUpdate(tcpip);
System.out.println("Booklist (authors swapped):\n");
booklist = BookPeer.doSelectAll();
printBooklist(booklist);
/*
* Deleting data. These lines will delete the data that matches the
* specified criteria.
*/
crit = new Criteria();
crit.where(BookPeer.ISBN, "0-618-12902-2");
BookPeer.doDelete(crit);
crit = new Criteria();
crit.where(BookPeer.ISBN, "0-201-63346-9");
crit.and(BookPeer.TITLE, "TCP/IP Illustrated, Volume 1");
BookPeer.doDelete(crit);
/*
* Deleting data by passing Data Objects instead of specifying
* criteria.
*/
AuthorPeer.doDelete(bloch);
AuthorPeer.doDelete(stevens);
PublisherPeer.doDelete(addison);
System.out.println("Booklist (should be empty):\n");
booklist = BookPeer.doSelectAll();
printBooklist(booklist);
}
catch (Exception e)
{
e.printStackTrace();
}
}
/*
* Helper method to print a booklist to standard out.
*/
private static void printBooklist(List<Book> booklist)
{
for (Book book : booklist)
{
System.out.println(book);
}
}
}