ssm + maven 编写客户信息管理系统

情到浓时终转凉″ 提交于 2019-11-27 04:59:19

前言

之前编写了servlet+jsp版本的客户信息管理系统,在学习了ssm框架和maven的相关知识后,尝试着使用ssm+maven来实现客户信息管理系统。

项目下载地址:ssm+maven实现客户信息管理系统

项目介绍

  • 使用框架:spring4+mybatis+springMVC
  • 数据库:mysql5.7
  • 项目管理工具:maven
  • 编译器:intellij idea

准备工作

  1. 编译器:intellij idea或eclipse(这里使用的是intellij idea编译器)
  2. 创建maven项目:可以使用编译器中直接生成maven项目,也可以使用命令行创建maven项目。具体教程参考:maven教程

这里直接使用idea创建出maven项目,并且在补全相应目录后,构建所得的项目结构如下:


使用maven管理项目的好处就是,不需要你自己去官网下载项目所需要的jar包,maven会自动帮你从本地仓库或者中央仓库寻找jar包。具体方式是通过pom.xml引入。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<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.silver</groupId>
  <artifactId>customer</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>customer Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <!--注意,引入相关依赖的时候一定要引入正确的版本(版本不匹配可能会出现错误)-->
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

      <!--引入3.1.0版本的servlet以及相关web依赖-->
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>

      <!--引入数据库相关依赖-->
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
        <version>5.1.46</version>
      </dependency>
    <dependency>
      <groupId>com.mchange</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.5.2</version>
    </dependency>

      <!--引入mybatis及mybatis和spring的整合包-->
      <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis</artifactId>
        <version>3.4.6</version>
      </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.2</version>
    </dependency>

    <!--引入spring核心依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
        <version>4.3.8.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.3.8.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.8.RELEASE</version>
    </dependency>
    <!--引入spring dao层依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>4.3.8.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>4.3.8.RELEASE</version>
    </dependency>
    <!--引入spring web层依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.3.8.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.3.8.RELEASE</version>
    </dependency>
    <!--spring test相关依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>4.3.8.RELEASE</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>customer</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.20.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

一、dao层编写

dao层主要是进行数据的持久化操作,连接数据库并实现CURD操作。

1. 建表

创建客户信息表customer以及插入数据,这里使用ddl语句建表。对应的sql文件放在java/sql目录下

-- 数据库初始化脚本

-- 创建数据库
CREATE DATABASE customer;

-- 切换到customer数据库
use customer;

-- 建表
CREATE TABLE `customer` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `gender` varchar(50) NOT NULL,
  `phone` varchar(50) NOT NULL,
  `email` varchar(50) DEFAULT NULL,
  `description` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- 插入数据
INSERT INTO customer(name,gender,phone,email,description)
  VALUES ('小明','男','13723232333','小明@126.com','我是小明'),
          ('小红','女','15689897568','小红@126.com','我是小红'),
          ('张飞','男','15826547965','张飞@126.com','我是张飞'),
          ('关羽','男','13621214896','关羽@126.com','我是关羽'),
          ('刘备','男','12345678910','刘备@126.com','我是刘备');

2.编写对应的实体类

在java/com/silver目录下新建entity包,用来存放实体类。entity包下新建Customer.java

package com.silver.entity;

/**
 * 封装客户信息(id,姓名,性别,电话,邮箱,个人描述)的pojo类
 * @author 光玉
 * @create 2018-05-16 22:36
 **/
public class Customer {
    private long id;
    private String name;
    private String gender;
    private String phone;
    private String email;           // 不是必填项
    private String description;     // 不是必填项

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Boolean isNull(){    // 判断除id外的属性是否为空,用于后面编写controller模糊查询时的判断
        if(this.name == null && this.gender == null &&  this.phone == null
                && this.email == null && this.description == null){
            return true;
        }
        return false;
    }

    @Override
    public String toString() {
        return "Customer{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", phone='" + phone + '\'' +
                ", email='" + email + '\'' +
                ", description='" + description + '\'' +
                '}';
    }
}

还需要一个分页操作的PageBean.java

package com.silver.entity;

import java.util.List;

/**
 * 进行分页操作的Java Bean封装
 * @author 光玉
 * @create 2018-05-17 14:09
 **/
