Spring IBatis Struts2 集成之一:Spring与IBatis集成

作者:聂勇 欢迎转载,请保留作者信息并说明文章来源!

已经近三年没有使用Spring,IBatis,Hibernate等框架,同部门的另一个项目组赶进度,我们整个项目组都加入开发的行列。Spring,IBatis如何配置,如何使用等都忘光了,上网找一找资料,看看以前写的项目,花了近半天,完成了 Spring + IBatis + Struts2 的集成。好脑袋不如写博客,记录下来,备用。
集成Spring IBatis 的整个过程如下:
引入所有需要的*.jar文件。

  1. 配置web.xml。
  2. 配置log4j。
  3. 配置C3P0数据库连接池。
  4. 配置Spring以及与IBatis集成。
  5. 建立数据库表结构及其domain类和配置
  6. 编写dao类。
  7. 编写单元测试类。

一、所需类库 | Required jar list

c3p0-0.9.1.2.jar // 连接池实现类库
commons-logging-1.0.4.jar
ibatis-2.3.4.726.jar
log4j-1.2.15.jar
ojdbc14-10g.jar // Oracle JDBC驱动类库
spring-2.5.6.jar
spring-test.jar // 单元测试需要用到的类库
junit-4.4.jar // 单元测试需要用到的类库

二、配置web.xml | How to configure web.xml

1、在web.xml中增加如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 载入Spring配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:ApplicationContext.xml
</param-value>
</context-param>
<!-- Spring 监听器配置 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>

三、配置log4j | How to configure log4j

1、在src/main/resouces 目录下建立 log4j.xml,其内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="sis_log_file" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="log/sis.log" />
<param name="DatePattern" value=".yyyyMMddHH" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d %p %t %C{3} %m%n" />
</layout>
</appender>
<root>
<level value="info" />
<appender-ref ref="sis_log_file" />
</root>
</log4j:configuration>

四、配置C3P0数据库连接池 | How to configure c3p0 jdbc connection pool

1、在src/main/resouces 目录下建立 jdbc.properties,其内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#c3p0 数据源配置;
jdbc.driverClassName=oracle.jdbc.OracleDriver
jdbc.url=jdbc:oracle:thin:@192.168.0.8:1521:orcl10
jdbc.username=aofeng
jdbc.password=aofeng
# 连接池完成初始化后建立的连接数量
initialPoolSize=0
# 连接池的最小连接数量
minPoolSize=2
# 连接池的最大连接数量
maxPoolSize=10
# 连接的最大空闲时间(单位:秒),当连接空闲超时此时间后,连接将被回收
maxIdleTime=1000
idleConnectionTestPeriod=1000

2、然后在Spring的配置ApplicationContext.xml中添加如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 载入资源文件,下面的dataSource就引用了资源文件中的配置项 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 数据源配置 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="maxIdleTime" value="${maxIdleTime}"/>
<property name="maxPoolSize" value="${maxPoolSize}"/>
<property name="minPoolSize" value="${minPoolSize}"/>
<property name="initialPoolSize" value="${initialPoolSize}"/>
<property name="idleConnectionTestPeriod" value="${idleConnectionTestPeriod}"/>
</bean>

五、配置Spring与IBatis集成 | How to configure spring integrates with ibatis

1、在src/main/resouces 目录下建立IBatis的SQL映射配置文件SqlMapConfig.xml,其内容如下:

1
2
3
4
5
6
7
8
9
10
<?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>
<settings cacheModelsEnabled="true" useStatementNamespaces="true"/>
<!-- 此处开始添加SqlMap配置文件 -->
</sqlMapConfig>

2、在Spring的配置ApplicationContext.xml中添加如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- IBatis ORM 操作类 -->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:SqlMapConfig.xml" />
</bean>
<!-- Spring的IBatis模板 -->
<bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
<property name="sqlMapClient" ref="sqlMapClient"></property>
</bean>
<!-- 事务管理配置 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

