Spring学习总结(六)——Spring整合MyBatis完整示例
目录
为了梳理前面学习的内容《Spring 整合 MyBatis(Maven+MySQL)一》与《Spring 整合 MyBatis(Maven+MySQL)二》,做一个完整的示例完成一个简单的图书管理功能,主要使用到的技术包含 Spring、MyBatis、Maven、MySQL 及简单 MVC 等。最后的运行效果如下所示:
项目结构如下:
一、新建一个基于 Maven 的 Web 项目
1.1、创建一个简单的 Maven 项目,项目信息如下:
1.2、修改层面信息,在项目上右键选择属性,再选择“Project Facets”,先设置 java 运行环境为 1.7,先去掉 "Dynamic Web Module" 前的勾,然后保存关闭;再打开勾选上 "Dynamic Web Module",版本选择“3.0”;这里在左下解会出现一个超链接,创建“Web Content”,完成关闭。
1.3、修改项目的部署内容。项目上右键属性,选择“Deplyment Assembly”, 删除不需要发布的内容如:带“test”的两个目录,WebContent 目录,再添加一个 main 下的 webapp 目录。
修改后的结果如下所示:
1.4、修改项目内容。将 WebContent 下的内容复制到 /src/main/webapp 下,再删除 WebContent 目录,修改后的结果如下所示:
1.5、添加“服务器运行时(Server Runtime)”,添加后的结果如下:
二、创建数据库与表
启动 MySQL,创建数据库,新建表 books,插入测试数据,完成后的表如下所示:
创建表的 sql 脚本如下:
/* Navicat MySQL Data TransferSource Server : localhost
Source Server Version : 50536
Source Host : localhost:3306
Source Database : db1Target Server Type : MYSQL
Target Server Version : 50536
File Encoding : 65001Date: 2016-07-06 22:05:07
*/SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure forbooks
-- ----------------------------
DROP TABLE IF EXISTSbooks
;
CREATE TABLEbooks
(id
int(11) NOT NULL AUTO_INCREMENT COMMENT '编号',title
varchar(100) NOT NULL COMMENT '书名',price
decimal(10,2) DEFAULT NULL COMMENT '价格',publishDate
timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '出版日期',
PRIMARY KEY (id
),
UNIQUE KEYtitle
(title
)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;-- ----------------------------
-- Records of books
-- ----------------------------
INSERT INTObooks
VALUES ('1', 'Java 编程思想', '98.50', '2005-01-02 00:00:00');
INSERT INTObooks
VALUES ('2', 'HeadFirst 设计模式', '55.70', '2010-11-09 00:00:00');
INSERT INTObooks
VALUES ('3', '第一行 Android 代码', '69.90', '2015-06-23 00:00:00');
INSERT INTObooks
VALUES ('4', 'C++ 编程思想', '88.50', '2004-01-09 00:00:00');
INSERT INTObooks
VALUES ('5', 'HeadFirst Java', '55.70', '2013-12-17 00:00:00');
INSERT INTObooks
VALUES ('6', '疯狂 Android', '19.50', '2014-07-31 00:00:00');
需特别注意的是书名是唯一键。
三、添加依赖包
项目主要依赖的 jar 包有 Spring 核心包、Spring AOP 包、MyBatis ORM 包、MyBatis-Spring 适配包、JSTL、JUnit、Log4j2 等,具体的 pom.xml 文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zhangguo</groupId> <artifactId>BookStore</artifactId> <version>0.0.1</version> <packaging>war</packaging><span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">properties</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">project.build.sourceEncoding</span><span style="color: rgba(0, 0, 255, 1)">></span>UTF-8<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">project.build.sourceEncoding</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">spring.version</span><span style="color: rgba(0, 0, 255, 1)">></span>4.3.0.RELEASE<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">spring.version</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">properties</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">dependencies</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">Spring框架核心库 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span>org.springframework<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span>spring-context<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span>${spring.version}<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> aspectJ AOP 织入器 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span>org.aspectj<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span>aspectjweaver<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span>1.8.9<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> Spring Web </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span>org.springframework<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span>spring-web<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span>${spring.version}<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">mybatis-spring适配器 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span>org.mybatis<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span>mybatis-spring<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span>1.3.0<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">Spring java数据库访问包,在本例中主要用于提供数据源 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span>org.springframework<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span>spring-jdbc<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span>${spring.version}<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">mysql数据库驱动 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span>mysql<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span>mysql-connector-java<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span>5.1.38<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">log4j日志包 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span>org.apache.logging.log4j<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span>log4j-core<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span>2.6.1<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> mybatis ORM框架 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span>org.mybatis<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span>mybatis<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span>3.4.1<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> JUnit单元测试工具 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span>junit<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span>junit<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span>4.10<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">c3p0 连接池 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span>c3p0<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span>c3p0<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span>0.9.1.2<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> jstl </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span>javax.servlet<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span>jstl<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span>1.2<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">dependencies</span><span style="color: rgba(0, 0, 255, 1)">></span>
</project>
如果是第一次依赖相关的包,则需要下载时间,请耐心等待,如果下载失败请手动下载后复制到本地的资源库中。依赖后的项目结果如下:
四、新建 POJO 实体层
为了实现与数据库中的 books 表进行关系映射新建一个 Book 类,具体代码如下:
package com.zhangguo.bookstore.entities;import java.util.Date;
/**
图书实体
*/
public class Book {
/**
- 编号
*/
private int id;
/**- 书名
*/
private String title;
/**- 价格
*/
private double price;
/**- 出版日期
*/
private Date publishDate;public Book(int id, String title, double price, Date publishDate) {
this.id = id;
this.title = title;
this.price = price;
this.publishDate = publishDate;
}public Book() {
}public int getId() {
return id;
}public void setId(int id) {
this.id = id;
}public String getTitle() {
return title;
}public void setTitle(String title) {
this.title = title;
}public double getPrice() {
return price;
}public void setPrice(double price) {
this.price = price;
}public Date getPublishDate() {
return publishDate;
}public void setPublishDate(Date publishDate) {
this.publishDate = publishDate;
}
}
五、新建 MyBatis SQL 映射层
这个项目中我们采用接口与 xml 结束的形式完成关系与对象间的映射,在接口中定义一些数据访问的方法,在 xml 文件中定义实现数据访问需要的 sql 脚本。图书数据访问映射接口如下:
package com.zhangguo.bookstore.mapper;import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.zhangguo.bookstore.entities.Book;
/**
- 图书数据访问接口
*/
public interface BookDAO {
/**
- 获得所有图书
*/
public List<Book> getAllBooks();
/**- 根据图书编号获得图书对象
*/
public Book getBookById(@Param("id") int id);
/**- 添加图书
*/
public int add(Book entity);
/**- 根据图书编号删除图书
*/
public int delete(int id);
/**- 更新图书
*/
public int update(Book entity);
}
为 MyBatis ORM 创建的映射文件 BookMapper.xml(命名尽量都遵循一个规则,便于扫描,这里约定以实体名 +Mapper)如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--命名空间应该是对应接口的包名 + 接口名 --> <mapper namespace="com.zhangguo.bookstore.mapper.BookDAO"> <!--id 应该是接口中的方法,结果类型如没有配置别名则应该使用全名称 --> <!--获得所有图书 --> <select id="getAllBooks" resultType="Book"> select id,title,price,publishDate from books </select> <!--获得图书对象通过编号 --> <select id="getBookById" resultType="Book"> select id,title,price,publishDate from books where id=#{id} </select> <!-- 增加 --> <insert id="add"> insert into books(title,price,publishDate) values(#{title},#{price},#{publishDate}) </insert> <!-- 删除 --> <delete id="delete"> delete from books where id=#{id} </delete> <!-- 更新 --> <update id="update"> update books set title=#{title},price=#{price},publishDate=#{publishDate} where id=#{id} </update> </mapper>
六、完成 Spring 整合 MyBatis 配置
6.1、在源代码的根目录下新建 db.properties 文件,用于存放数据库连接信息,文件内容如下:
#mysql jdbc jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=UTF-8 jdbc.uid=root jdbc.pwd=root
6.2、在源代码的根目录下新建 applicationContext.xml 文件,用于整合 MyBatis 与 Spring,该文件是整个项目的控制中心,非常关键,具体的内容如下:
<?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:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" 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-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"><span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">1 引入属性文件,在配置中占位使用 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">context:property-placeholder </span><span style="color: rgba(255, 0, 0, 1)">location</span><span style="color: rgba(0, 0, 255, 1)">="classpath*:db.properties"</span> <span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">2 配置C3P0数据源 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">bean </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="datasource"</span><span style="color: rgba(255, 0, 0, 1)"> class</span><span style="color: rgba(0, 0, 255, 1)">="com.mchange.v2.c3p0.ComboPooledDataSource"</span><span style="color: rgba(255, 0, 0, 1)"> destroy-method</span><span style="color: rgba(0, 0, 255, 1)">="close"</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">驱动类名 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="driverClass"</span><span style="color: rgba(255, 0, 0, 1)"> value</span><span style="color: rgba(0, 0, 255, 1)">="${jdbc.driver}"</span> <span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> url </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="jdbcUrl"</span><span style="color: rgba(255, 0, 0, 1)"> value</span><span style="color: rgba(0, 0, 255, 1)">="${jdbc.url}"</span> <span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 用户名 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="user"</span><span style="color: rgba(255, 0, 0, 1)"> value</span><span style="color: rgba(0, 0, 255, 1)">="${jdbc.uid}"</span> <span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 密码 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="password"</span><span style="color: rgba(255, 0, 0, 1)"> value</span><span style="color: rgba(0, 0, 255, 1)">="${jdbc.pwd}"</span> <span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 当连接池中的连接耗尽的时候c3p0一次同时获取的连接数 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="acquireIncrement"</span><span style="color: rgba(255, 0, 0, 1)"> value</span><span style="color: rgba(0, 0, 255, 1)">="5"</span><span style="color: rgba(0, 0, 255, 1)">></</span><span style="color: rgba(128, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 初始连接池大小 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="initialPoolSize"</span><span style="color: rgba(255, 0, 0, 1)"> value</span><span style="color: rgba(0, 0, 255, 1)">="10"</span><span style="color: rgba(0, 0, 255, 1)">></</span><span style="color: rgba(128, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 连接池中连接最小个数 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="minPoolSize"</span><span style="color: rgba(255, 0, 0, 1)"> value</span><span style="color: rgba(0, 0, 255, 1)">="5"</span><span style="color: rgba(0, 0, 255, 1)">></</span><span style="color: rgba(128, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 连接池中连接最大个数 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="maxPoolSize"</span><span style="color: rgba(255, 0, 0, 1)"> value</span><span style="color: rgba(0, 0, 255, 1)">="20"</span><span style="color: rgba(0, 0, 255, 1)">></</span><span style="color: rgba(128, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">bean</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">3 会话工厂bean sqlSessionFactoryBean </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">bean </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="sqlSessionFactory"</span><span style="color: rgba(255, 0, 0, 1)"> class</span><span style="color: rgba(0, 0, 255, 1)">="org.mybatis.spring.SqlSessionFactoryBean"</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 数据源 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="dataSource"</span><span style="color: rgba(255, 0, 0, 1)"> ref</span><span style="color: rgba(0, 0, 255, 1)">="datasource"</span><span style="color: rgba(0, 0, 255, 1)">></</span><span style="color: rgba(128, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 别名 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="typeAliasesPackage"</span><span style="color: rgba(255, 0, 0, 1)"> value</span><span style="color: rgba(0, 0, 255, 1)">="com.zhangguo.bookstore.entities"</span><span style="color: rgba(0, 0, 255, 1)">></</span><span style="color: rgba(128, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> sql映射文件路径 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="mapperLocations"</span><span style="color: rgba(255, 0, 0, 1)"> value</span><span style="color: rgba(0, 0, 255, 1)">="classpath*:com/zhangguo/bookstore/mapper/*Mapper.xml"</span><span style="color: rgba(0, 0, 255, 1)">></</span><span style="color: rgba(128, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">bean</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">4 自动扫描对象关系映射 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">bean </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="org.mybatis.spring.mapper.MapperScannerConfigurer"</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">指定会话工厂,如果当前上下文中只定义了一个则该属性可省去 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="sqlSessionFactoryBeanName"</span><span style="color: rgba(255, 0, 0, 1)"> value</span><span style="color: rgba(0, 0, 255, 1)">="sqlSessionFactory"</span><span style="color: rgba(0, 0, 255, 1)">></</span><span style="color: rgba(128, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 指定要自动扫描接口的基础包,实现接口 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="basePackage"</span><span style="color: rgba(255, 0, 0, 1)"> value</span><span style="color: rgba(0, 0, 255, 1)">="com.zhangguo.bookstore.mapper"</span><span style="color: rgba(0, 0, 255, 1)">></</span><span style="color: rgba(128, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">bean</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">5 声明式事务管理 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">定义事物管理器,由spring管理事务 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">bean </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="transactionManager"</span><span style="color: rgba(255, 0, 0, 1)"> class</span><span style="color: rgba(0, 0, 255, 1)">="org.springframework.jdbc.datasource.DataSourceTransactionManager"</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="dataSource"</span><span style="color: rgba(255, 0, 0, 1)"> ref</span><span style="color: rgba(0, 0, 255, 1)">="datasource"</span><span style="color: rgba(0, 0, 255, 1)">></</span><span style="color: rgba(128, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">bean</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">支持注解驱动的事务管理,指定事务管理器 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">tx:annotation-driven </span><span style="color: rgba(255, 0, 0, 1)">transaction-manager</span><span style="color: rgba(0, 0, 255, 1)">="transactionManager"</span><span style="color: rgba(0, 0, 255, 1)">/></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">6 容器自动扫描IOC组件 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">context:component-scan </span><span style="color: rgba(255, 0, 0, 1)">base-package</span><span style="color: rgba(0, 0, 255, 1)">="com.zhangguo.bookstore"</span><span style="color: rgba(0, 0, 255, 1)">></</span><span style="color: rgba(128, 0, 0, 1)">context:component-scan</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">7 aspectj支持自动代理实现AOP功能 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">aop:aspectj-autoproxy </span><span style="color: rgba(255, 0, 0, 1)">proxy-target-class</span><span style="color: rgba(0, 0, 255, 1)">="true"</span><span style="color: rgba(0, 0, 255, 1)">></</span><span style="color: rgba(128, 0, 0, 1)">aop:aspectj-autoproxy</span><span style="color: rgba(0, 0, 255, 1)">></span>
</beans>
共有 7 处配置,第 7 处配置非必要,另外关于事务管理可以选择 AOP 拦截式事务管理。
七、创建服务层
创建 BookService 服务类,完成图书管理业务,有些项目中也叫业务层,这里我们叫服务层,具体实现如下:
package com.zhangguo.bookstore.service;import java.util.List;
import javax.annotation.Resource;import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import com.zhangguo.bookstore.entities.Book;
import com.zhangguo.bookstore.mapper.BookDAO;@Service
public class BookService{@Resource BookDAO bookdao; </span><span style="color: rgba(0, 0, 255, 1)">public</span> List<Book><span style="color: rgba(0, 0, 0, 1)"> getAllBooks() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> bookdao.getAllBooks(); } </span><span style="color: rgba(0, 0, 255, 1)">public</span> Book getBookById(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> id){ </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> bookdao.getBookById(id); } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span> add(Book entity) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> Exception { </span><span style="color: rgba(0, 0, 255, 1)">if</span>(entity.getTitle()==<span style="color: rgba(0, 0, 255, 1)">null</span>||entity.getTitle().equals(""<span style="color: rgba(0, 0, 0, 1)">)){ </span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Exception("书名必须不为空"<span style="color: rgba(0, 0, 0, 1)">); } </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> bookdao.add(entity); } @Transactional </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> add(Book entity1,Book entityBak){ </span><span style="color: rgba(0, 0, 255, 1)">int</span> rows=0<span style="color: rgba(0, 0, 0, 1)">; rows</span>=<span style="color: rgba(0, 0, 0, 1)">bookdao.add(entity1); rows</span>=<span style="color: rgba(0, 0, 0, 1)">bookdao.add(entityBak); </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> rows; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span> delete(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> id) { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> bookdao.delete(id); } </span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)"> * 多删除 </span><span style="color: rgba(0, 128, 0, 1)">*/</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> delete(String[] ids){ </span><span style="color: rgba(0, 0, 255, 1)">int</span> rows=0<span style="color: rgba(0, 0, 0, 1)">; </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> (String idStr : ids) { </span><span style="color: rgba(0, 0, 255, 1)">int</span> id=<span style="color: rgba(0, 0, 0, 1)">Integer.parseInt(idStr); rows</span>+=<span style="color: rgba(0, 0, 0, 1)">delete(id); } </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> rows; } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> update(Book entity) { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> bookdao.update(entity); }
}
服务层不只是一个 dao 的接力棒,认为他可有可无,其实是因为我们现在的的示例中没有涉及到更多的复杂业务,所以显得比较空,实现开发可能有更多的业务逻辑要在这里处理。另外给 bookdao 成员变量注解为自动装配,service 类注解为 IOC 组件。
八、JUnit 测试服务类
为了确保服务类中的每个方法正确,先使用 JUnit 进行单元测试,测试代码如下:
package com.zhangguo.bookstore.test;import static org.junit.Assert.*;
import java.util.Date;
import java.util.List;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zhangguo.bookstore.entities.Book;
import com.zhangguo.bookstore.service.BookService;public class TestBookService {
</span><span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> BookService bookservice; @BeforeClass </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> before(){ ApplicationContext ctx</span>=<span style="color: rgba(0, 0, 255, 1)">new</span> ClassPathXmlApplicationContext("applicationContext.xml"<span style="color: rgba(0, 0, 0, 1)">); bookservice</span>=ctx.getBean(BookService.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">); } @Test </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> testGetAllBooks() { List</span><Book> books=<span style="color: rgba(0, 0, 0, 1)">bookservice.getAllBooks(); assertNotNull(books); } @Test </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> testAdd() { Book entity</span>=<span style="color: rgba(0, 0, 255, 1)">new</span> Book(0, "Hibernate 第七版", 78.1, <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Date()); </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> { assertEquals(</span>1<span style="color: rgba(0, 0, 0, 1)">, bookservice.add(entity)); } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) { e.printStackTrace(); } } @Test </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> testDeleteInt() { assertEquals(</span>1, bookservice.delete(9<span style="color: rgba(0, 0, 0, 1)">)); } @Test </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> testDeleteStringArray() { String[] ids</span>={"7","11","12"<span style="color: rgba(0, 0, 0, 1)">}; assertEquals(</span>3<span style="color: rgba(0, 0, 0, 1)">, bookservice.delete(ids)); } @Test </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> testUpdate() { Book entity</span>=<span style="color: rgba(0, 0, 255, 1)">new</span> Book(7, "Hibernate 第二版", 79.1, <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Date()); </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> { assertEquals(</span>1<span style="color: rgba(0, 0, 0, 1)">, bookservice.update(entity)); } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) { e.printStackTrace(); } } @Test </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> testGetBookById() { assertNotNull(bookservice.getBookById(</span>1<span style="color: rgba(0, 0, 0, 1)">)); } @Test </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> testAddDouble(){ </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">因为书名相同,添加第二本会失败,用于测试事务</span> Book entity1=<span style="color: rgba(0, 0, 255, 1)">new</span> Book(0, "Hibernate 第八版", 78.1, <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Date()); Book entity2</span>=<span style="color: rgba(0, 0, 255, 1)">new</span> Book(0, "Hibernate 第八版", 78.1, <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Date()); assertEquals(</span>2<span style="color: rgba(0, 0, 0, 1)">, bookservice.add(entity1, entity2)); }
}
所有的测试均通过,有一个想法就是能否测试完成后数据库还原,如删除的数据在测试后不被真正删除。
九、加载 Spring 容器与获得容器对象
9.1、修改 web.xml 文件,添加加载 Spring 容器用的监听器,修改后的结果如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0" > <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list><span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">listener</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">description</span><span style="color: rgba(0, 0, 255, 1)">></span>Spring容器加载监听器<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">description</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">listener-class</span><span style="color: rgba(0, 0, 255, 1)">></span>org.springframework.web.context.ContextLoaderListener<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">listener-class</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">listener</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">context-param</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">description</span><span style="color: rgba(0, 0, 255, 1)">></span>设置Spring加载时的配置文件位置,默认位置在web-inf/lib下<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">description</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">param-name</span><span style="color: rgba(0, 0, 255, 1)">></span>contextConfigLocation<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">param-name</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">param-value</span><span style="color: rgba(0, 0, 255, 1)">></span>classpath*:applicationContext.xml<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">param-value</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">context-param</span><span style="color: rgba(0, 0, 255, 1)">></span>
</web-app>
类 org.springframework.web.context.ContextLoaderListener 处在 Spring-web.jar 包中,要记得在 pom.xml 中添加依赖,测试是否加载成功的简单办法是:重新启动 tomcat 查看控制信息。
9.2、为了方便获得 Spring 容器实例,定义一个 CtxUtil 工具类,工具类的代码如下:
package com.zhangguo.bookstore.action;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;/**
Spring 容器上下文工具类,用于获取当前的 Spring 容器
实现了接口 ApplicationContextAware 且该类被 Spring 管理
则会自动调用 setApplicationContext 方法获取 Spring 容器对象
/
@Component
public class CtxUtil implements ApplicationContextAware {public static ApplicationContext ctx;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ctx=applicationContext;
}
/**
- 根据类型获得 bean
*/
public static <T> T getBean(Class<T> clazz){
return ctx.getBean(clazz);
}
/**- 根据名称名称获得 bean
*/
public static Object getBean(String name){
return ctx.getBean(name);
}}
十、简单 MVC 控制器封装
为了实现一个简单的 MVC 基础控制器,定义了一个叫 BaseController 的 Servlet,可以让其它的 Servlet 继承该 Servlet 获得部分 MVC 功能,具体代码如下:
package com.zhangguo.bookstore.action;import java.io.IOException;
import java.lang.reflect.*;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/**
Servlet 基类
自定义控制器基类
*/
public class BaseController extends HttpServlet {
private static final long serialVersionUID = 1L;protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获得要执行的方法名</span> String act = request.getParameter("act"<span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 如果用户没有提供方法名</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (act == <span style="color: rgba(0, 0, 255, 1)">null</span> || act.equals(""<span style="color: rgba(0, 0, 0, 1)">)) { </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 默认方法</span> act = "execute"<span style="color: rgba(0, 0, 0, 1)">; } </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 根据方法名获得方法信息获得方法信息</span>
Method method;
try {
// 在对象中获得类型信息, 在类型中获得方法通过方法名,与参数类型
method = this.getClass().getMethod(act, HttpServletRequest.class, HttpServletResponse.class);
// 调用方法, 在当前对象中调用,传递参数 request 与 response, 获得返回结果
String targetUri = method.invoke(this, request, response) + "";
// 如果返回的 url 是以 redirect 开始,则是重定向
if (targetUri.startsWith("redirect:")) {
response.sendRedirect(targetUri.substring(9, targetUri.length()));
} else {
// 转发
request.getRequestDispatcher(targetUri).forward(request, response);
}
} catch (Exception e) {
response.sendError(400, e.getMessage());
e.printStackTrace();
}
}</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> execute(HttpServletRequest request, HttpServletResponse response) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> IOException { response.sendError(</span>400, "请使用参数act指定您要访问的方法"<span style="color: rgba(0, 0, 0, 1)">); }
}
十一、完成图书管理功能
11.1、定义 BookController 控制器
该控制器继承 BaseController,中间每一个参数为(HttpServletRequest request,HttpServletResponse response)的方法都充当一个 Action,代码如下:
package com.zhangguo.bookstore.action;import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.zhangguo.bookstore.entities.Book;
import com.zhangguo.bookstore.service.BookService;@WebServlet("/BookController.do")
public class BookController extends BaseController {
private static final long serialVersionUID = 1L;BookService bookservice; @Override </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> init() <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> ServletException { bookservice </span>= CtxUtil.getBean(BookService.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">); } </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 图书列表Action</span> <span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String ListBook(HttpServletRequest request, HttpServletResponse response) { request.setAttribute(</span>"books"<span style="color: rgba(0, 0, 0, 1)">, bookservice.getAllBooks()); </span><span style="color: rgba(0, 0, 255, 1)">return</span> "ListBook.jsp"<span style="color: rgba(0, 0, 0, 1)">; } </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 删除图书Action</span> <span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String Delete(HttpServletRequest request, HttpServletResponse response) { </span><span style="color: rgba(0, 0, 255, 1)">int</span> id = Integer.parseInt(request.getParameter("id"<span style="color: rgba(0, 0, 0, 1)">)); request.setAttribute(</span>"message", bookservice.delete(id) > 0 ? "删除成功!" : "删除失败!"<span style="color: rgba(0, 0, 0, 1)">); request.setAttribute(</span>"books"<span style="color: rgba(0, 0, 0, 1)">, bookservice.getAllBooks()); </span><span style="color: rgba(0, 0, 255, 1)">return</span> "ListBook.jsp"<span style="color: rgba(0, 0, 0, 1)">; } </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 多删除图书Action</span> <span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String Deletes(HttpServletRequest request, HttpServletResponse response) { String[] ids </span>= request.getParameterValues("ids"<span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (ids!=<span style="color: rgba(0, 0, 255, 1)">null</span>&&ids.length > 0<span style="color: rgba(0, 0, 0, 1)">) { request.setAttribute(</span>"message", bookservice.delete(ids) > 0 ? "删除成功!" : "删除失败!"<span style="color: rgba(0, 0, 0, 1)">); } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> { request.setAttribute(</span>"message", "请选择删除项!"<span style="color: rgba(0, 0, 0, 1)">); } request.setAttribute(</span>"books"<span style="color: rgba(0, 0, 0, 1)">, bookservice.getAllBooks()); </span><span style="color: rgba(0, 0, 255, 1)">return</span> "ListBook.jsp"<span style="color: rgba(0, 0, 0, 1)">; } </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 添加图书Action</span> <span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String AddBook(HttpServletRequest request, HttpServletResponse response) { </span><span style="color: rgba(0, 0, 255, 1)">return</span> "AddBook.jsp"<span style="color: rgba(0, 0, 0, 1)">; } </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 保存添加图书Action</span> <span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String AddBookPost(HttpServletRequest request, HttpServletResponse response) { </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> { String title </span>= request.getParameter("title"<span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 0, 255, 1)">double</span> price = Double.parseDouble(request.getParameter("price"<span style="color: rgba(0, 0, 0, 1)">)); SimpleDateFormat simpleDateFormat </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> SimpleDateFormat("yyyy-MM-dd"<span style="color: rgba(0, 0, 0, 1)">); Date publishDate </span>= simpleDateFormat.parse(request.getParameter("publishDate"<span style="color: rgba(0, 0, 0, 1)">)); Book entity </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> Book(0<span style="color: rgba(0, 0, 0, 1)">, title, price, publishDate); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (bookservice.add(entity) > 0<span style="color: rgba(0, 0, 0, 1)">) { request.setAttribute(</span>"model", <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Book()); request.setAttribute(</span>"message", "添加成功!"<span style="color: rgba(0, 0, 0, 1)">); } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> { request.setAttribute(</span>"model"<span style="color: rgba(0, 0, 0, 1)">, entity); request.setAttribute(</span>"message", "添加失败!"<span style="color: rgba(0, 0, 0, 1)">); } } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception exp) { request.setAttribute(</span>"message"<span style="color: rgba(0, 0, 0, 1)">, exp.getMessage()); exp.printStackTrace(); } </span><span style="color: rgba(0, 0, 255, 1)">return</span> "AddBook.jsp"<span style="color: rgba(0, 0, 0, 1)">; } </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">编辑图书Action</span> <span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String EditBook(HttpServletRequest request, HttpServletResponse response) { </span><span style="color: rgba(0, 0, 255, 1)">int</span> id = Integer.parseInt(request.getParameter("id"<span style="color: rgba(0, 0, 0, 1)">)); Book model</span>=<span style="color: rgba(0, 0, 0, 1)">bookservice.getBookById(id); request.setAttribute(</span>"model"<span style="color: rgba(0, 0, 0, 1)">, model); </span><span style="color: rgba(0, 0, 255, 1)">return</span> "EditBook.jsp"<span style="color: rgba(0, 0, 0, 1)">; } </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 保存编辑图书Action</span> <span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> String EditBookPost(HttpServletRequest request, HttpServletResponse response) { </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> { </span><span style="color: rgba(0, 0, 255, 1)">int</span> id=Integer.parseInt(request.getParameter("id"<span style="color: rgba(0, 0, 0, 1)">)); String title </span>= request.getParameter("title"<span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 0, 255, 1)">double</span> price = Double.parseDouble(request.getParameter("price"<span style="color: rgba(0, 0, 0, 1)">)); SimpleDateFormat simpleDateFormat </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> SimpleDateFormat("yyyy-MM-dd"<span style="color: rgba(0, 0, 0, 1)">); Date publishDate </span>= simpleDateFormat.parse(request.getParameter("publishDate"<span style="color: rgba(0, 0, 0, 1)">)); Book entity </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Book(id, title, price, publishDate); request.setAttribute(</span>"message", bookservice.update(entity) > 0 ? "更新成功!" : "更新失败!"<span style="color: rgba(0, 0, 0, 1)">); request.setAttribute(</span>"model"<span style="color: rgba(0, 0, 0, 1)">, entity); } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception exp) { request.setAttribute(</span>"message"<span style="color: rgba(0, 0, 0, 1)">, exp.getMessage()); exp.printStackTrace(); } </span><span style="color: rgba(0, 0, 255, 1)">return</span> "EditBook.jsp"<span style="color: rgba(0, 0, 0, 1)">; }
}
11.2、图书列表与删除
定义视图 ListBook.jsp,用于完成图书管理,实现图书的列表、删除与多删除功能,页面脚本如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link href="styles/main.css" type="text/css" rel="stylesheet" /> <title>图书管理</title> </head> <body> <div class="main"> <h2 class="title"><span>图书管理</span></h2> <form action="BookController.do?act=Deletes" method="post"> <table border="1" width="100%" class="tab"> <tr> <th><input type="checkbox" id="chbAll"></th> <th>编号</th> <th>书名</th> <th>价格</th> <th>出版日期</th> <th>操作</th> </tr> <c:forEach var="book" items="${books}"> <tr> <th><input type="checkbox" name="ids" value="${book.id}"></th> <td>${book.id}</td> <td>${book.title}</td> <td>${book.price}</td> <td><fmt:formatDate value="${book.publishDate}" pattern="yyyy 年 MM 月 dd 日"/></td> <td> <a href="BookController.do?act=Delete&id=${book.id}" class="abtn">删除</a> <a href="BookController.do?act=EditBook&id=${book.id}" class="abtn">编辑</a> </td> </tr> </c:forEach> </table> <p style="color: red">${message}</p> <p> <a href="BookController.do?act=AddBook" class="abtn">添加</a> <input type="submit" value="删除选择项" class="btn"/> </p> </form> </div> </body> </html>
运行时效果如下图所示:
11.3、新增图书功能
定义页面 AddBook.jsp 完成添加图书功能,在控制器中有两个 Action 对应新增功能,一个是 AddBook,完成页面展示;另一个是 AddBookPost 处理保存事件,页面脚本如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link href="styles/main.css" type="text/css" rel="stylesheet" /> <title>新增图书</title> </head> <body> <div class="main"> <h2 class="title"><span>新增图书</span></h2> <form action="BookController.do?act=AddBookPost" method="post"> <fieldset> <legend>图书</legend> <p> <label for="title">图书名称:</label> <input type="text" id="title" name="title" value="${model.title}"/> </p> <p> <label for="title">图书价格:</label> <input type="text" id="price" name="price" value="${model.price}"/> </p> <p> <label for="title">出版日期:</label> <input type="text" id="publishDate" name="publishDate" value="${model.publishDate}"/> </p> <p> <input type="submit" value="保存" class="btn"> </p> </fieldset> </form> <p style="color: red">${message}</p> <p> <a href="BookController.do?act=ListBook" class="abtn">返回列表</a> </p> </div> </body> </html>
运行成功时的状态如下:
11.4、编辑图书功能
定义页面 EditBook.jsp 完成更新图书功能,在控制器中有两个 Action 对应更新功能,一个是 EditBook,完成页面展示与加载要编辑图书实体的信息;另一个是 EditBookPost 处理保存事件,页面脚本如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link href="styles/main.css" type="text/css" rel="stylesheet" /> <title>编辑图书</title> </head> <body> <div class="main"> <h2 class="title"><span>编辑图书</span></h2> <form action="BookController.do?act=EditBookPost" method="post"> <fieldset> <legend>图书</legend> <p> <label for="title">图书名称:</label> <input type="text" id="title" name="title" value="${model.title}"/> </p> <p> <label for="title">图书价格:</label> <input type="text" id="price" name="price" value="${model.price}"/> </p> <p> <label for="title">出版日期:</label> <input type="text" id="publishDate" name="publishDate" value="<fmt:formatDate value="${model.publishDate}" pattern="yyyy-MM-dd"/>"/> </p> <p> <input type="hidden" id="id" name="id" value="${model.id}"/> <input type="submit" value="保存" class="btn"> </p> </fieldset> </form> <p style="color: red">${message}</p> <p> <a href="BookController.do?act=ListBook" class="abtn">返回列表</a> </p> </div> </body> </html>
运行时的状态如下所示:
11.5、首页与样式
定义 index.jsp 页面,让其转发到指定的控制器(有点类似路由功能了),页面代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <jsp:forward page="BookController.do?act=ListBook"></jsp:forward>
定义了一个简陋的样式 main.css,样式表脚本如下:
@CHARSET "UTF-8";
- {
margin: 0;
padding: 0;
font-family: microsoft yahei;
font-size: 14px;
}
body {
padding-top: 20px;
}
.main {
width: 90%;
margin: 0 auto;
border: 1px solid #777;
padding: 20px;
}
.main .title {
font-size: 20px;
font-weight: normal;
border-bottom: 1px solid #ccc;
margin-bottom: 15px;
padding-bottom: 5px;
color: blue;
}
.main .title span {
display: inline-block;
font-size: 20px;
background : blue;
color: #fff;
padding: 0 8px;
background: blue;
}
a {
color: blue;
text-decoration: none;
}
a:hover {
color: orangered;
}
.tab td, .tab, .tab th {
border: 1px solid #777;
border-collapse: collapse;
}
.tab td, .tab th {
line-height: 26px;
height: 26px;
padding-left: 5px;
}
.abtn {
display: inline-block;
height: 20px;
line-height: 20px;
background: blue;
color: #fff;
padding: 0 5px;
}
.btn {
height: 20px;
line-height: 20px;
background: blue;
color: #fff;
padding: 0 8px;
border:0;
}
.abtn:hover,.btn:hover{
background: orangered;
color: #fff;
}
p{
padding:5px 0;
}
fieldset{
border: 1px solid #ccc;
padding:5px 10px;
}
fieldset legend{
margin-left:10px;
font-size:16px;
}
十二、总结与示例下载
这个 Demo 起到了承前启后的作用,通过该示例将前面学习过的 Spring IOC、MyBatis、JSP、Servlet、Maven 及 Spring 整合 MyBatis 的内容进行巩固,也为后面学习 Spring MVC 作好了铺垫。示例中隐约的实现了一些 MVC 的功能,这远远不够,在 URL 的处理、表单验证、自动映射表单等方面还可以完善,只想有一个抛砖引玉的作用就满意了,谢谢您的阅读,谢谢!