public class PageBean<Object> {
    private int pageNum;                // 当前页码
    private int pageRecord;             // 每页记录数
    private int totalRecord;            // 总记录数
    private int totalPage;              // 总页数
    private List<Object> beanList;      // 当前页的记录

    public int getPageNum() {
        return pageNum;
    }

    public void setPageNum(int pageNum) {
        this.pageNum = pageNum;
    }

    public int getPageRecord() {
        return pageRecord;
    }

    public void setPageRecord(int pageRecord) {
        this.pageRecord = pageRecord;
    }

    public int getTotalRecord() {
        return totalRecord;
    }

    public void setTotalRecord(int totalRecord) {
        this.totalRecord = totalRecord;
    }

    public int getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }

    public List<Object> getBeanList() {
        return beanList;
    }

    public void setBeanList(List<Object> beanList) {
        this.beanList = beanList;
    }

    @Override
    public String toString() {
        return "PageBean{" +
                "pageNum=" + pageNum +
                ", pageRecord=" + pageRecord +
                ", totalRecord=" + totalRecord +
                ", totalPage=" + totalPage +
                ", beanList=" + beanList +
                '}';
    }
}

3. 数据库CURD操作

在java/com/silver下新建dao包,在dao包中新建CustomerDao接口,用来实现数据库CURD操作。

package com.silver.dao;

import com.silver.entity.Customer;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * 客户信息dao层编写(增,删,查,改操作)
 * @author 光玉
 * @create 2018-05-16 22:49
 **/
public interface CustomerDao {
    /**
     * 由于有多个形参,在spring中形参是以arg0,arg1...的形式传递的,需要使用@Param设置对应的名字
     * 分页查询客户
     * @param offset            偏移量
     * @param pageRecord        每页记录数
     * @return
     */
    public List<Customer> findAll(@Param("offset") int offset,@Param("pageRecord") int pageRecord);

    /**
     * 通过id查找应客户信息
     * @param id
     * @return
     */
    public Customer findById(long id) throws Exception;

    /**
     * 通过传入的customer对象获取对应客户信息,并将其插入数据库
     * @param customer
     */
    public void addCustomer(Customer customer) throws Exception;

    /**
     * 通过id来删除对应的客户
     * @param id
     */
    public void deleteCustomer(long id) throws Exception;

    /**
     * 根据id修改信息,传入要修改的信息
     * @param id
     * @param customer
     * @throws Exception
     */
    public void editCustomer(@Param("id") long id,@Param("customer") Customer customer)throws Exception;

    /**
     * 返回客户列表的总记录数(模糊查询时,返回模糊查询总记录数)
     * @param customer
     * @return
     * @throws Exception
     */
    public int countCustomers(@Param("customer") Customer customer)throws Exception;

    /**
     * 分页查询客户,并且有模糊查询功能
     * @param offset
     * @param pageRecord
     * @param customer
     * @return
     * @throws Exception
     */
    public List<Customer> queryAll(@Param("offset") int offset,@Param("pageRecord") int pageRecord,@Param("customer") Customer customer) throws Exception;

}

4. 配置dao层的配置文件

注意:配置文件都放在java/resources目录下。

a. mybatis全局配置文件

mybatis作为持久层框架,用来和数据库进行交互。

在resources目录下新建mybatis-config.xml文件。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--配置全局属性-->
    <settings>
        <!--使用jdbc的getGeneratekeys获取自增主键值-->
        <setting name="useGeneratedKeys" value="true"/>
        <!--使用列别名替换列名  默认值为true
        select name as title(实体中的属性名是title) form table;
        开启后mybatis会自动帮我们把表中name的值赋到对应实体的title属性中
        -->
        <setting name="useColumnLabel" value="true"/>
    </settings>

</configuration>

b. 编写要映射到mybatis的mapper

在resources目录下新建mapper包,用来存放映射文件。在mapper包下新建CustomerDao.xml文件。

