本篇文章的第一部分带你走q一pd的“fash Track”,带你览一遍SQL maps的简单应用。在walkthrough之后Q将有详l的?
Fast Track: Preparing to Use SQL Maps
SQL Maps对不好的数据库模型甚臛_象模型都有很强的容忍度。尽如此,q是推荐你用最佛_跉|设计你的的数据库模型和对象模型。通过q样Q你得到更q净的设计和更好的性能?/p>
最单的开始就是分析你在做的内容,商业模型是什么样的,表结构是什么样的,它们怎么样互相发生关pR第一个例子,我们q单的实现一个典型的PersioncR?/p>
Person.java package examples.domain; //imports implied? public class Person { private int id; private String firstName; private String lastName; private Date birthDate; private double weightInKilograms; private double heightInMeters; public int getId () { return id; } public void setId (int id) { this.id = id; } //…let’s assume we have the other getters and setters to save space?br />} |
现在persion对象怎么映射到数据库QSQL Mapsq不U束你必要一个表一个对象或者多个表一个对象这U映关pR因Z可以自由使用SQL语句Q所以约束很。在q个例子里,我们使用下面单的表,实现一个表对象一个对象的映射关系?/p>
Person.sql CREATE TABLE PERSON( PER_ID NUMBER (5, 0) NOT NULL, PER_FIRST_NAME VARCHAR (40) NOT NULL, PER_LAST_NAME VARCHAR (40) NOT NULL, PER_BIRTH_DATE DATETIME , PER_WEIGHT_KG NUMBER (4, 2) NOT NULL, PER_HEIGHT_M NUMBER (4, 2) NOT NULL, PRIMARY KEY (PER_ID) ) |
Fast Track: The SQL Map Configuration File
当我们对我们的工作感到很舒适时Q最好的开始就是SQL Map的配|文件。这个文件是SQL Map实现的根配置?/p>
配置文g是XML文gQ我们用它来配置属性,JDBC DataSources ?SQL Maps。它l我们一个便利的地方可以集中配置不同的DataSource。这个框架支持iBATIS SimpleDataSource, Jakarta DBCP (Commons)Q以及其他Q何可以通过JNDI context来访问的DataSource。我们在以后详l讨个问题。现在我们用Jakarta DBCPQ结构很单,象上面这个例子,它的配置文g如下?/p>
SqlMapConfigExample.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sql-map-config PUBLIC "-//iBATIS.com//DTD SQL Map Config 1.0//EN" "http://www.ibatis.com/dtd/sql-map-config.dtd">
<!-- Always ensure to use the correct XML header as above! -->
<sql-map-config>
<!-- The properties (name=value) in the file specified here can be used placeholders in this config file (e.g. ?{driver}? The file is relative to the classpath and is completely optional. -->
<properties resource="examples/sqlmap/maps/SqlMapConfigExample.properties" />
<!-- These settings control SqlMap configuration details, primarily to do with transaction management. They are all optional (more detail later in this document). -->
<settings maxExecute="300" maxExecutePerConnection="1" maxTransactions="10" statementCacheSize="75" useGlobalTransactions="false" useBeansMetaClasses=”true?> <!-- Configure a datasource to use with this SQL Map using Jakarta DBCP. Notice the use of the properties from the above resource --> <datasource name="basic" default = "true" factory-class="com.ibatis.db.sqlmap.datasource.DbcpDataSourceFactory"> <property name="JDBC.Driver" value="${driver}"/> <property name="JDBC.ConnectionURL" value="${url}"/> <property name="JDBC.Username" value="${username}"/> <property name="JDBC.Password" value="${password}"/> <property name="Pool.MaximumActiveConnections" value="10"/> <property name="Pool.MaximumIdleConnections" value="5"/> <property name="Pool.MaximumWait" value="60000"/> </datasource>
<!-- Identify all SQL Map XML files to be loaded by this SQL map. Notice the paths are relative to the classpath. For now, we only have one?-->
<sql-map resource="examples/sqlmap/maps/Person.xml" />
</sql-map-config>
|
SqlMapConfigExample.properties
# This is just a simple properties file that simplifies automated configuration # of the SQL Maps configuration file (e.g. by Ant builds or continuous # integration tools for different environments?etc.) # These values can be used in any property value in the file above (e.g. ?{driver}? # Using a properties file such as this is completely optional.
driver=oracle.jdbc.driver.OracleDriver url=jdbc:oracle:thin:@localhost:1521:oracle1 username=jsmith password=test
|
Fast Track: The SQL Map File(s)
现在我们已经配置好DataSource了,然后p准备核心配置文g了。我们需要准备一个实际的SQL Map文g来存放SQL语句和以及用作映的参数对象和结果对象(分别是输入和输出Q?/p>
l箋我们上面的示例。让我们为PersoncdPerson表徏立映关pR我们先建立一个标准结构,和一个简单的select说明?/p>
Person.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sql-map PUBLIC "-//iBATIS.com//DTD SQL Map 1.0//EN" "http://www.ibatis.com/dtd/sql-map.dtd">
<sql-map name="Person">
<mapped-statement name="getPerson" result-class="examples.domain.Person"> SELECT PER_ID as id, PER_FIRST_NAME as firstName, PER_LAST_NAME as lastName, PER_BIRTH_DATE as birthDate, PER_WEIGHT_KG as weightInKilograms, PER_HEIGHT_M as heightInMeters FROM PERSON WHERE PER_ID = #value# </mapped-statement> </sql-map> |
上面的示例显CZ一个SQL map的一个最单的l成。它使用了SQL Maps的一个特性,是自动Ҏ字段名和JAVABean属?Map的主?名徏立对应关pR?value#象征着一个输入参敎ͼ多情况下Q?value"意味着我们使用一个基本类?(e.g. Integer; but we’re not limited to this).
因ؓ非常单,所以用这U方法有一些限制。首先不能明指定每个字D늚输入cd。没有办法自动加载相x据(复杂cdQ,同时有一些性能影响Q因为它使用了ResultSetMetaData。通过使用result-mapQ我们可以克服所有这些限制。但是现在,单是我们的目标。同是,以后我们可以随便修改成其他方式(不需要修改java代码Q?/p>
多数JAVAE序不仅d数据Q还要更Ҏ据。我们已l看到怎样在Map-statement里用select 了,那Update,delete和Insert是什么样的?一个好消息Q跟select没有什么区别。下面我们就完成一个我们的Person Sql MapQ包括一pd的statement用来操作和修Ҏ据?/p>
Person.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sql-map
PUBLIC "-//iBATIS.com//DTD SQL Map 1.0//EN"
"http://www.ibatis.com/dtd/sql-map.dtd">
<sql-map name="Person">
<!-- Use primitive wrapper type (e.g. Integer) as parameter and allow results to
be auto-mapped results to Person object (JavaBean) properties -->
<mapped-statement name="getPerson" result-class="examples.domain.Person">
SELECT
PER_ID as id,
PER_FIRST_NAME as firstName,
PER_LAST_NAME as lastName,
PER_BIRTH_DATE as birthDate,
PER_WEIGHT_KG as weightInKilograms,
PER_HEIGHT_M as heightInMeters
FROM PERSON
WHERE PER_ID = #value#
</mapped-statement>
<!-- Use Person object (JavaBean) properties as parameters for insert. Each of the
parameters in the #hash# symbols is a JavaBeans property. -->
<mapped-statement name="insertPerson" >
INSERT INTO
PERSON (PER_ID, PER_FIRST_NAME, PER_LAST_NAME,
PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT_M)
VALUES (#id#, #firstName#, #lastName#,
#birthDate#, #weightInKilograms#, #heightInMeters#)
</mapped-statement>
<!-- Use Person object (JavaBean) properties as parameters for update. Each of the
parameters in the #hash# symbols is a JavaBeans property. -->
<mapped-statement name="updatePerson" >
UPDATE PERSON
SET (PER_ID = PER_FIRST_NAME = #firstName#,
PER_LAST_NAME = #lastName#, PER_BIRTH_DATE = #birthDate#,
PER_WEIGHT_KG = #weightInKilograms#,
PER_HEIGHT_M = #heightInMeters#)
WHERE PER_ID = #id#
</mapped-statement>
<!-- Use Person object (JavaBean) “id?properties as parameters for delete. Each of the
parameters in the #hash# symbols is a JavaBeans property. -->
<mapped-statement name="deletePerson" >
DELETE PERSON
WHERE PER_ID = #id#
</mapped-statement>
</sql-map>
|
Fast Track: Programming with the SQL Map Framework
现在我们已经完成了所有的配置和映,剩下的就是写JAVA代码了。第一步是配置SQL Map。加载我们前面配|好的SQL Map XML文g是很单的。加载XML以后Q就可以在框枉使用资源cR?/p>
String resource = “com/ibatis/example/sql-map-config.xml? Reader reader = Resources.getResourceAsReader (resource); SqlMap sqlMap = XmlSqlMapBuilder.buildSqlMap(reader); |
SQL Map对象是线E安全的Q意味着是长期生存的。对于一个运行的pȝ来说Q你只要配置一ơ。所以它可以很好的成Z个基cȝ静态对象(比如Q一个BASE Daoc)Q也怽更喜Ƣ集中配|ƈ成ؓ全局可见Q你可以把它包装在你自己的工L中。比如说Q?/p>
private MyAppSqlConfig {
private static final SqlMap sqlMap;
static {
try {
String resource = “com/ibatis/example/sql-map-config.xml?
Reader reader = Resources.getResourceAsReader (resource);
sqlMap = XmlSqlMapBuilder.buildSqlMap(reader);
} catch (Exception e) {
// If you get an error at this point, it matters little what it was. It is going to be
// unrecoverable and we will want the app to blow up good so we are aware of the
// problem. You should always log such errors and re-throw them in such a way that
// you can be made immediately aware of the problem.
e.printStackTrace();
throw new RuntimeException (“Error initializing MyAppSqlConfig class. Cause: ?+ e);
}
}
public static getSqlMapInstance () {
return sqlMap;
}
}
|
从数据库d对象
现在SQL Map实例已经完成初始化,q且很容易访?我们可以使用它了。首先我们用它从数据库中取得一个Person对象?举例Q我们假设数据库中有10条记录,PER_ID分别从是1?0)
Z从数据库中取得一个Person对象Q我们需要SQL Map实例Qmapped statement的名UC及PER_ID?让我们读?5。
?br />SqlMap sqlMap = MyAppSqlMapConfig.getSqlMapInstance(); // as coded above ?br />Integer personPk = new Integer(5); Person person = (Person) sqlMap.executeQueryForObject (“getPerson? personPk); ?/td>
|
把对象写到数据库?/p>
现在我们已经从数据库取得一个对象,让我们修改一些|我们修改n高和体重。 ?/p>
?br />person.setHeightInMeters(1.83); // person as read from the database above person.setWeightInKilograms(86.36); ?br />sqlMap.executeUpdate(“updatePerson? person); ?/td>
|
如果我们要删除一个对象,也一L单?/p>
?br />sqlMap.executeUpdate(“deletePerson? person); ?/td>
|
同样的,新插入一个对象也cM?/p>
Person newPerson = new Person(); newPerson.setId(11); // you would normally get the ID from a sequence or custom table newPerson.setFirstName(“Clinton?; newPerson.setLastName(“Begin?; newPerson.setBirthDate (null); newPerson.setHeightInMeters(1.83); newPerson.setWeightInKilograms(86.36); ?br />sqlMap.executeUpdate (“insertPerson? newPerson); ?/td>
|
End of Fast Track(l束?
This is the end of the quick walkthrough. The next several sections will discuss the features of the SqlMap framework in more detail.
|