六、建立数据表结构及Domain类 | Create table and its corresponding domain class
1、测试Spring与IBatis集成的表结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
create table USER
(
USER_ID NUMBER(10) not null,
USER_TYPE NUMBER(2),
USER_STATUS NUMBER(1) not null,
USER_NAME VARCHAR2(11) not null,
USER_PASSWD VARCHAR2(20) not null,
CREATE_TIME DATE not null,
UPDATE_TIME DATE not null,
LAST_LOGIN_TIME DATE
);
alter table USER
add constraint PK_USER primary key (USER_ID)
using index;

2、建立User表对应的domain类:User.java,其内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/**
* 建立时间:2011-3-19
*/
package cn.aofeng.sis.domain;
import java.util.Date;
/**
* 表USER对应的持久层POJO.
*
* @author 傲风 <a href="mailto:aofengblog@163.com">aofengblog@163.com</a>
*/
public class User {
/**
* This field corresponds to the database column USER.USER_ID
*/
private Long userId;
/**
* This field corresponds to the database column USER.USER_TYPE
*/
private Short userType;
/**
* This field corresponds to the database column USER.USER_STATUS
*/
private Short userStatus;
/**
* This field corresponds to the database column USER.USER_NAME
*/
private String userName;
/**
* This field corresponds to the database column USER.USER_PASSWD
*/
private String userPasswd;
/**
* This field corresponds to the database column USER.CREATE_TIME
*/
private Date createTime;
/**
* This field corresponds to the database column USER.UPDATE_TIME
*/
private Date updateTime;
/**
* This field corresponds to the database column USER.LAST_LOGIN_TIME
*/
private Date lastLoginTime;
/**
* This method returns the value of the database column USER.USER_ID
*
* @return the value of USER.USER_ID
*/
public Long getUserId() {
return userId;
}
/**
* This method sets the value of the database column USER.USER_ID
*
* @param userId the value for USER.USER_ID
*/
public void setUserId(Long userId) {
this.userId = userId;
}
/**
* This method returns the value of the database column USER.USER_TYPE
*
* @return the value of USER.USER_TYPE
*/
public Short getUserType() {
return userType;
}
/**
* This method sets the value of the database column USER.USER_TYPE
*
* @param userType the value for USER.USER_TYPE
*/
public void setUserType(Short userType) {
this.userType = userType;
}
/**
* This method returns the value of the database column USER.USER_STATUS
*
* @return the value of USER.USER_STATUS
*/
public Short getUserStatus() {
return userStatus;
}
/**
* This method sets the value of the database column USER.USER_STATUS
*
* @param userStatus the value for USER.USER_STATUS
*/
public void setUserStatus(Short userStatus) {
this.userStatus = userStatus;
}
/**
* This method returns the value of the database column USER.USER_NAME
*
* @return the value of USER.USER_NAME
*/
public String getUserName() {
return userName;
}
/**
* This method sets the value of the database column USER.USER_NAME
*
* @param userName the value for USER.USER_NAME
*/
public void setUserName(String userName) {
this.userName = userName;
}
/**
* This method returns the value of the database column USER.USER_PASSWD
*
* @return the value of USER.USER_PASSWD
*/
public String getUserPasswd() {
return userPasswd;
}
/**
* This method sets the value of the database column USER.USER_PASSWD
*
* @param userPasswd the value for USER.USER_PASSWD
*/
public void setUserPasswd(String userPasswd) {
this.userPasswd = userPasswd;
}
/**
* This method returns the value of the database column USER.CREATE_TIME
*
* @return the value of USER.CREATE_TIME
*/
public Date getCreateTime() {
return createTime;
}
/**
* This method sets the value of the database column USER.CREATE_TIME
*
* @param createTime the value for USER.CREATE_TIME
*/
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
/**
* This method returns the value of the database column USER.UPDATE_TIME
*
* @return the value of USER.UPDATE_TIME
*/
public Date getUpdateTime() {
return updateTime;
}
/**
* This method sets the value of the database column USER.UPDATE_TIME
*
* @param updateTime the value for USER.UPDATE_TIME
*/
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
/**
* This method returns the value of the database column USER.LAST_LOGIN_TIME
*
* @return the value of USER.LAST_LOGIN_TIME
*/
public Date getLastLoginTime() {
return lastLoginTime;
}
/**
* This method sets the value of the database column USER.LAST_LOGIN_TIME
*
* @param lastLoginTime the value for USER.LAST_LOGIN_TIME
*/
public void setLastLoginTime(Date lastLoginTime) {
this.lastLoginTime = lastLoginTime;
}
}

