一、创建 SSMDemo 项目

点击菜单,选择“File -> New Project” 创建新项目。选择使用 archetype 中的 maven-webapp 模版创建。

玩转SSH(四):Struts + Spring + MyBatis_struts

输入对应的项目坐标GroupId 和 ArtifactId。

玩转SSH(四):Struts + Spring + MyBatis_spring_02

之后在项目名称中填入项目名称,这里我填的 ProjectName 和上文的 ArtifactId 相同,都是 SSMDemo。

点击确定后,等待 Maven 帮我们构建好项目的目录结构。当控制台显示 BUILD SUCCESS 就表示初始化完成了。

玩转SSH(四):Struts + Spring + MyBatis_struts_03

初始化完成后的目录结构是这样的:

玩转SSH(四):Struts + Spring + MyBatis_spring_04

在 main 目录下创建 java 目录并将其设置为源码目录:

玩转SSH(四):Struts + Spring + MyBatis_bc_05

之后创建 com.chanshuyi.action 等包,创建完成后的目录结构如下:

玩转SSH(四):Struts + Spring + MyBatis_bc_06

二、导入依赖的包和插件

设置 POM.XML 配置文件中的全局属性:

<!-- 声明全局属性 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<struts.version>2.3.24</struts.version>
<springframework.version>4.1.6.RELEASE</springframework.version>
<junit.version>3.8.1</junit.version>
<commonsLogging.version>1.2</commonsLogging.version>
</properties>

依次引入 Struts、MyBatis、Spring、MySQL、Druid、JUnit、Log4J 等的依赖 Jar 包:

<!-- ********************** Struts ********************** -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${struts.version}</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>${struts.version}</version>
</dependency>
<!-- Struts 注解 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
<version>${struts.version}</version>
</dependency>

<!-- ********************** MyBatis ********************** -->
<!-- MyBatis 核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.1.1</version>
</dependency>
<!-- 添加mybatis与Spring整合的核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.1.1</version>
</dependency>

<!-- ********************** Spring ********************** -->
<!-- 添加Spring-core包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- 添加spring-tx包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- Spring ORM 相关-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- 添加spring-jdbc包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${springframework.version}</version>
</dependency>
<!--添加spring-web包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- 添加spring-context包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${commonsLogging.version}</version>
</dependency>
<!--添加aspectjweaver包 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.5</version>
</dependency>

<!-- ********************** DB Connection ********************** -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
<!-- Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.6</version>
</dependency>

<!-- ********************** 其他 ********************** -->
<!-- 单元测试 JUnit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- 日志记录 Log4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.6</version>
</dependency>

之后导入 Tomcat 启动插件,我们将通过 Maven 方式启动 Tomcat,这样就不必在本地配置一个 Tomcat 服务器。

<!--  Maven的Tomcat插件(支持Maven以"tomcat7:run"方式启动web项目)  -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>5050</port>
<path>/</path>
<uriEncoding>UTF-8</uriEncoding>
<finalName>mgr</finalName>
<server>tomcat7</server>
</configuration>
</plugin>

配置完成后的 POM.XML 是这样的:

玩转SSH(四):Struts + Spring + MyBatis_struts_07

玩转SSH(四):Struts + Spring + MyBatis_bc_08