<?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">
<!-- 将CustomerDao接口对应方法映射到mybatis中,编写相应的sql语句 -->
<mapper namespace="com.silver.dao.CustomerDao">
    <select id="findAll" resultType="Customer">
        SELECT * FROM customer
        limit #{offset}, #{pageRecord}
    </select>

    <select id="findById" resultType="Customer" parameterType="long">
        SELECT * FROM customer
        WHERE id = #{id}
    </select>

    <insert id="addCustomer">
        INSERT INTO customer(id,name,gender,phone,email,description)
        VALUES (null,#{name},#{gender},#{phone},#{email},#{description})
    </insert>

    <delete id="deleteCustomer" parameterType="long">
        DELETE FROM customer
        WHERE id = #{id}
    </delete>

    <update id="editCustomer">
        UPDATE customer
        SET name = #{customer.name},
            phone = #{customer.phone},
            gender = #{customer.gender},
            email = #{customer.email},
            description = #{customer.description}
        WHERE id = #{id}
    </update>

    <select id="countCustomers" resultType="int">
        SELECT COUNT(*) FROM customer
        <!--包含模糊查询sql片段-->
        <include refid="query_customer_where"/>
    </select>

    <select id="queryAll" resultType="Customer">
        SELECT * FROM customer
        <!--包含模糊查询sql片段-->
        <include refid="query_customer_where"/>
        limit #{offset}, #{pageRecord}
    </select>

    <!--用来模糊查询的sql片段-->
    <sql id="query_customer_where">
        WHERE 1 = 1
        <!--使用动态sql语句,通过if进行判断,满足条件则进行拼接-->
        <if test="customer != null">
            <if test="customer.name != null and customer.name != ''">
                and name like "%${customer.name}%"
            </if>
            <if test="customer.gender != null and customer.gender != ''">
                and gender like "%${customer.gender}%"
            </if>
            <if test="customer.phone != null and customer.phone != ''">
                and phone like "%${customer.phone}%"
            </if>
            <if test="customer.email != null and customer.email != ''">
                and email like "%${customer.email}%"
            </if>
            <if test="customer.description != null and customer.description != ''">
                and description like "%${customer.description}%"
            </if>
        </if>
    </sql>
</mapper>

c. 整合spring和mybatis

首先,在resources目录下新建jdbc.properties文件,用来设置数据库相关参数。(这里使用的是mysql数据库,如果使用的 是其他数据库,请自行修改参数)

# url中“useSSL=false”表示不使用SSL连接(也可以设置为true),如果使用高版本的mysql,不写上的话会在控制台输出警告
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/customer?useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.username=mysql
jdbc.password=123456

接着,在resources目录下新建spring目录,在spring目录下新建spring-dao.xml文件,用来整合spring和mybatis。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!--整合mybatis-->
    <!--1、配置数据库相关参数-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--2、配置数据库连接池-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!--配置连接池属性-->
        <property name="driverClass" value="${jdbc.driver}" />

        <!-- 基本属性 url、user、password -->
        <property name="jdbcUrl" value="${jdbc.url}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />

        <!--c3p0私有属性-->
        <property name="maxPoolSize" value="30"/>
        <property name="minPoolSize" value="10"/>
        <!--关闭连接后不自动commit-->
        <property name="autoCommitOnClose" value="false"/>

        <!--获取连接超时时间,如果数据库连接不上的话,可以试试把超时时间设长一点-->
        <property name="checkoutTimeout" value="3000"/>
        <!--当获取连接失败重试次数-->
        <property name="acquireRetryAttempts" value="2"/>
    </bean>

    <!--3、配置sqlSessionFactory对象-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--spring和mybatis的整合-->
        <!--注入数据库连接池-->
        <property name="dataSource" ref="dataSource"/>
        <!--配置mybatis全局配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--扫描实体类的包,使用别名-->
        <property name="typeAliasesPackage" value="com.silver.entity"/>
        <!--扫描sql配置文件-->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
    </bean>

    <!--4、配置扫描dao接口包,动态实现Dao接口,注入到spring容器中-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--注入sqlSessionFactory-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--给出需要扫描的dao接口-->
        <property name="basePackage" value="com.silver.dao"/>
    </bean>
</beans>

d. 编写dao测试类

测试类保存在test目录中,生成的测试类CustomerDaoTest.java,目录结构及代码如下:


package com.silver.dao;

import com.silver.entity.Customer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;
import java.util.List;

import static org.junit.Assert.*;

@RunWith(SpringJUnit4ClassRunner.class)
// 配置文件路径
@ContextConfiguration({"classpath:spring/spring-dao.xml"})
public class CustomerDaoTest {

    // 注入依赖
    @Resource
    private CustomerDao customerDao;

    @Test
    public void findAll() {
        int pageNum = 1;            // 当前页数
        int pageRecord = 10;        // 每页记录数
        List<Customer> customers = customerDao.findAll((pageNum - 1) * pageRecord, pageRecord);
        for (Customer c : customers) {
            System.out.println(c);
        }
    }


    @Test
    public void findById() throws Exception {
        // 根据id查找对应客户
        long id = 3L;
        Customer customer = customerDao.findById(id);
        System.out.println(customer);
    }

    @Test
    public void addCustomer() throws Exception {
        // 添加客户
        Customer customer = new Customer();
        customer.setName("曹操");
        customer.setGender("男");
        customer.setPhone("13245987562");
        //customer.setEmail(null);
        customer.setDescription("我是曹操");
        customerDao.addCustomer(customer);
    }

    @Test
    public void deleteCustomer() throws Exception {
        // 通过id删除客户
        long id = 4L;
        customerDao.deleteCustomer(id);
    }

    @Test
    public void editCustomer() throws Exception {
        // 修改客户信息
        long id = 1L;
        Customer customer = customerDao.findById(id);
        customer.setDescription("小明同学");            // 修改id为1的客户的个人描述
        customerDao.editCustomer(id,customer);
        System.out.println(customerDao.findById(id));   // 输出修改后的信息
    }

    @Test
    public void countCustomers() throws Exception{
        // 查找客户总记录数
        Customer customer = new Customer();         // 进行模糊查询所要传入的客户信息
        customer.setName("小");
        int count = customerDao.countCustomers(customer);
        System.out.println("客户数量:"+count);
    }

    @Test
    public void queryAll() throws Exception {
        // 分页显示客户列表,并且有模糊查询的功能
        int pageNum = 1;                            // 页数
        int pageRecord = 10;                        // 每页记录数
        Customer customer = new Customer();         // 设置要模糊查询的客户信息
        customer.setName("小");                     // 按照名字模糊查询
        List<Customer> customers = customerDao.queryAll((pageNum - 1) * pageRecord, pageRecord, customer);
        for (Customer c : customers) {
            System.out.println(c);
        }
    }
}

这里使用的是junit4测试工具,在pom.xml中有进行配置。

二、service层编写

service层主要是处理相关的业务逻辑,通过调用dao层实现相应操作。

1. 编写service接口及对应的实现类

在com/silver目录下新建service包,在service包下新建CustomerService接口。

package com.silver.service;

import com.silver.entity.Customer;
import com.silver.entity.PageBean;

import java.util.List;

/**
 * 业务层,编写业务逻辑,调用Dao层
 * @author 光玉
 * @create 2018-05-17 16:07
 **/
public interface CustomerService {
    /**
     * 分页查询
     * @param offset
     * @param pageRecord
     * @return
     */
    public PageBean<Customer> allList(int offset, int pageRecord) throws Exception;

    /**
     * 通过id查找客户
     * @param id
     * @return
     * @throws Exception
     */
    public Customer getById(long id)throws Exception;

    /**
     * 添加客户
     * @param customer
     * @throws Exception
     */
    public void insert(Customer customer)throws Exception;

    /**
     * 通过id删除客户
     * @param id
     * @throws Exception
     */
    public void delete(long id)throws Exception;

    /**
     * 修改客户信息
     * @param id
     * @param customer
     * @throws Exception
     */
    public void update(long id,Customer customer)throws Exception;

    /**
     * 分页查询,模糊查询,还需要在Service实现类中编写一些业务逻辑
     * @param offset
     * @param pageRecord
     * @param customer
     * @return
     * @throws Exception
     */
    public PageBean<Customer> queryList(int offset, int pageRecord, Customer customer)throws Exception;

}

在service包下新建impl包,在impl包下新建service实现类CustomerServiceImpl。在实现类中编写相关业务逻辑代码。

package com.silver.service.impl;

import com.silver.dao.CustomerDao;
import com.silver.entity.Customer;
import com.silver.entity.PageBean;
import com.silver.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Service接口的实现类
 * @author 光玉
 * @create 2018-05-17 16:54
 **/
@Service
public class CustomerServiceImpl implements CustomerService{
    // 注入依赖
    @Autowired
    private CustomerDao customerDao;

    @Override
    public PageBean<Customer> allList(int offset, int pageRecord) throws Exception{
        List<Customer> customers = customerDao.findAll(offset,pageRecord);
        Customer customer = new Customer();
        int totalRecord = customerDao.countCustomers(customer);                         // 获取总记录数
        int pageNum = offset/pageRecord + 1;                                            // 当前页数
        // 计算总页数
        int totalPage;
        if (totalRecord % pageRecord == 0){
            totalPage = totalRecord/pageRecord;
        } else {
            totalPage = totalRecord/pageRecord + 1;
        }
        PageBean<Customer> pageBean = new PageBean<>();                                 // 将分页数据封装到PageBean中
        pageBean.setBeanList(customers);
        pageBean.setPageNum(pageNum);
        pageBean.setPageRecord(pageRecord);
        pageBean.setTotalRecord(totalRecord);
        pageBean.setTotalPage(totalPage);

        return pageBean;    // 返回封装后的数据
    }

    @Override
    public Customer getById(long id) throws Exception {
        Customer customer = customerDao.findById(id);
        return customer;
    }

    @Override
    public void insert(Customer customer) throws Exception {
        customerDao.addCustomer(customer);
    }

    @Override
    public void delete(long id) throws Exception {
        customerDao.deleteCustomer(id);
    }

    @Override
    public void update(long id,Customer customer) throws Exception {
        customerDao.editCustomer(id,customer);
    }

    @Override      
    public PageBean<Customer> queryList(int offset, int pageRecord, Customer customer) throws Exception {
        List<Customer> customers = customerDao.queryAll(offset,pageRecord,customer);    // 获取每页的所有记录
        int totalRecord = customerDao.countCustomers(customer);                         // 获取模糊查询总记录数
        int pageNum = offset/pageRecord + 1;                                            // 当前页数
        // 计算总页数
        int totalPage;
        if (totalRecord % pageRecord == 0){
            totalPage = totalRecord/pageRecord;
        } else {
            totalPage = totalRecord/pageRecord + 1;
        }
        PageBean<Customer> pageBean = new PageBean<>();   // 将分页数据封装到PageBean中 
        pageBean.setBeanList(customers);
        pageBean.setPageNum(pageNum);
        pageBean.setPageRecord(pageRecord);
        pageBean.setTotalRecord(totalRecord);
        pageBean.setTotalPage(totalPage);

        return pageBean;       // 返回封装后的数据
    }
}

2. 配置spring-service.xml文件

在resources/spring目录下,新建spring-service.xml文件,用来管理service层。

package com.silver.service;

import com.silver.entity.Customer;
import com.silver.entity.PageBean;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-dao.xml",
                        "classpath:spring/spring-service.xml"})