3、在与User.java的同一个package下建立User表的SqlMap映射配置文件:USER_SqlMap.xml。其内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?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="USER" >
<resultMap id="BaseResultMap" class="cn.aofeng.sis.domain.User" >
<result column="USER_ID" property="userId" jdbcType="DECIMAL" />
<result column="USER_TYPE" property="userType" jdbcType="DECIMAL" />
<result column="USER_STATUS" property="userStatus" jdbcType="DECIMAL" />
<result column="USER_NAME" property="userName" jdbcType="VARCHAR" />
<result column="USER_PASSWD" property="userPasswd" jdbcType="VARCHAR" />
<result column="CREATE_TIME" property="createTime" jdbcType="DATE" />
<result column="UPDATE_TIME" property="updateTime" jdbcType="DATE" />
<result column="LAST_LOGIN_TIME" property="lastLoginTime" jdbcType="DATE" />
</resultMap>
<select id="selectByUserIdOrUserName" resultMap="BaseResultMap" parameterClass="cn.aofeng.sis.domain.User" >
select USER_ID, USER_TYPE, USER_STATUS, USER_NAME, USER_PASSWD, CREATE_TIME, UPDATE_TIME,
LAST_LOGIN_TIME
from TEST_PTL_USER
<dynamic prepend=" where" >
<isNotNull prepend="or" property="userId" >
USER_ID = #userId:DECIMAL#
</isNotNull>
<isNotNull prepend="or" property="userName" >
USER_NAME= #userName:VARCHAR#
</isNotNull>
</dynamic>
</select>
<delete id="deleteByUserId" parameterClass="Long" >
delete from TEST_PTL_USER
where USER_ID = #value#
</delete>
</sqlMap>

4、在IBatis的配置文件SqlMapConfig.xml中加入USER_SqlMap.xml:

1
<sqlMap resource ="cn/aofeng/sis/domain/USER_SqlMap.xml" />

七、编写DAO类 | Write dao class

1、编写DAO接口类:UserDAO.java,其内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
* 建立时间:2011-3-19
*/
package cn.aofeng.sis.dao;
import cn.aofeng.sis.domain.User;
/**
* 账号表User DAO接口定义.
*
* @author 傲风 <a href="mailto:aofengblog@163.com">aofengblog@163.com</a>
*/
public interface UserDAO {
/**
* 根据账号ID删除账号.
*
* @param userId 账号ID.
* @return 返回1表示成功,返回0表示失败.
*/
int deleteByUserId(Long userId);
/**
* 根据账号ID查询账号信息.
*
* @param userId 账号ID.
* @return 如果查询成功返回一个@{link com.ailk.dm.odomain.testportal.domain.TestPtlUser}实例;查找不到返回null.
*/
User selectByUserId(Long userId);
/**
* 根据账号名称询账号信息.
*
* @param userName 账号名称.
* @return 如果查询成功返回一个@{link com.ailk.dm.odomain.testportal.domain.TestPtlUser}实例;查找不到返回null.
*/
User selectByUserName(String userName);
}