1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3 <modelVersion>4.0.0</modelVersion>
4 <groupId>com.chanshuyi.SSMDemo</groupId>
5 <artifactId>SSMDemo</artifactId>
6 <packaging>war</packaging>
7 <version>1.0-SNAPSHOT</version>
8 <name>SSMDemo Maven Webapp</name>
9 <url>http://maven.apache.org</url>
10
11 <!-- 声明全局属性 -->
12 <properties>
13 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
14 <struts.version>2.3.24</struts.version>
15 <springframework.version>4.1.6.RELEASE</springframework.version>
16 <junit.version>3.8.1</junit.version>
17 <commonsLogging.version>1.2</commonsLogging.version>
18 </properties>
19
20 <dependencies>
21 <!-- ********************** Struts ********************** -->
22 <dependency>
23 <groupId>org.apache.struts</groupId>
24 <artifactId>struts2-core</artifactId>
25 <version>${struts.version}</version>
26 </dependency>
27 <dependency>
28 <groupId>org.apache.struts</groupId>
29 <artifactId>struts2-spring-plugin</artifactId>
30 <version>${struts.version}</version>
31 </dependency>
32 <!-- Struts 注解 -->
33 <dependency>
34 <groupId>org.apache.struts</groupId>
35 <artifactId>struts2-convention-plugin</artifactId>
36 <version>${struts.version}</version>
37 </dependency>
38
39 <!-- ********************** MyBatis ********************** -->
40 <!-- MyBatis 核心包 -->
41 <dependency>
42 <groupId>org.mybatis</groupId>
43 <artifactId>mybatis</artifactId>
44 <version>3.1.1</version>
45 </dependency>
46 <!-- 添加mybatis与Spring整合的核心包 -->
47 <dependency>
48 <groupId>org.mybatis</groupId>
49 <artifactId>mybatis-spring</artifactId>
50 <version>1.1.1</version>
51 </dependency>
52
53 <!-- ********************** Spring ********************** -->
54 <!-- 添加Spring-core包 -->
55 <dependency>
56 <groupId>org.springframework</groupId>
57 <artifactId>spring-core</artifactId>
58 <version>${springframework.version}</version>
59 </dependency>
60 <!-- 添加spring-tx包 -->
61 <dependency>
62 <groupId>org.springframework</groupId>
63 <artifactId>spring-tx</artifactId>
64 <version>${springframework.version}</version>
65 </dependency>
66 <!-- Spring ORM 相关-->
67 <dependency>
68 <groupId>org.springframework</groupId>
69 <artifactId>spring-orm</artifactId>
70 <version>${springframework.version}</version>
71 </dependency>
72 <!-- 添加spring-jdbc包 -->
73 <dependency>
74 <groupId>org.springframework</groupId>
75 <artifactId>spring-jdbc</artifactId>
76 <version>${springframework.version}</version>
77 </dependency>
78 <!--添加spring-web包 -->
79 <dependency>
80 <groupId>org.springframework</groupId>
81 <artifactId>spring-web</artifactId>
82 <version>${springframework.version}</version>
83 </dependency>
84 <!-- 添加spring-context包 -->
85 <dependency>
86 <groupId>org.springframework</groupId>
87 <artifactId>spring-context</artifactId>
88 <version>${springframework.version}</version>
89 </dependency>
90 <dependency>
91 <groupId>org.springframework</groupId>
92 <artifactId>spring-beans</artifactId>
93 <version>${springframework.version}</version>
94 </dependency>
95 <dependency>
96 <groupId>commons-logging</groupId>
97 <artifactId>commons-logging</artifactId>
98 <version>${commonsLogging.version}</version>
99 </dependency>
100 <!--添加aspectjweaver包 -->
101 <dependency>
102 <groupId>org.aspectj</groupId>
103 <artifactId>aspectjweaver</artifactId>
104 <version>1.8.5</version>
105 </dependency>
106
107 <!-- ********************** DB Connection ********************** -->
108 <dependency>
109 <groupId>mysql</groupId>
110 <artifactId>mysql-connector-java</artifactId>
111 <version>5.1.21</version>
112 </dependency>
113 <!-- Druid -->
114 <dependency>
115 <groupId>com.alibaba</groupId>
116 <artifactId>druid</artifactId>
117 <version>1.0.6</version>
118 </dependency>
119
120 <!-- ********************** 其他 ********************** -->
121 <!-- 单元测试 JUnit -->
122 <dependency>
123 <groupId>junit</groupId>
124 <artifactId>junit</artifactId>
125 <version>${junit.version}</version>
126 <scope>test</scope>
127 </dependency>
128 <!-- 日志记录 Log4j -->
129 <dependency>
130 <groupId>org.slf4j</groupId>
131 <artifactId>slf4j-api</artifactId>
132 <version>1.7.6</version>
133 </dependency>
134 <dependency>
135 <groupId>org.slf4j</groupId>
136 <artifactId>slf4j-log4j12</artifactId>
137 <version>1.7.6</version>
138 </dependency>
139 </dependencies>
140
141
142 <build>
143 <finalName>SSMDemo</finalName>
144 <plugins>
145 <!-- Maven的Tomcat插件(支持Maven以"tomcat7:run"方式启动web项目) -->
146 <plugin>
147 <groupId>org.apache.tomcat.maven</groupId>
148 <artifactId>tomcat7-maven-plugin</artifactId>
149 <version>2.1</version>
150 <configuration>
151 <port>5050</port>
152 <path>/</path>
153 <uriEncoding>UTF-8</uriEncoding>
154 <finalName>mgr</finalName>
155 <server>tomcat7</server>
156 </configuration>
157 </plugin>
158 </plugins>
159 </build>
160 </project>