public class CustomerServiceTest {

    @Autowired
    private CustomerService customerService;

    @Test
    public void allList() throws Exception{
        PageBean<Customer> pageBean = customerService.allList(0, 8);    // 设置每页8条记录
        System.out.println(pageBean);
    }

    @Test
    public void getById() throws Exception{
        long id = 1L;
        Customer customer = customerService.getById(id);
        System.out.println(customer);
    }

    @Test
    public void insert() throws Exception{
        Customer customer = new Customer();
        customer.setName("吕布");
        customer.setGender("男");
        customer.setPhone("15823232333");
        customerService.insert(customer);
    }

    @Test
    public void delete() throws Exception{
        long id = 7L;
        customerService.delete(id);
    }

    @Test
    public void update() throws Exception{
        long id = 1L;
        Customer customer = customerService.getById(id);
        customer.setDescription("我是小明");
        customerService.update(id,customer);
        System.out.println(customer);
    }

    @Test
    public void queryList() throws Exception{
        int offset = 0;
        int pageRecord = 8;
        Customer customer = new Customer();
        customer.setName("小");
        PageBean<Customer> pageBean = customerService.queryList(offset, pageRecord, customer);
        System.out.println(pageBean);
    }
}

三、controller层编写

controller(handler),也就是控制器,负责和前端页面进行交互(如:显示前端页面视图,接收前端传过来的数据等)。

