jPetStore 源码分析
jPetStore 作为ibatis的一个成功实例,此刻我们就来分析下它的结构
下面这个类是dao的初始化类,开始的静态块负责把数据库建立
...
private static final String resource = "com/ibatis/jpetstore/persistence/dao.xml";
private static final DaoManager daoManager;
static {
try {
daoManager = newDaoManager(null);
Properties props = Resources.getResourceAsProperties("properties/database.properties");
String url = props.getProperty("url");
String driver = props.getProperty("driver");
String username = props.getProperty("username");
String password = props.getProperty("password");
if (url.equals("jdbc:hsqldb:mem:jpetstore")) {
Class.forName(driver).newInstance();
Connection conn = DriverManager.getConnection(url, username, password);
try {
ScriptRunner runner = new ScriptRunner(conn, false, false);
runner.setErrorLogWriter(null);
runner.setLogWriter(null);
runner.runScript(Resources.getResourceAsReader("ddl/hsql/jpetstore-hsqldb-schema.sql"));
runner.runScript(Resources.getResourceAsReader("ddl/hsql/jpetstore-hsqldb-dataload.sql"));
} finally {
conn.close();
}
}
} catch (Exception e) {
throw new RuntimeException("Description. Cause: " + e, e);
}
}
public static DaoManager getDaoManager() {
return daoManager;
}
public static DaoManager newDaoManager(Properties props) {
try {
Reader reader = Resources.getResourceAsReader(resource);
return DaoManagerBuilder.buildDaoManager(reader, props);
} catch (Exception e) {
throw new RuntimeException("Could not initialize DaoConfig. Cause: " + e, e);
}
}
}
静态方法newDaoManager是读取dao.xml中的配置创建DaoManagerBuilder对象实例
在service层通过类似如下的语句来生产数据操作对象:
DaoManager daoMgr = DaoConfig.getDaoManager();
this.accountDao = (AccountDao) daoMgr.getDao(AccountDao.class);
AccountDao是一个数据库操作接口
这些类包括在ibatis-dao-2.jar中
在dao层通过调用template包中的一些类如:
queryForObject("getAccountByUsernameAndPassword", account);
其中getAccountByUsernameAndPassword是映射文件中配置的sql的名称,account是
配置中规定的查询条件封装类实例
下面我们来看看配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE daoConfig
PUBLIC "-//ibatis.apache.org//DTD DAO Configuration 2.0//EN"
"http://ibatis.apache.org/dtd/dao-2.dtd">
<daoConfig>
<context>
<transactionManager type="SQLMAP">
<property name="SqlMapConfigResource"
value="com/ibatis/jpetstore/persistence/sqlmapdao/sql/sql-map-config.xml"/>
</transactionManager>
<dao interface="com.ibatis.jpetstore.persistence.iface.ItemDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.ItemSqlMapDao"/>
<dao interface="com.ibatis.jpetstore.persistence.iface.SequenceDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.SequenceSqlMapDao"/>
<dao interface="com.ibatis.jpetstore.persistence.iface.AccountDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.AccountSqlMapDao"/>
<dao interface="com.ibatis.jpetstore.persistence.iface.CategoryDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.CategorySqlMapDao"/>
<dao interface="com.ibatis.jpetstore.persistence.iface.ProductDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.ProductSqlMapDao"/>
<dao interface="com.ibatis.jpetstore.persistence.iface.OrderDao"
implementation="com.ibatis.jpetstore.persistence.sqlmapdao.OrderSqlMapDao"/>
</context>
</daoConfig>
这是dao.xml。它在初始化DaoManagerBuilder时被调用
...
<transactionManager type="SQLMAP">
<property name="SqlMapConfigResource"
value="com/ibatis/jpetstore/persistence/sqlmapdao/sql/sql-map-config.xml"/>
</transactionManager>
...
引用了sql-map-config.xml配置文件
其他的配置项是对dao接口以及实现类的描述
现在我们把视线跳转到ibatis的sql-map-config.xml配置上来
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<properties resource="properties/database.properties"/>
<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property value="${driver}" name="JDBC.Driver"/>
<property value="${url}" name="JDBC.ConnectionURL"/>
<property value="${username}" name="JDBC.Username"/>
<property value="${password}" name="JDBC.Password"/>
</dataSource>
</transactionManager>
<sqlMap resource="com/ibatis/jpetstore/persistence/sqlmapdao/sql/Account.xml"/>
<sqlMap resource="com/ibatis/jpetstore/persistence/sqlmapdao/sql/Category.xml"/>
<sqlMap resource="com/ibatis/jpetstore/persistence/sqlmapdao/sql/Product.xml"/>
<sqlMap resource="com/ibatis/jpetstore/persistence/sqlmapdao/sql/Sequence.xml"/>
<sqlMap resource="com/ibatis/jpetstore/persistence/sqlmapdao/sql/LineItem.xml"/>
<sqlMap resource="com/ibatis/jpetstore/persistence/sqlmapdao/sql/Order.xml"/>
<sqlMap resource="com/ibatis/jpetstore/persistence/sqlmapdao/sql/Item.xml"/>
</sqlMapConfig>
在<transactionManager type="JDBC">配置项中配置采用通过传统JDBC commit/rollback实现事务支持
dataSource中配置的是所用的连接池类型
SIMPLE是ibatis内置的dataSource实现,其中实现了一个简单的
数据库连接池机制, 对应ibatis 实现类为
com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory。
sqlMap节点是配置具体dao的映射引用
以下是Account类的sql映射配置片段
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="Account">
<typeAlias alias="account" type="com.ibatis.jpetstore.domain.Account"/>
...
<update id="updateAccount" parameterClass="account">
UPDATE ACCOUNT SET
EMAIL = #email#,
FIRSTNAME = #firstName#,
LASTNAME = #lastName#,
STATUS = #status#,
ADDR1 = #address1#,
ADDR2 = #address2:VARCHAR#,
CITY = #city#,
STATE = #state#,
ZIP = #zip#,
COUNTRY = #country#,
PHONE = #phone#
WHERE USERID = #username#
</update>
...
再#之间内容与pojo类的属性对应
由于ibatis采用的是“半自动化”的ORM机制,所以具体的sql语句需要自己编写。这样
sql的优化也是自己来完成的。这样对sql性能要求较高的系统是个好消息。
本文对jPetStore项目进行了深入的源码分析,重点探讨了DAO层的初始化,如何通过`DaoManager`获取数据库操作对象,并详细介绍了接口`AccountDao`的使用。在DAO层,接口的实现依赖于iBatis的模板方法,如`queryForObject`,配合映射文件中的SQL语句进行数据操作。配置文件如`dao.xml`和`sql-map-config.xml`对于理解jPetStore的数据访问逻辑至关重要,其中事务管理和数据库连接池配置也进行了说明。
2213

被折叠的 条评论
为什么被折叠?