POM.xml

三、开发模型层(MyBatis)

创建 resources/applicationContext.xml 文件。

1 <beans xmlns="http://www.springframework.org/schema/beans"
2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
3 xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
4 xmlns:context="http://www.springframework.org/schema/context"
5 xmlns:task="http://www.springframework.org/schema/task"
6 xsi:schemaLocation="
7 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
8 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
9 http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
10 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
11 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
12 http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
15
16 <!-- ================================== import sub-config file ================================== -->
17 <import resource="spring-mybatis.xml" />
18 <!-- ================================== /import sub-config file ================================== -->
19 </beans>

创建 spring-mybatis.xml 文件,配置一个只读的数据源以及一个只写的数据源。

1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:context="http://www.springframework.org/schema/context"
5 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
6
7 <!-- 引入外部properties文件 -->
8 <context:property-placeholder location="classpath:jdbc.properties" />
9
10 <!-- ====================================================== Add MyBatis Support Start ====================================================== -->
11 <!-- 配置写数据源 -->
12 <bean id="dataSourceWrite" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
13 <!-- 基本属性 url、user、password -->
14 <property name="url" value="${jdbc.master.url}" />
15 <property name="username" value="${jdbc.master.username}" />
16 <property name="password" value="${jdbc.master.password}" />
17 <!-- 配置初始化大小、最小、最大 -->
18 <property name="initialSize" value="${jdbc.master.initialSize}" />
19 <property name="minIdle" value="${jdbc.master.minIdle}" />
20 <property name="maxActive" value="${jdbc.master.maxActive}" />
21 <!-- 配置获取连接等待超时的时间 -->
22 <property name="maxWait" value="60000" />
23 <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
24 <property name="timeBetweenEvictionRunsMillis" value="60000" />
25 <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
26 <property name="minEvictableIdleTimeMillis" value="300000" />
27 <property name="validationQuery" value="SELECT '1'" />
28 <property name="testWhileIdle" value="true" />
29 <property name="testOnBorrow" value="true" />
30 <property name="testOnReturn" value="false" />
31 <!-- 打开PSCache,并且指定每个连接上PSCache的大小 mysql false -->
32 <property name="poolPreparedStatements" value="false" />
33 <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
34 <!-- 配置监控统计拦截的filters -->
35 <property name="filters" value="config,stat,log4j,wall" />
36 <property name="connectionProperties" value="config.decrypt=false" />
37 </bean>
38 <!-- 配置读数据源 -->
39 <bean id="dataSourceRead" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
40 <!-- 基本属性 url、user、password -->
41 <property name="url" value="${jdbc.slave.url}" />
42 <property name="username" value="${jdbc.slave.username}" />
43 <property name="password" value="${jdbc.slave.password}" />
44 <!-- 配置初始化大小、最小、最大 -->
45 <property name="initialSize" value="${jdbc.slave.initialSize}" />
46 <property name="minIdle" value="${jdbc.slave.minIdle}" />
47 <property name="maxActive" value="${jdbc.slave.maxActive}" />
48 <!-- 配置获取连接等待超时的时间 -->
49 <property name="maxWait" value="60000" />
50 <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
51 <property name="timeBetweenEvictionRunsMillis" value="60000" />
52 <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
53 <property name="minEvictableIdleTimeMillis" value="300000" />
54 <property name="validationQuery" value="SELECT '1'" />
55 <property name="testWhileIdle" value="true" />
56 <property name="testOnBorrow" value="false" />
57 <property name="testOnReturn" value="false" />
58 <!-- 打开PSCache,并且指定每个连接上PSCache的大小 mysql false -->
59 <property name="poolPreparedStatements" value="false" />
60 <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
61 <!-- 配置监控统计拦截的filters -->
62 <property name="filters" value="config,stat,log4j,wall" />
63 <property name="connectionProperties" value="config.decrypt=false" />
64 </bean>
65
66 <!-- 可写的SessionFactory -->
67 <bean id="sqlWriteSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" scope="singleton">
68 <property name="dataSource" ref="dataSourceWrite" />
69 <property name="configLocation" value="classpath:mybatis-config.xml" />
70 </bean>
71 <!-- 只读的SessionFactory -->
72 <bean id="sqlReadOnlySessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" scope="singleton">
73 <property name="dataSource" ref="dataSourceRead" />
74 <property name="configLocation" value="classpath:mybatis-config.xml" />
75 </bean>
76
77 <!-- 可写的Session -->
78 <bean id="writableSQLSession" class="org.mybatis.spring.SqlSessionTemplate">
79 <constructor-arg index="0" ref="sqlWriteSessionFactory" />
80 </bean>
81 <!-- 只读的Session -->
82 <bean id="readonlySQLSession" class="org.mybatis.spring.SqlSessionTemplate">
83 <constructor-arg index="0" ref="sqlReadOnlySessionFactory" />
84 </bean>
85 <!-- ====================================================== Add MyBatis Support End ====================================================== -->
86 </beans>