1. 编写CustomerController.java

在com/silver下新建controller包,在controller包下新建CustomerController.java

package com.silver.controller;

import com.silver.entity.Customer;
import com.silver.entity.PageBean;
import com.silver.service.CustomerService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 编写控制器,用来和前端页面进行交互
 * @author 光玉
 * @create 2018-05-18 15:40
 **/
@Controller
@RequestMapping("/customer")        // 相当于模块化,这个模块下的请求格式为“/customer/**”
public class CustomerController {
    @Autowired
    private CustomerService customerService;

    private Customer myCustomer;       // 用来保存模糊查询的客户信息

    // 这里设置了只能使用get方法传递url
    @RequestMapping(value = "/frame", method = RequestMethod.GET)
    public String mainFrame(){
        // 显示主界面
        return "frame";
    }

    @RequestMapping(value = "/allCustomerList/{pageNum}", method = RequestMethod.GET)
    public String allCustomerList(@PathVariable("pageNum") Integer pageNum,Model model) throws Exception{
        // 显示所有客户列表
        // 获取从前端传过来的当前页数,并进行分页操作,显示列表
        if(pageNum == null){
            pageNum = 1;                    // 空则当前页面设置为1
        }
        int pageRecord = 8;                 // 设置每页8条记录
        PageBean<Customer> pb = customerService.allList((pageNum-1)*pageRecord, pageRecord);
        myCustomer = new Customer();        // 实例化myCustomer对象(如果之前有进行模糊查询操作,则相当于清除保存在myCustomer对象中的信息)
        model.addAttribute("pb",pb);    // 将pb对象传到前端页面中
        return "list";
    }

