SpringMVC整合mybaitis 一、新建一个基于Maven的Web项目 二、创建数据库与表 三、添加依赖包 四、新建POJO实体层 五、新建MyBatis SQL映射层 六、完成Spring整合MyBatis配置 七、创建服务层 八、JUnit测试服务类 九、加载Spring容器与获得容器对象 十、简单MVC控制器封装 十一、完成图书管理功能 十二、总结与示例下载

SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

目录

该文详细的通过Spring IOC、MyBatis、Servlet、Maven及Spring整合MyBatis的等技术完成一个简单的图书管理功能,实现图书列表、删除、多删除、编辑、新增功能。梳理前面学习的内容《Spring整合MyBatis(Maven+MySQL)一》《Spring整合MyBatis(Maven+MySQL)二》,做一个完整的示例完成一个简单的图书管理功能,主要使用到的技术包含Spring、MyBatis、Maven、MySQL及简单MVC等。最后的运行效果如下所示:

SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

 SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

项目结构如下:

 SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

1.1、创建一个简单的Maven项目,项目信息如下:

SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

 1.2、修改层面信息,在项目上右键选择属性,再选择“Project Facets”,先设置java运行环境为1.7,先去掉"Dynamic Web Module"前的勾,然后保存关闭;再打开勾选上"Dynamic Web Module",版本选择“3.0”;这里在左下解会出现一个超链接,创建“Web Content”,完成关闭。

SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

1.3、修改项目的部署内容。项目上右键属性,选择“Deplyment Assembly”,删除不需要发布的内容如:带“test”的两个目录,WebContent目录,再添加一个main下的webapp目录。

SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

修改后的结果如下所示:

SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

1.4、修改项目内容。将WebContent下的内容复制到/src/main/webapp下,再删除WebContent目录,修改后的结果如下所示:

SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

1.5、添加“服务器运行时(Server Runtime)”,添加后的结果如下:

SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

二、创建数据库与表

启动MySQL,创建数据库,新建表books,插入测试数据,完成后的表如下所示:

SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

创建表的sql脚本如下:

/*
Navicat MySQL Data Transfer

Source Server         : localhost
Source Server Version : 50536
Source Host           : localhost:3306
Source Database       : db1

Target Server Type    : MYSQL
Target Server Version : 50536
File Encoding         : 65001

Date: 2016-07-06 22:05:07
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `books`
-- ----------------------------
DROP TABLE IF EXISTS `books`;
CREATE TABLE `books` (
  `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 KEY `title` (`title`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of books
-- ----------------------------
INSERT INTO `books` VALUES ('1', 'Java编程思想', '98.50', '2005-01-02 00:00:00');
INSERT INTO `books` VALUES ('2', 'HeadFirst设计模式', '55.70', '2010-11-09 00:00:00');
INSERT INTO `books` VALUES ('3', '第一行Android代码', '69.90', '2015-06-23 00:00:00');
INSERT INTO `books` VALUES ('4', 'C++编程思想', '88.50', '2004-01-09 00:00:00');
INSERT INTO `books` VALUES ('5', 'HeadFirst Java', '55.70', '2013-12-17 00:00:00');
INSERT INTO `books` 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>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>4.3.0.RELEASE</spring.version>
    </properties>

    <dependencies>
        <!--Spring框架核心库 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- aspectJ AOP 织入器 -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.9</version>
        </dependency>
        <!-- Spring Web -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--mybatis-spring适配器 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.0</version>
        </dependency>
        <!--Spring java数据库访问包,在本例中主要用于提供数据源 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--mysql数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
        <!--log4j日志包 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.6.1</version>
        </dependency>
        <!-- mybatis ORM框架 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!-- JUnit单元测试工具 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>
        <!--c3p0 连接池 -->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
        <!-- jstl -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>
</project>
SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载
SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

如果是第一次依赖相关的包,则需要下载时间,请耐心等待,如果下载失败请手动下载后复制到本地的资源库中。依赖后的项目结果如下:

SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

四、新建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 >
        select id,title,price,publishDate from books
    </select>
    <!--获得图书对象通过编号 -->
    <select >
        select id,title,price,publishDate from books where id=#{id}
    </select>
    <!-- 增加 -->
    <insert >
        insert into books(title,price,publishDate)
        values(#{title},#{price},#{publishDate})
    </insert>
    <!-- 删除 -->
    <delete >
        delete from books where id=#{id}
    </delete>
    <!-- 更新 -->
    <update >
        update books set title=#{title},price=#{price},publishDate=#{publishDate}
        where id=#{id}
    </update>
</mapper>
SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载
SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

六、完成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">

    <!--1 引入属性文件,在配置中占位使用 -->
    <context:property-placeholder location="classpath*:db.properties" />

    <!--2 配置C3P0数据源 -->
    <bean >
        <!--驱动类名 -->
        <property name="driverClass" value="${jdbc.driver}" />
        <!-- url -->
        <property name="jdbcUrl" value="${jdbc.url}" />
        <!-- 用户名 -->
        <property name="user" value="${jdbc.uid}" />
        <!-- 密码 -->
        <property name="password" value="${jdbc.pwd}" />
        <!-- 当连接池中的连接耗尽的时候c3p0一次同时获取的连接数  -->
        <property name="acquireIncrement" value="5"></property>
        <!-- 初始连接池大小 -->
        <property name="initialPoolSize" value="10"></property>
        <!-- 连接池中连接最小个数 -->
        <property name="minPoolSize" value="5"></property>
        <!-- 连接池中连接最大个数 -->
        <property name="maxPoolSize" value="20"></property>
    </bean>
    
    <!--3 会话工厂bean sqlSessionFactoryBean -->
    <bean >
        <!-- 数据源 -->
        <property name="dataSource" ref="datasource"></property>
        <!-- 别名 -->
        <property name="typeAliasesPackage" value="com.zhangguo.bookstore.entities"></property>
        <!-- sql映射文件路径 -->
        <property name="mapperLocations" value="classpath*:com/zhangguo/bookstore/mapper/*Mapper.xml"></property>
    </bean>
    
    <!--4 自动扫描对象关系映射 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--指定会话工厂,如果当前上下文中只定义了一个则该属性可省去 -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
        <!-- 指定要自动扫描接口的基础包,实现接口 -->
        <property name="basePackage" value="com.zhangguo.bookstore.mapper"></property>
    </bean>
    
    <!--5 声明式事务管理 -->
    <!--定义事物管理器,由spring管理事务 -->
    <bean >
        <property name="dataSource" ref="datasource"></property>
    </bean>
    <!--支持注解驱动的事务管理,指定事务管理器 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

    <!--6 容器自动扫描IOC组件  -->
    <context:component-scan base-package="com.zhangguo.bookstore"></context:component-scan>
    
    <!--7 aspectj支持自动代理实现AOP功能 -->
    <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
</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;
    
    public List<Book> getAllBooks() {
        return bookdao.getAllBooks();
    }
    
    public Book getBookById(int id){
        return bookdao.getBookById(id);
    }
    
    public int add(Book entity) throws Exception {
        if(entity.getTitle()==null||entity.getTitle().equals("")){
            throw new Exception("书名必须不为空");
        }
        return bookdao.add(entity);
    }
    
    @Transactional
    public int add(Book entity1,Book entityBak){
        int rows=0;
        rows=bookdao.add(entity1);
        rows=bookdao.add(entityBak);
        return rows;
    }

    public int delete(int id) {
        return bookdao.delete(id);
    }
    
    /**
     * 多删除
     */
    public int delete(String[] ids){
        int rows=0;
        for (String idStr : ids) {
            int id=Integer.parseInt(idStr);
            rows+=delete(id);
        }
        return rows;
    }

    public int update(Book entity) {
        return 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 {

    static BookService bookservice;
    
    @BeforeClass
    public static void before(){
        ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
        bookservice=ctx.getBean(BookService.class);
    }
    
    @Test
    public void testGetAllBooks() {
        List<Book> books=bookservice.getAllBooks();
        assertNotNull(books);
    }

    @Test
    public void testAdd() {
        Book entity=new Book(0, "Hibernate 第七版", 78.1, new Date());
        try {
            assertEquals(1, bookservice.add(entity));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testDeleteInt() {
        assertEquals(1, bookservice.delete(9));
    }

    @Test
    public void testDeleteStringArray() {
        String[] ids={"7","11","12"};
        assertEquals(3, bookservice.delete(ids));
    }

    @Test
    public void testUpdate() {
        Book entity=new Book(7, "Hibernate 第二版", 79.1, new Date());
        try {
            assertEquals(1, bookservice.update(entity));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    @Test
    public void testGetBookById()
    {
        assertNotNull(bookservice.getBookById(1));
    }
    
    @Test
    public void testAddDouble(){
        //因为书名相同,添加第二本会失败,用于测试事务
        Book entity1=new Book(0, "Hibernate 第八版", 78.1, new Date());
        Book entity2=new Book(0, "Hibernate 第八版", 78.1, new Date());
        assertEquals(2, 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"
     >
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    
    <listener>
        <description>Spring容器加载监听器</description>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <description>设置Spring加载时的配置文件位置,默认位置在web-inf/lib下</description>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:applicationContext.xml</param-value>
    </context-param>
</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");

        // 获得要执行的方法名
        String act = request.getParameter("act");

        // 如果用户没有提供方法名
        if (act == null || act.equals("")) {
            // 默认方法
            act = "execute";
        }

        // 根据方法名获得方法信息获得方法信息
        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();
        }
    }

    public void execute(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.sendError(400, "请使用参数act指定您要访问的方法");
    }
}
 
 

十一、完成图书管理功能

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
    public void init() throws ServletException {
        bookservice = CtxUtil.getBean(BookService.class);
    }

    // 图书列表Action
    public String ListBook(HttpServletRequest request, HttpServletResponse response) {
        request.setAttribute("books", bookservice.getAllBooks());
        return "ListBook.jsp";
    }

    // 删除图书Action
    public String Delete(HttpServletRequest request, HttpServletResponse response) {
        int id = Integer.parseInt(request.getParameter("id"));
        request.setAttribute("message", bookservice.delete(id) > 0 ? "删除成功!" : "删除失败!");
        request.setAttribute("books", bookservice.getAllBooks());
        return "ListBook.jsp";
    }

    // 多删除图书Action
    public String Deletes(HttpServletRequest request, HttpServletResponse response) {
        String[] ids = request.getParameterValues("ids");
        if (ids!=null&&ids.length > 0) {
            request.setAttribute("message", bookservice.delete(ids) > 0 ? "删除成功!" : "删除失败!");
        } else {
            request.setAttribute("message", "请选择删除项!");
        }
        request.setAttribute("books", bookservice.getAllBooks());
        return "ListBook.jsp";
    }

    // 添加图书Action
    public String AddBook(HttpServletRequest request, HttpServletResponse response) {
        return "AddBook.jsp";
    }

    // 保存添加图书Action
    public String AddBookPost(HttpServletRequest request, HttpServletResponse response) {
        try {
            String title = request.getParameter("title");
            double price = Double.parseDouble(request.getParameter("price"));

            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Date publishDate = simpleDateFormat.parse(request.getParameter("publishDate"));

            Book entity = new Book(0, title, price, publishDate);
            if (bookservice.add(entity) > 0) {
                request.setAttribute("model", new Book());
                request.setAttribute("message", "添加成功!");
            } else {
                request.setAttribute("model", entity);
                request.setAttribute("message", "添加失败!");
            }
        } catch (Exception exp) {
            request.setAttribute("message", exp.getMessage());
            exp.printStackTrace();
        }
        return "AddBook.jsp";
    }
    
        //编辑图书Action
        public String EditBook(HttpServletRequest request, HttpServletResponse response) {
            int id = Integer.parseInt(request.getParameter("id"));
            Book model=bookservice.getBookById(id);
            request.setAttribute("model", model);
            return "EditBook.jsp";
        }

        // 保存编辑图书Action
        public String EditBookPost(HttpServletRequest request, HttpServletResponse response) {
            try {
                int id=Integer.parseInt(request.getParameter("id"));
                
                String title = request.getParameter("title");
                double price = Double.parseDouble(request.getParameter("price"));

                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                Date publishDate = simpleDateFormat.parse(request.getParameter("publishDate"));

                Book entity = new Book(id, title, price, publishDate);
                request.setAttribute("message", bookservice.update(entity) > 0 ? "更新成功!" : "更新失败!");
                request.setAttribute("model", entity);
            } catch (Exception exp) {
                request.setAttribute("message", exp.getMessage());
                exp.printStackTrace();
            }
            return "EditBook.jsp";
        }

}
SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载
SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

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" ></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>
 

运行时效果如下图所示:

SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

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" />
            </p>
            <p>
                <label for="title">图书价格:</label>
                <input type="text" />
            </p>
            <p>
                <label for="title">出版日期:</label>
                <input type="text" />
            </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>
 

运行成功时的状态如下:

SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

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" />
            </p>
            <p>
                <label for="title">图书价格:</label>
                <input type="text" />
            </p>
            <p>
                <label for="title">出版日期:</label>
                <input type="text" />
            </p>
            <p>
               <input type="hidden" />
              <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>
 

运行时的状态如下所示:

SpringMVC整合mybaitis
一、新建一个基于Maven的Web项目
二、创建数据库与表
三、添加依赖包
四、新建POJO实体层
五、新建MyBatis SQL映射层
六、完成Spring整合MyBatis配置
七、创建服务层
八、JUnit测试服务类
九、加载Spring容器与获得容器对象
十、简单MVC控制器封装
十一、完成图书管理功能
十二、总结与示例下载

 

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 {
     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作好了铺垫

 demo

1. IDEA,出现 invalid bound statement (not found)解决办法

<!-- 如果不添加此节点mybatis的mapper.xml文件都会被漏掉。 -->
		<resources>
			<resource>
				<directory>src/main/java</directory>
				<includes>
					<include>**/*.properties</include>
					<include>**/*.xml</include>
				</includes>
				<filtering>false</filtering>
			</resource>
			<resource>
				<directory>src/main/resources</directory>
				<includes>
					<include>**/*.properties</include>
					<include>**/*.xml</include>
				</includes>
				<filtering>false</filtering>
			</resource>
		</resources>

2. 新建的IDEA工程,没有JUnit,要在Project Setting 增加 Junit

3.创建一个新的Maven Web工程,然后倒入相关的java和resources代码

4.注意配置文件的路径

5. 关于maven的配置文件,如果公司有私服,使用公司的私服,没有的话,就设置阿里云的镜像,加快maven jar包的下载