创建 jdbc.properties 配置文件

############################  MySQL/Oracle/SQLServer Database Configuratioin Info ###############################
# MySQL Master DB Info
jdbc.master.dialet=org.hibernate.dialect.MySQLDialect
jdbc.master.driverClassName=com.mysql.jdbc.Driver
jdbc.master.url=jdbc:mysql://127.0.0.1:3306/SSMDemo
jdbc.master.username=root
jdbc.master.password=sa

# MySQL Slave DB Info
jdbc.slave.dialet=org.hibernate.dialect.MySQLDialect
jdbc.slave.driverClassName=com.mysql.jdbc.Driver
jdbc.slave.url=jdbc:mysql://localhost:3306/SSMDemo
jdbc.slave.username=root
jdbc.slave.password=sa

############################## Connection Pool Configuration Info ##############################################
# MySQL Master DB Setting
jdbc.master.initialSize = 10
jdbc.master.minIdle = 0
jdbc.master.maxActive = 30

# MySQL Slave DB Setting
jdbc.slave.initialSize = 10
jdbc.slave.minIdle = 0
jdbc.slave.maxActive = 30

在本地 MySQL 数据库创建一个 SSMDemo 数据库,执行下面的语句创建 user 表并插入一条测试数据。

CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(45) DEFAULT NULL,
`password` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'admin', 'password');

创建 mybatis-config.xml 文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<mappers>
<!-- 配置扫描的Mapper类 -->
<package name="com.chanshuyi.dao.mapper"/>
</mappers>
</configuration>

下载 ​​MBGGenerator​​(密码:c1dy),这是MyBatis 官方的 MyBatis Generator,我们使用它将数据库表转化成 model、mapper 以及 SqlProvider 文件。

下载文件解压放到 resources 目录下。进入 resources/mbg 目录,双击运行 generate.bat,程序自动将配置文件 resources/mbgconfig.xml 中配置的表格映射成相对应的文件。

玩转SSH(四):Struts + Spring + MyBatis_spring_09

四、开发视图层(Spring)

创建 resources/log4j.properties 文件,提供日志记录。

#Console Log
log4j.rootLogger=info, console, file

# Write to Console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=INFO
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%5p %d{MM-dd HH:mm:ss}(%F:%L): %m%n

# Write to File
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File=${catalina.home}app/log/log.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%5p %d{MM-dd HH:mm:ss}(%F:%L): %m%n

在 com.chanshuyi.dao.mapper.UserMapper 类中增加 getUserListByMapSql 接口:

/**
* 根据参数构造SQL进行查询
* @param param
* @return
*/
@SelectProvider(type = UserSqlProvider.class, method = "getUserListByMapSql")
List<User> getUserListByMapSql(@Param("param") Map<String, String> param);

在 UserSqlProvider 类增加对上面接口 SQL 的实现:

/**
* 获取查询SQL
* @param param
* @return
*/
public String getUserListByMapSql(Map<String, Object> param) {
StringBuilder builder = new StringBuilder();
Map<String, String> realParam = (Map<String, String>)param.get("param");

//add select part
builder.append(" select * from user where 1 = 1 ");

//add condition part
String conditionStr = "";
if(!StringUtil.isNullOrEmpty(realParam)){
conditionStr = getQueryCondition(realParam);
if(!StringUtil.isNullOrEmpty(conditionStr)){
builder.append(conditionStr);
}
}

return new String(builder);
}