    @RequestMapping(value = "/add",method = RequestMethod.GET)      // 设置传递的url以及设置访问方式
    public String addCustomer() throws Exception{
        return "add";               // 返回添加客户的jsp页面
    }

    @RequestMapping(value = "/addCustomerSubmit",method = RequestMethod.POST)
    public String addCustomerSuccess(Customer customer) throws Exception{
        // 进行添加客户操作
        customerService.insert(customer);
        return "redirect:allCustomerList/1";         // 重定向到列表页面,显示第一页
    }

    @RequestMapping(value = "/edit/{id}",method = RequestMethod.GET)
    public String editCustomer(@PathVariable("id") Long id, Model model)throws Exception{
        // 到要修改客户的信息页
        Customer customer = customerService.getById(id);
        model.addAttribute("customer",customer);
        return "edit";
    }

    @RequestMapping(value = "/editCustomerSubmit",method = RequestMethod.POST)
    public String editCustomerSubmit(@Param("id") Long id,@Param("customer") Customer customer) throws Exception{
        // 传入id和要修改的相关客户信息,执行更新操作
        customerService.update(id,customer);
        return "redirect:allCustomerList/1";
    }

    @RequestMapping(value = "/delete/{id}",method = RequestMethod.GET)
    public void deleteCustomer(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response)throws Exception{
        // 删除客户信息
        customerService.delete(id);
        String url = request.getRequestURL().toString();                // 获取当前请求的url
        String newUrl = url.substring(0,url.lastIndexOf("delete"))
                                + "allCustomerList/1";                  // 重新拼接url

        response.sendRedirect(newUrl);    // 重定向回客户列表的第一页
    }

    @RequestMapping(value = "/query",method = RequestMethod.GET)
    public String queryList(){
        // 进入模糊查询页面
        return "query";
    }

    // 由于模糊查询需要使用post提交表单,这里设置了可以使用get和post方法传递url
    @RequestMapping(value = "/list/{pageNum}", method = {RequestMethod.GET, RequestMethod.POST})
    public String queryCustomerList(@PathVariable("pageNum") Integer pageNum,Customer customer, Model model) throws Exception{
        // 获取从前端传过来的当前页数,并进行分页操作,显示列表,具有模糊查询的功能
        if(pageNum == null){
            pageNum = 1;                 // 空则当前页面设置为1
        }
        int pageRecord = 8;             // 设置每页记录数为8
        if(!customer.isNull()){         // 如果模糊查询中有设置查询信息,则将信息保存到myCustomer对象中
            myCustomer = customer;
        }
        PageBean<Customer> pb = customerService.queryList((pageNum-1)*pageRecord, pageRecord,myCustomer);
        model.addAttribute("pb",pb);

        return "list";
    }

