與現在最流行的SSH相比較,Tapestry能夠完全替代其中Struts2和Spring,但是他還是需要一個ORM的框架。IBatis由于比較低的學習曲線,也受到很多人的喜愛。尤其是在IBatis3中引入了許多新的概念和想法,使用更加安全和便利。
本文主要介紹如何將Tapestry5.1和IBatis3進行整合。
簡要步驟:
1. 準備工作
2. 數據庫的建立
3. POJO的建立
4. IBatis相關配置文件的創建
5. Tapestry相關代碼的完成
概要說明:
1、準備工作。這一部分是比較簡單的,Eclipse之類的開發環境是必需的。Tapestry5.1、IBatis3(目前還是Beta7)、數據庫(我使用的是MySql)的下載安裝。
2、數據庫的建立,由于是示例,所以數據庫的建立也非常簡單,只有一張User表,3個字段,Id,Name,Password
3、com.sample.User類,對應數據庫表的3個字段,生成User類
4、IBatis配置文件:Configuration.xml,UserMapper.xml,jdbc.properties的生成, 前兩個必需,最后一個可選.
5、在AppModule里,使用build方法, 添加服務生成IBatis3的SqlSessionFactory, 在需要使用SqlSessionFactory的地方,使用@InjectService注入即可
詳細說明:
1、大家到各自的網站上下載相應的包好了。我只羅列一下我所用到的Lib:
antlr-runtime-3.1.1.jar
commons-codec-1.3.jar
commons-lang-2.4.jar
ibatis-3-core-3.0.0.216.jar
javassist.jar
log4j-1.2.14.jar
mysql-connector-java-5.0.5.jar
slf4j-api-1.5.10.jar
slf4j-log4j12-1.5.10.jar
stax2-api-3.0.1.jar
tapestry-core-5.1.0.5.jar
tapestry-ioc-5.1.0.5.jar
tapestry5-annotations-5.1.0.5.jar
woodstox-core-lgpl-4.0.7.jar
2、Create Table
DROP TABLE IF EXISTS `test`.`user`;
CREATE TABLE `test`.`user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`password` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
3、
package com.sample.model;
public class User {
private long id;
private String name;
private String password;
// getter and setter ....
}
4、我把Configuration.xml和UserMapper.xml都放在src目錄下,這樣在部署的時候,就是生成在classes,也就是類路徑的根目錄下。
Configuration.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-config.dtd">
<configuration>
<properties resource="jdbc.properties">
</properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="poolPingEnabled" value="${pingenable}"/>
<property name="poolPingQuery" value="${pingquery}"/>
<property name="poolPingConnectionsNotUsedFor" value="${pingnotusetime}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
UserMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.sample.model.UserMapper">
<select id="selectUser" parameterType="int" resultType="com.sample.model.User">
select * from user where id = #{id}
</select>
</mapper>
jdbc.properties:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost/test?autoReconnect=true
jdbc.username=root
jdbc.password=root
pingenable=true
pingquery=SELECT 1
pingoldertime=0
pingnotusetime=3600000
5、
package com.sample.web.services;
public class AppModule {
public static SqlSessionFactory buildSqlSessionFactory() {
try {
String resource = "Configuration.xml";
Reader reader = Resources.getResourceAsReader(resource);
return new SqlSessionFactoryBuilder().build(reader);
} catch (Exception e) {
logger.warn("failed to build SqlSessionFactory: ", e);
return null;
}
}
private static Logger logger = LoggerFactory.getLogger(AppModule.class);
}
package com.sample.model;
public interface UserMapper {
public User selectUser(int id);
}
package com.pc.sample.web.pages;
public class Layout {
@InjectService("SqlSessionFactory")
private SqlSessionFactory sqlMapper;
public String getUserName() {
if ( sqlMapper == null ) {
return "null-mapper";
}
SqlSession session = sqlMapper.openSession();
try {
UserMapper userMapper = session.getMapper(UserMapper.class);
if ( userMapper == null ) {
return "null-userMapper";
}
User user = userMapper.selectUser(1);
if ( user == null ) {
return "null-user";
}
return user.getName();
} catch (Exception e) {
return "exception-" + e.getMessage();
} finally {
session.close();
}
}
}
幾個注意事項:
1,
因為我的IBatis的配置文件Configuration.xml是放在類路徑的根目錄下,所以在初始化SqlSessionFactory的時候,直
接用String resource =
"Configuration.xml";就行了,否則需要添加相應的路徑,比如:把Configuration.xml與User類放在一起,也就是在
com.sample.model這個package中,那么就要寫成:String resource =
"com/sample/model/Configuration.xml";
同樣,在Configuration.xml中,指定UserMapper.xml的規則也是這樣的。
2,UserMapper的使用。Mapper的使用是IBatis3中才有的新功能,也是IBatis用戶指南中推薦使用的方式。因為這樣使用的話,就完全避免了類型的強制轉換,實現了類型安全。
需要注意的是UserMapper只是一個接口。我們不需要提供這個接口的具體實現。IBatis3會自動生成一個具體的實例。
其中的方法名必須與UserMapper.xml中的select語句的id一樣。在我的例子中是selectUser.
另外,此方法的返回值的類型必須與UserMapper.xml中配置的returnType一致。
最后要提醒的是UserMapper.xml中的namespace必須是UserMapper的全類名,在本例中就是com.sample.model.UserMapper