public String getQueryCondition(Map<String, String> param){
StringBuilder builder = new StringBuilder();

//if param is null or empty, return empty String
if(param == null || param.size() < 1){
return "";
}

for(String key : param.keySet()){
String value = param.get(key);
if(value != null && !value.isEmpty()){
builder.append(" and " + key + " = '" + value + "'");
}
}

return new String(builder);
}

上面用到了 StringUtil.java,我们在 com.chanshuyi.util 中导入它:

玩转SSH(四):Struts + Spring + MyBatis_struts_07

玩转SSH(四):Struts + Spring + MyBatis_bc_08

package com.mszz.util;

import java.util.Collection;
import java.util.Map;

/**
* 字符串工具类
* @author chenxinquan
*
*/
public class StringUtil {
/**
* 判断对象或对象数组中每一个对象是否为空: 对象为null,字符序列长度为0,集合类、Map为empty
* @author zl
* @param obj
* @return
*/
public static boolean isNullOrEmpty(Object obj) {
if (obj == null)
return true;

if (obj instanceof CharSequence)
return ((CharSequence) obj).length() == 0;

if (obj instanceof Collection)
return ((Collection) obj).isEmpty();

if (obj instanceof Map)
return ((Map) obj).isEmpty();

if (obj instanceof Object[]) {
Object[] object = (Object[]) obj;
if (object.length == 0) {
return true;
}
boolean empty = true;
for (int i = 0; i < object.length; i++) {
if (!isNullOrEmpty(object[i])) {
empty = false;
break;
}
}
return empty;
}
return false;
}
}

StringUtil.java

创建 com.chanshuyi.dao.impl.BaseDao.java 类,提供基本的数据库读写对象。

package com.chanshuyi.dao.impl;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;

/**
* 所有Service的基类,用来注入sqlSession
*/
public class BaseDao {
/**
* 可写的sqlSession
*/protected SqlSession writableSQLSession;

/**
* 只读的sqlSession
*/protected SqlSession readonlySQLSession;

public void setWritableSQLSession(SqlSession writableSQLSession) {
this.writableSQLSession = writableSQLSession;
}

public void setReadonlySQLSession(SqlSession readonlySQLSession) {
this.readonlySQLSession = readonlySQLSession;
}
}

创建DAO层接口 IUserDao.java:

package com.chanshuyi.dao;

import com.chanshuyi.model.User;

import java.util.List;
import java.util.Map;

/**
* Created by chanshuyi on 2015/12/26.
*/
public interface IUserDao {
User getUserById(int userId);

/**
*
* @param param Map中的key要与数据库表中的字段名相同
* @return
*/
User getUserByMapSql(Map<String, String> param);

List<User> getUserListByMapSql(Map<String, String> param);
}

创建 UserDaoImpl.java 继承 BaseDao.java、实现 IUserDao 接口:

package com.mszz.dao.impl;

import com.mszz.dao.mapper.UserMapper;
import com.mszz.model.User;
import com.mszz.dao.IUserDao;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;

/**
* Created by Administrator on 2015/12/26.
*/public class UserDaoImpl extends BaseDao implements IUserDao {

private static Log logger = LogFactory.getLog(UserDaoImpl.class);

@Override
public User getUserById(int userId) {
UserMapper mapper = readonlySQLSession.getMapper(UserMapper.class);
return mapper.selectByPrimaryKey(userId);
}

/**
* dsafdsf
* @param param
* @return
*/
@Override
public User getUserByMapSql(Map<String, String> param) {
logger.info("getUserByMapSql 根据动态参数查询用户对象");
return getUserListByMapSql(param).size() > 0 ? getUserListByMapSql(param).get(0) : null;
}

/**
* get**MapSql()类的方法只能用于各参数的等于查询
* 例如:select * from user where username = 1 and password = 3 (正确)
* select * from user where username in (1,2,3) (错误,无法实现)
* @param param
* @return
*/
@Override
public List<User> getUserListByMapSql(Map<String, String> param) {
logger.info("getUserListByMapSql 根据动态参数查询用户对象列表");
UserMapper mapper = readonlySQLSession.getMapper(UserMapper.class);
return mapper.getUserListByMapSql(param);
}
}

