ibatis初体验的第一个例子(jpetstore前奏)
学习jpetstote4.0首先要熟悉ibatis
SQL Maps对不好的数据库模型甚至对象模型都有很强的容忍度。尽管如此,还是推荐你使用最佳实践来设
计你的的数据库模型和对象模型。通过这样,你将得到更干净的设计和更好的性能。
最简单的开始就是分析你在做的内容,商业模型是什么样的,表结构是什么样的,它们怎么样互相发生
关系。第一个例子,我们就简单的实现一个典型的Persion类。
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…
}
现在persion对象怎么映射到数据库?SQL Maps并不约束你必须要一个表一个对象或者多个表一个对象这
种映射关系。因为你可以自由使用SQL语句,所以约束很小。在这个例子里,我们使用下面简单的表,实
现一个表对象一个对象的映射关系。
Person.sql
CREATE TABLE `person` (
`PER_ID` int(11) NOT NULL AUTO_INCREMENT,
`PER_FIRST_NAME` varchar(40) NOT NULL,
`PER_LAST_NAME` varchar(40) NOT NULL,
`PER_BIRTH_DATE` datetime DEFAULT NULL,
`PER_WEIGHT_KG` int(11) NOT NULL,
`PER_HEIGHT_M` int(11) NOT NULL,
PRIMARY KEY (`PER_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=gbk;
Fast Track: The SQL Map Configuration File
当我们对我们的工作感到很舒适时,最好的开始就是SQL Map的配置文件。这个文件是SQL Map实现的根配
置。
配置文件是XML文件,我们用它来配置属性,JDBC DataSources 和 SQL Maps。它给我们一个便利的地方
可以集中配置不同的DataSource。这个框架支持iBATIS SimpleDataSource, Jakarta DBCP (Commons),
以及其他任何可以通过JNDI context来访问的DataSource。我们在以后将详细讨论这个问题。现在我们用
Jakarta DBCP,结构很简单,象上面这个例子,它的配置文件如下。
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">
<sql-map-config>
<properties resource="examples/domain/SqlMapConfigExample.properties" />
<settings maxExecute="300"
maxExecutePerConnection="1"
maxTransactions="10"
statementCacheSize="75"
useGlobalTransactions="false"
useBeansMetaClasses="true"/>
<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>
<sql-map resource="examples/domain/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=com.mysql.jdbc.Driver
url= jdbc:mysql://localhost:3306/test
username=root
password=860317
Fast Track: The SQL Map File(s)
现在我们已经配置好DataSource了,然后就要准备核心配置文件了。我们需要准备一个实际的SQL
Map文件来存放SQL语句和以及用作映射的参数对象和结果对象(分别是输入和输出)。
继续我们上面的示例。让我们为Person类和Person表建立映射关系。我们先建立一个标准结构,和一个简
单的select说明。
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>
<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>
<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>
<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文件是很简单的。加载XML以后,就可以在框架里使用资源类。
String resource = “com/ibatis/example/sql-map-config.xml”;
Reader reader = Resources.getResourceAsReader (resource);
SqlMap sqlMap = XmlSqlMapBuilder.buildSqlMap(reader);
SQL Map对象是线程安全的,意味着是长期生存的。对于一个运行的系统来说,你只要配置一次。所以它
可以很好的成为一个基类的静态对象(比如,一个BASE Dao类),也许你更喜欢集中配置并成为全局可见
,你可以把它包装在你自己的工具类中。比如说:
package examples.domain;
import java.io.Reader;
import com.ibatis.common.resources.Resources;
import com.ibatis.db.sqlmap.SqlMap;
import com.ibatis.db.sqlmap.XmlSqlMapBuilder;
public class MysqlCon {
private static final SqlMap sqlMap;
static {
try {
String resource = "examples/domain/SqlMapConfigExample.xml";
Reader reader = Resources.getResourceAsReader (resource);
sqlMap = XmlSqlMapBuilder.buildSqlMap(reader);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException ("Error initializing MyAppSqlConfig class. Cause: " + e);
}
}
public static SqlMap getSqlMapInstance() {
return sqlMap;
}
}
从数据库读取对象
现在SQL Map实例已经完成初始化,并且很容易访问,我们可以使用它了。首先我们用它从数据库中取得
一个Person对象。(举例,我们假设数据库中有10条记录,PER_ID分别从是1到10)
为了从数据库中取得一个Person对象,我们需要SQL Map实例,mapped statement的名称以及PER_ID号,让
我们读取#5。
SqlMap sqlMap = MysqlCon.getSqlMapInstance(); // as coded above
Integer personPk = new Integer(5);
Person person = (Person) sqlMap.executeQueryForObject ("getPerson",
personPk);
System.out.print(person.getFirstName());
把对象写到数据库中
现在我们已经从数据库取得一个对象,让我们修改一些值,我们将修改身高和体重。
…
person.setHeightInMeters(1.83); // person as read from the database above
person.setWeightInKilograms(86.36);
…
sqlMap.executeUpdate(“updatePerson”, person);
…
如果我们要删除一个对象,也一样的简单。
…
sqlMap.executeUpdate(“deletePerson”, person);
…
同样的,新插入一个对象也类似。
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);
…
sqlMap.executeUpdate (“insertPerson”, newPerson);
…