2、编写DAO实现类:UserDAOImpl.java,其内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/**
* 建立时间:2011-3-19
*/
package cn.aofeng.sis.dao;
import cn.aofeng.sis.domain.User;
import javax.annotation.Resource;
import org.springframework.orm.ibatis.SqlMapClientTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
* 账号表User DAO IBatis实现.
*
* @author 傲风 <a href="mailto:aofengblog@163.com">aofengblog@163.com</a>
*/
@ Repository("userDAO")
@ Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class UserDAOImpl implements UserDAO {
@ Resource(name = "sqlMapClientTemplate")
private SqlMapClientTemplate _sqlMapClientTemplate;
protected SqlMapClientTemplate getSqlMapClientTemplate() {
return _sqlMapClientTemplate;
}
protected String getNamespace() {
return "USER";
}
@ Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public int deleteByUserId(Long userId) {
int result = getSqlMapClientTemplate().delete (getNamespace() + ".deleteByUserId", userId);
return result;
}
public User selectByUserId(Long userId) {
User param = new User();
param.setUserId(userId);
return (User)getSqlMapClientTemplate().queryForObject(getNamespace() + ".selectByUserIdOrUserName", param);
}
public User selectByUserName(String userName) {
User param = new User();
param.setUserName(userName);
return (User)getSqlMapClientTemplate().queryForObject(getNamespace() + ".selectByUserIdOrUserName", param);
}
}

八、编写JUnit单元测试 | Write junit testcase class

1、编写JUnit公用类:DaoBaseTestCase.java,其内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/**
* 建立时间:2011-3-19
*/
package cn.aofeng.sis.dao;
import java.util.Date;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import cn.aofeng.sis.domain.UserStatus;
import cn.aofeng.sis.domain.UserType;
/**
* DAO单元测试公用类.
*
* @author 傲风 <a href="mailto:aofengblog@163.com">aofengblog@163.com</a>
*/
public class DaoBaseTestCase extends AbstractTransactionalJUnit4SpringContextTests {
/**
* Default constructor.
*/
public DaoBaseTestCase() {}
/**
* 向数据库插入一条账号记录.
*
* @param userId 账号ID.
* @return 插入记录成功返回1;插入记录失败返回0.
*/
public int insertUser(Long userId) {
final String sql = "insert into USER(USER_ID, USER_TYPE, USER_STATUS, USER_NAME, USER_PASSWD, CREATE_TIME, UPDATE_TIME) values(?, ?, ?, ?, ?, ?, ?)";
int result = simpleJdbcTemplate.update(sql, userId, UserType.OPERATOR, UserStatus.NORMAL, "aofeng" + userId, "aofeng", new Date(), new Date());
return result;
}
/**
* 删除指定账号ID的账号记录.
*
* @param userId 账号ID.
* @return 删除记录成功返回1;删除记录失败返回0.
*/
public int deleteUserByUserId(Long userId) {
final String sql = "delete from USER where USER_ID = ?";
int result = simpleJdbcTemplate.update(sql, userId);
return result;
}
}

2、编写UserDAOImpl的单元测试类:UserDaoImplTest,其内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/**
* 建立时间:2011-3-19
*/
package cn.aofeng.sis.dao;
import static org.junit.Assert. * ;
import javax.annotation.Resource;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.test.context.ContextConfiguration;
import cn.aofeng.sis.domain.User;
/**
* {@link cn.aofemg.sis.dao.UserDAOImpl}的单元测试代码.
*
* @author 傲风 <a href="mailto:aofengblog@163.com">aofengblog@163.com</a>
*/
@ ContextConfiguration(locations = {
"/ApplicationContext.xml"
}, inheritLocations = false)
public class UserDAOImplTest extends DaoBaseTestCase {
protected Long _userId = 1L;
@ Resource(name = "userDAO")
protected UserDAO _userDAO;
/**
* @throws java.lang.Exception
*/
@ Before
public void setUp()throws Exception {
int result = super.insertUser(_userId);
assertEquals(1, result);
}
/**
* @throws java.lang.Exception
*/
@ After
public void tearDown()throws Exception {
@ SuppressWarnings("unused")
int result = super.deleteUserByUserId(_userId);
}
/**
* Test method for {@link cn.aofeng.sis.dao.UserDAOImpl#deleteByUserId(java.lang.Long)}.
*/
@ Test
public void testDeleteByUserIdForExist() {
// 测试删除已经存在的记录.
int result = _userDAO.deleteByUserId(_userId);
assertEquals(1, result);
}
/**
* Test method for {@link cn.aofeng.sis.dao.UserDAOImpl#deleteByUserId(java.lang.Long)}.
*/
@ Test
public void testDeleteByUserIdForNotExist() {
// 测试删除不存在的记录.
int result = _userDAO.deleteByUserId(100L);
assertEquals(0, result);
}
/**
* Test method for {@link cn.aofeng.sis.dao.UserDAOImpl#selectByUserId(java.lang.Long)}.
*/
@ Test
public void testSelectByUserIdForExist() {
// 测试查询已经存在的记录
User record = _userDAO.selectByUserId(_userId);
assertNotNull(record);
assertEquals(1, record.getUserId().longValue());
assertEquals("aofeng" + _userId, record.getUserName());
}
/**
* Test method for {@link cn.aofeng.sis.dao.UserDAOImpl#selectByUserId(java.lang.Long)}.
*/
@ Test
public void testSelectByUserIdForNotExist() {
// 测试查询不存在的记录
User record = _userDAO.selectByUserId(100L);
assertNull(record);
}
/**
* Test method for {@link cn.aofeng.sis.dao.UserDAOImpl#selectByUserName(java.lang.String)}.
*/
@ Test
public void testSelectByUserNameForExist() {
// 测试查询用户名存在的记录
User record = _userDAO.selectByUserName("aofeng" + _userId);
assertNotNull(record);
assertEquals(1, record.getUserId().longValue());
assertEquals("aofeng" + _userId, record.getUserName());
}
/**
* Test method for {@link cn.aofeng.sis.dao.UserDAOImpl#selectByUserName(java.lang.String)}.
*/
@ Test
public void testSelectByUserNameForNotExist() {
// 测试查询用户名不存在的记录
User record = _userDAO.selectByUserName("userNotExists");
assertNull(record);
}
}