创建 IUserService.java 和 UserServiceImpl.java:

package com.mszz.service;

import com.mszz.model.User;

import java.util.List;
import java.util.Map;

/**
* Created by chanshuyi on 2015/12/26.
*/
public interface IUserService {
User getUserById(int userId);

/**
*
* @param param Map中的key要与数据库表中的字段名相同
* @return
*/
User getUserByMapSql(Map<String, String> param);

List<User> getUserListByMapSql(Map<String, String> param);
}
package com.chanshuyi.service.impl;

import com.chanshuyi.dao.IUserDao;
import com.chanshuyi.model.User;
import com.chanshuyi.service.IUserService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.List;
import java.util.Map;

/**
* Created by Administrator on 2015/6/18.
*/
public class UserServiceImpl implements IUserService {

private static Log logger = LogFactory.getLog(UserServiceImpl.class);

IUserDao userDao;

@Override
public User getUserById(int userId) {
return userDao.getUserById(userId);
}

@Override
public User getUserByMapSql(Map<String, String> param) {
return userDao.getUserByMapSql(param);
}

@Override
public List<User> getUserListByMapSql(Map<String, String> param) {
return userDao.getUserListByMapSql(param);
}

public IUserDao getUserDao() {
return userDao;
}

public void setUserDao(IUserDao userDao) {
this.userDao = userDao;
}
}

配置 applicationContext.xml 文件,加入对 Dao 和 Service 的创建:

<!-- UserDao 服务 -->
<bean id="useDao" class="com.chanshuyi.dao.impl.UserDaoImpl">
<property name="readonlySQLSession" ref="readonlySQLSession"/>
<property name="writableSQLSession" ref="writableSQLSession"/>
</bean>
<!-- UserService 服务 -->
<bean id="userService" class="com.chanshuyi.service.impl.UserServiceImpl">
<property name="userDao" ref="useDao"/>
</bean>
<!-- UserAction 服务 -->
<bean id="userAction" class="com.chanshuyi.action.UserAction">
<property name="userService" ref="userService"/>
</bean>

修改后的 applicationContext.xml 文件为:

玩转SSH(四):Struts + Spring + MyBatis_struts_07

玩转SSH(四):Struts + Spring + MyBatis_bc_08

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">

<!-- UserDao 服务 -->
<bean id="useDao" class="com.chanshuyi.dao.impl.UserDaoImpl">
<property name="readonlySQLSession" ref="readonlySQLSession"/>
<property name="writableSQLSession" ref="writableSQLSession"/>
</bean>
<!-- UserService 服务 -->
<bean id="userService" class="com.chanshuyi.service.impl.UserServiceImpl">
<property name="userDao" ref="useDao"/>
</bean>
<!-- UserAction 服务 -->
<bean id="userAction" class="com.chanshuyi.action.UserAction">
<property name="userService" ref="userService"/>
</bean>

<!-- ================================== import sub-config file ================================== -->
<import resource="spring-mybatis.xml" />
<!-- ================================== /import sub-config file ================================== -->
</beans>

applicationContext.xml

五、开发控制层(Struts)

创建 com.chanshuyi.action.UserAction 类

package com.chanshuyi.action;

import com.chanshuyi.service.IUserService;
import com.opensymphony.xwork2.ActionSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

/**
* Created by Administrator on 2015/6/18.
*/
public class UserAction extends ActionSupport {

private static Logger logger = LoggerFactory.getLogger(UserAction.class);

private String message;

private String username;

private String password;

private IUserService userService;

public String login(){
try{
Map<String, String> param = new HashMap<String, String>();
param.put("username", username);
param.put("password", password);
if(userService.getUserByMapSql(param) != null){
message = "登录成功!";
logger.info(message);
return SUCCESS;
}else{
message = "登录失败!";
logger.info(message);
return INPUT;
}
}catch(Exception e){
logger.warn(e.getMessage());
e.printStackTrace();
return INPUT;
}
}

/******** set/get ********/
public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public IUserService getUserService() {
return userService;
}

public void setUserService(IUserService userService) {
this.userService = userService;
}
}