    @RequestMapping(value = "/DevelopDoc",method = RequestMethod.GET)
    public String developDoc(){
        // 显示开发日志页面
        return "DevelopDoc";
    }

}

2. 配置前端控制器

修改webapp/WEB-INF目录下的web.xml文件。

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0"
         metadata-complete="true">
    <!-- 将servletschema定义换为3.0 -->
    <!-- 配置前端控制器 -->
    <servlet>
          <servlet-name>customer-dispatcher</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <!-- 配置springmvc要加载的配置文件
                  spring包下的spring-*.xml文件
                  实现mybatis,spring和springMVC的整合 -->
          <init-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>classpath:spring/spring-*.xml</param-value>
          </init-param>
    </servlet>

    <!-- 进行映射 -->
    <servlet-mapping>
          <servlet-name>customer-dispatcher</servlet-name>
          <!-- 设置“/”表示拦截所有请求,Restful风格 -->
          <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- 表单通过post方式提交,可能会出现乱码问题,需要设置过滤器解决 -->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <!-- 设置过滤器中的属性,将编码格式统一为utf-8 -->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <!-- 这里的/* 表示过滤所有请求 -->
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

3. 编写spring-web.xml文件

在resources/spring目录下新建spring-web.xml文件。用来进行视图,静态资源处理等相关配置。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--配置springmvc-->
    <!--1、配置注解驱动
         可以简化配置:
         a. 直接使用mvc:annotation-driven相当于配置了注解映射器和适配器
         b. 提供一系列功能:数据绑定,数据和日期的format @NumberFormat,@DateTimeFormat
         c. xml,json的默认读写  -->
    <mvc:annotation-driven conversion-service="conversionService">
        <!--这里的conversionService是转换器的配置,在下面会进行具体配置-->
    </mvc:annotation-driven>

    <!--2、配置静态资源处理方式
            当我们使用Restful风格时,所有请求都会经过前端控制器Dispatcher处理解析,
            但是,静态资源并不需要被处理解析,因此,需要单独配置   -->
    <!--webapp/resources目录下为静态文件,配置该文件夹下所有文件均不被解析-->
    <mvc:resources mapping="/resources/**" location="/resources/"/>

    <!--3、配置视图显示ViewResolver,以及jsp页面的相关设置-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--配置jstl标签以及jsp页面的前缀和后缀配置-->
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--4、配置扫描controller包-->
    <context:component-scan base-package="com.silver.controller"/>

    <!--5、配置转换器-->
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <!-- 这里可以配置多个转换器 -->
                <!-- 去除字符串两边空格的转换器 -->
                <bean class="com.silver.controller.converter.TrimStringConverter"/>
            </list>
        </property>
    </bean>
</beans>

在spring-web.xml配置文件中配置了一个去除两边空格的转换器TrimStringConverter.java,所在目录为com/silver/controller/converter。因此,我们需要在com/silver/controller下新建converter包,在converter包下新建TrimStringConverter.java。

package com.silver.controller.converter;

import org.springframework.core.convert.converter.Converter;

/**
 * 去除前后空格的转换器
 * @author 光玉
 * @create 2018-05-20 16:45
 **/
public class TrimStringConverter implements Converter<String,String> {
    // 编写去除前后空格的转换器
    // 若去除空格后字符串为空,则返回null,否则返回去空格后的字符串
    @Override
    public String convert(String source){
        try{
            if(source != null){
                source=source.trim();
                if(source.equals("")){
                    return null;
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return source;
    }
}

4. 前端jsp页面以及所要引入的前端插件

jsp页面放在WEB-INF/jsp目录下,layui前端插件放置在webapp/resources目录下。如有需要,请自行到customer-maven项目下载。

四、效果展示

输入http://localhost:8080/customer/frame查看效果

1. 客户列表页


2. 添加客户


3. 高级搜索


4. 开发日志


最后,项目源码放在ssm+maven实现客户信息管理系统中,有需要的请自行下载。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!