3、运行单元测试,结果如下:
单元测试

至此,完成Spring与IBatis的集成。

附录I:项目结构及完整配置 | Appendix I: Project structure and complete configuration

1、项目结构如下图所示:
项目代码结构

2、Spring 配置文件ApplicationContext.xml的完整内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
<!-- 载入资源文件,下面的dataSource就引用了资源文件中的配置项 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<context:component-scan base-package="cn.aofeng.sis" />
<context:annotation-config />
<!-- 数据源配置 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="maxIdleTime" value="${maxIdleTime}"/>
<property name="maxPoolSize" value="${maxPoolSize}"/>
<property name="minPoolSize" value="${minPoolSize}"/>
<property name="initialPoolSize" value="${initialPoolSize}"/>
<property name="idleConnectionTestPeriod" value="${idleConnectionTestPeriod}"/>
</bean>
<!-- IBatis ORM 操作类 -->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:SqlMapConfig.xml" />
</bean>
<!-- Spring的IBatis模板 -->
<bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
<property name="sqlMapClient" ref="sqlMapClient"></property>
</bean>
<!-- 事务管理配置 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>

3、IBatis 配置文件SqlMapConfig.xml的完整内容:

1
2
3
4
5
6
7
8
9
10
<?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>
<settings cacheModelsEnabled="true" useStatementNamespaces="true"/>
<sqlMap resource ="cn/aofeng/sis/domain/USER_SqlMap.xml" />
</sqlMapConfig>

附录II:Spring配置项说明 | Appendix II: Spring configuration items description

1、<context:component-scan/>说明
<context:component-scan/> 配置项不但启用了对类包进行扫描以实施注释驱动 Bean 定义的功能,同时还启用了注释驱动自动注入的功能(即还隐式地在内部注册了 AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor),因此当使用 <context:component-scan/> 后,就可以将 <context:annotation-config/> 移除了。

2、<context:annotationconfig/>说明
<context:annotationconfig/> 将隐式地向 Spring 容器注册 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor 以及 equiredAnnotationBeanPostProcessor 这 4 个 BeanPostProcessor。

3、<tx:annotation-driven /> 说明
<tx:annotation-driven /> 表示使用声明式事务。如果用 ‘transactionManager’ 来定义 PlatformTransactionManager bean的名字的话,你就可以忽略 <tx:annotation-driven/> 标签里的 ‘transaction-manager’ 属性。 如果 PlatformTransactionManager bean你要通过其它名称来注入的话,你必须用 ‘transaction-manager’ 属性来指定它。