创建 struts.xml 配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 指定Spring装配Action对象的方式,与objectFactory相关联(有4个取值:name 按照名称、type按照类型,auto,constructor) -->
<constant name="struts.objectFactory.spring.autoWire" value="name"/>

<!-- 所有匹配*.action的请求都由struts2处理 -->
<constant name="struts.action.extension" value="action" />
<!-- 是否启用开发模式(开发时设置为true,发布到生产环境后设置为false) -->
<constant name="struts.devMode" value="true" />
<!-- struts配置文件改动后,是否重新加载(开发时设置为true,发布到生产环境后设置为false) -->
<constant name="struts.configuration.xml.reload" value="true" />
<!-- 设置浏览器是否缓存静态内容(开发时设置为false,发布到生产环境后设置为true) -->
<constant name="struts.serve.static.browserCache" value="false" />
<!-- 请求参数的编码方式 -->
<constant name="struts.i18n.encoding" value="utf-8" />
<!-- 每次HTTP请求系统都重新加载资源文件,有助于开发(开发时设置为true,发布到生产环境后设置为false) -->
<constant name="struts.i18n.reload" value="true" />
<!-- 文件上传最大值 -->
<constant name="struts.multipart.maxSize" value="104857600" />
<!-- 让struts2支持动态方法调用,使用叹号访问方法 -->
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<!-- Action名称中是否还是用斜线 -->
<constant name="struts.enable.SlashesInActionNames" value="false" />
<!-- 允许标签中使用表达式语法 -->
<constant name="struts.tag.altSyntax" value="true" />
<!-- 相当于普通xml配置中的extends,指定默认的继承包 -->
<constant name="struts.convention.default.parent.package" value="struts-default" />
<!-- 结果资源所在路径,这个地方要注意,详见下面解释 -->
<constant name="struts.convention.result.path" value="/jspPage" />
<!-- 指定以那些后缀结尾的java类package包被搜索,以发现注解 -->
<constant name="struts.convention.package.locators" value="web,action" />
<!-- 对于WebLogic,Orion,OC4J此属性应该设置成true -->
<constant name="struts.dispatcher.parametersWorkaround" value="false" />
<!-- Action 映射配置 -->
<package name="basePackage" extends="struts-default">
<!-- 1. Struts 自己处理 -->
<!-- 访问路径:http://localhost:5050/index.jsp -->
<action name="user_login" class="com.chanshuyi.action.UserAction" method="login">
<result name="success">/index.jsp</result>
<result name="input">/index.jsp</result>
</action>
</package>
</struts>

创建 webapp/index.jsp 文件

<%@page language="java" pageEncoding="UTF-8"%>
<%@ page contentType="text/html;charset=utf-8" %>
<%@ page isELIgnored="false"%>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h2>Hello World!</h2>
<%-- 通过Struts传递参数,数据传递方式必须选择post,否则编码错误! --%>
<form action="login.action" method="post" >
<p id="message">${message}</p>
<b>Username:</b><input type="text" id="name" name="username" /><br>
<b>Password:</b><input type="password" id="password" name="password"/><br>
<input type="submit" value="Login"/>
</form>
</body>
</html>

配置 web.xml 文件,使项目启动的时候加载 Struts 核心过滤器和 Spring 核心监听器。

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<display-name>SSMDemo : A Demo of Struts + Spring + MyBatis</display-name>

<!-- Spring 配置文件 -->
<!-- 1.配置spring配置文件位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
<!--<param-value>classpath*:applicationContext-*.xml</param-value>-->
</context-param>
<!-- 2.Struts核心过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 3.Spring核心监听器 -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>

 

六、启动项目测试

为工程配置 Maven 命令 “tomcat7:run” 

玩转SSH(四):Struts + Spring + MyBatis_spring_14

点击启动项目

玩转SSH(四):Struts + Spring + MyBatis_spring_15

打开浏览器输入:​​http://localhost:5050/index.jsp​​ 

玩转SSH(四):Struts + Spring + MyBatis_bc_16

输入 admin/password,点击 Login,提示登录成功

玩转SSH(四):Struts + Spring + MyBatis_bc_17

 

链接:​​http://pan.baidu.com/s/1S5cRW​​ 密码:qx97

 

玩转SSH(四):Struts + Spring + MyBatis_bc_18