CRM项目外观

SSM综合练习

1. 开发环境

IDE Eclipse Neon Release (4.6.0) 

Jdk: 1.8

数据库: MySQL

2. 创建数据库

创建crm数据库,这里使用的是SqlLyog.

SSM综合练习

导入提供的sql文件

SSM综合练习

数据库创建如下

SSM综合练习

3. 工程搭建

使用的Bootstrap前端框架,官方网站

http://www.bootcss.com/

工程使用Springmvcspringmybatis框架整合完成。

 

3.1. 需要的jar

  1. spring(包括springmvc
  2. mybatis
  3. mybatis-spring整合包
  4. 数据库驱动
  5. 第三方连接池。
  6. Json依赖包Jackson

        SSM综合练习

        SSM综合练习

3.2. 整合思路

Dao层:

1、SqlMapConfig.xml,空文件即可,但是需要文件头。

2、applicationContext-dao.xml

a) 数据库连接Druid

b) SqlSessionFactory对象,需要springmybatis整合包下的。

c) 配置mapper文件扫描器。Mapper动态代理开发 增强版

Service层:

1、applicationContext-service.xml包扫描器,扫描@service注解的类。

2、applicationContext-trans.xml配置事务。

Controller层:

1、Springmvc.xml

a) 包扫描器,扫描@Controller注解的类。

b) 配置注解驱动

c) 配置视图解析器

Web.xml文件:

1、配置spring监听器

2、配置前端控制器。

 

3.3. 创建工程

创建动态web工程,步骤如下图:

 SSM综合练习

3.4. 加入jar

加入需要的jar

 

3.5. 加入配置文件

3.5.1. SqlMapConfig.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>

</configuration>

3.5.2. applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

    <!-- 配置 读取properties文件 jdbc.properties -->
    <context:property-placeholder location="classpath:jdbc.properties" />

    <!-- 配置 数据源 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <!-- 配置SqlSessionFactory -->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 设置MyBatis核心配置文件 -->
        <property name="configLocation" value="classpath:SqlMapConfig.xml" />
        <!-- 设置数据源 -->
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- 配置Mapper扫描 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 设置Mapper扫描包 -->
        <property name="basePackage" value="cn.itcast.crm.mapper" />
    </bean>
    
    <!-- 配置Service扫描 -->
    <context:component-scan base-package="cn.itcast.crm.service" />
</beans>

创建好配置里面对应的包名和文件。

3.5.3. jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/crm?characterEncoding=utf-8
jdbc.username=root
jdbc.password=123

3.5.4. springmvc.xml

配置SpringMVC表现层:Controller扫描、注解驱动、视图解析器

<?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: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-4.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!-- 配置Controller扫描 -->
    <context:component-scan base-package="cn.itcast.crm.controller" />

    <!-- 配置注解驱动 -->
    <mvc:annotation-driven />

    <!-- 配置视图解析器 -->
    <bean    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!-- 后缀 -->
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

3.5.5. Web.xml

配置SpringSpringMVC、解决post乱码问题 

<?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_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>crm</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
      <!-- 配置spring -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <!-- 配置监听器加载spring -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- 配置过滤器,解决post的乱码问题 -->
    <filter>
        <filter-name>encoding</filter-name>    
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 配置SpringMVC -->
    <servlet>
        <servlet-name>crm</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <!-- 配置springmvc什么时候启动,参数必须为整数 -->
        <!-- 如果为0或者大于0,则springMVC随着容器启动而启动 -->
        <!-- 如果小于0,则在第一次请求进来的时候启动 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>crm</servlet-name>
        <!-- 所有的请求都进入springMVC -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

 

3.6. 加入静态资源

 最终效果如下:

SSM综合练习

4. 加入分页标签

新建工具包 cn.itcast.common.utils

NavigationTag.java

package cn.itcast.common.utils;

import java.io.IOException;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;


/**
 * 显示格式 上一页 1 2 3 4 5 下一页
 */
public class NavigationTag extends TagSupport {
    static final long serialVersionUID = 2372405317744358833L;
    
    /**
     * request 中用于保存Page<E> 对象的变量名,默认为“page”
     */
    private String bean = "page";
    
    /**
     * 分页跳转的url地址,此属性必须
     */
    private String url = null;
    
    /**
     * 显示页码数量
     */
    private int number = 5;
    
    @Override
    public int doStartTag() throws JspException {
        JspWriter writer = pageContext.getOut();
        HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
        Page page = (Page)request.getAttribute(bean); 
        if (page == null) 
            return SKIP_BODY;
        url = resolveUrl(url, pageContext);
        try {
            //计算总页数
            int pageCount = page.getTotal() / page.getSize();
            if (page.getTotal() % page.getSize() > 0) {
                pageCount++;
            }
            writer.print("<nav><ul class=\"pagination\">");
            //显示“上一页”按钮
            if (page.getPage() > 1) {
                String preUrl = append(url, "page", page.getPage() - 1);
                preUrl = append(preUrl, "rows", page.getSize());
                writer.print("<li><a href=\"" + preUrl + "\">上一页</a></li>");
            } else {
                writer.print("<li class=\"disabled\"><a href=\"#\">上一页</a></li>");
            }
            //显示当前页码的前2页码和后两页码 
            //若1 则 1 2 3 4 5, 若2 则 1 2 3 4 5, 若3 则1 2 3 4 5,
            //若4 则 2 3 4 5 6 ,若10  则 8 9 10 11 12
            int indexPage = (page.getPage() - 2 > 0)? page.getPage() - 2 : 1;  
            for(int i=1; i <= number && indexPage <= pageCount; indexPage++, i++) {
                if(indexPage == page.getPage()) {
                    writer.print( "<li class=\"active\"><a href=\"#\">"+indexPage+"<span class=\"sr-only\">(current)</span></a></li>");
                    continue;
                }
                String pageUrl  = append(url, "page", indexPage);
                pageUrl = append(pageUrl, "rows", page.getSize());
                writer.print("<li><a href=\"" + pageUrl + "\">"+ indexPage +"</a></li>");
            }
            //显示“下一页”按钮
            if (page.getPage() < pageCount) {
                String nextUrl  = append(url, "page", page.getPage() + 1);
                nextUrl = append(nextUrl, "rows", page.getSize());
                writer.print("<li><a href=\"" + nextUrl + "\">下一页</a></li>");
            } else {
                writer.print("<li class=\"disabled\"><a href=\"#\">下一页</a></li>");
            }
            writer.print("</nav>");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return SKIP_BODY;
    }
    
    private String append(String url, String key, int value) {

        return append(url, key, String.valueOf(value));
    }
    
    /**
     * 为url 参加参数对儿
     * 
     * @param url
     * @param key
     * @param value
     * @return
     */
    private String append(String url, String key, String value) {
        if (url == null || url.trim().length() == 0) {
            return "";
        }

        if (url.indexOf("?") == -1) {
            url = url + "?" + key + "=" + value;
        } else {
            if(url.endsWith("?")) {
                url = url + key + "=" + value;
            } else {
                url = url + "&amp;" + key + "=" + value;
            }
        }
        
        return url;
    }
    
    /**
     * 为url 添加翻页请求参数
     * 
     * @param url
     * @param pageContext
     * @return
     * @throws javax.servlet.jsp.JspException
     */
    private String resolveUrl(String url, javax.servlet.jsp.PageContext pageContext) throws JspException{
        //UrlSupport.resolveUrl(url, context, pageContext)
        Map params = pageContext.getRequest().getParameterMap();
        for (Object key:params.keySet()) {
            if ("page".equals(key) || "rows".equals(key)) continue;
            Object value = params.get(key);
            if (value == null) continue;
            if (value.getClass().isArray()) {
                url = append(url, key.toString(), ((String[])value)[0]);
            } else if (value instanceof String) {
                url = append(url, key.toString(), value.toString());
            }
        }
        return url;
    }
    
    
    public String getBean() {
        return bean;
    }

    public void setBean(String bean) {
        this.bean = bean;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void setNumber(int number) {
        this.number = number;
    }
    
}

Page.java

package cn.itcast.common.utils;

import java.util.List;

public class Page<T> {
    
    private int total;
    private int page;
    private int size;
    private List<T> rows;
    public int getTotal() {
        return total;
    }
    public void setTotal(int total) {
        this.total = total;
    }
    public int getPage() {
        return page;
    }
    public void setPage(int page) {
        this.page = page;
    }
    public int getSize() {
        return size;
    }
    public void setSize(int size) {
        this.size = size;
    }
    public List<T> getRows() {
        return rows;
    }
    public void setRows(List<T> rows) {
        this.rows = rows;
    }   
}

5. 实现页面展示

配置springmvc.xml,释放静态资源

    <!-- 对静态资源放行  -->
    <mvc:resources location="/css/" mapping="/css/**"/>
    <mvc:resources location="/js/" mapping="/js/**"/>
    <mvc:resources location="/fonts/" mapping="/fonts/**"/>

创建CustomerController.java

package cn.itcast.crm.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("customer")
public class CustomerController {
    
    @RequestMapping("list")
    public String list(){
        return "customer";
    }
}

访问页面:http://localhost:8080/crm/customer/list.action

效果如下:

SSM综合练习

6. 实现查询条件初始化

6.1. 需求分析

SSM综合练习

页面效果如上图,在查询客户的时候,可以选择客户来源,所属行业,客户级别信息,页面加载时需要初始化查询条件下拉列表。

 前端jsp逻辑:

    <div class="form-group">
                            <label for="customerFrom">客户来源</label> 
                            <select    class="form-control" id="customerFrom" placeholder="客户来源" name="custSource">
                                <option value="">--请选择--</option>
                                <c:forEach items="${fromType}" var="item">
                                    <option value="${item.dict_id}"<c:if test="${item.dict_id == custSource}"> selected</c:if>>${item.dict_item_name }</option>
                                </c:forEach>
                            </select>
                        </div>
                        <div class="form-group">
                            <label for="custIndustry">所属行业</label> 
                            <select    class="form-control" id="custIndustry"  name="custIndustry">
                                <option value="">--请选择--</option>
                                <c:forEach items="${industryType}" var="item">
                                    <option value="${item.dict_id}"<c:if test="${item.dict_id == custIndustry}"> selected</c:if>>${item.dict_item_name }</option>
                                </c:forEach>
                            </select>
                        </div>
                        <div class="form-group">
                            <label for="custLevel">客户级别</label>
                            <select    class="form-control" id="custLevel" name="custLevel">
                                <option value="">--请选择--</option>
                                <c:forEach items="${levelType}" var="item">
                                    <option value="${item.dict_id}"<c:if test="${item.dict_id == custLevel}"> selected</c:if>>${item.dict_item_name }</option>
                                </c:forEach>
                            </select>
                        </div>

6.2. 实现Dao开发

6.2.1. pojo

因为页面显示的名字是下划线方式,和数据库表列名一样,根据页面的样式,编写pojo

package cn.itcast.crm.pojo;

public class BaseDict{
    private String dict_id;
    private String dict_type_code;
    private String dict_type_name;
    private String dict_item_name;
    private String dict_item_code;
    private Integer dict_sort;
    private String dict_enable;
    private String dict_memo;
    public String getDict_id() {
        return dict_id;
    }
    public void setDict_id(String dict_id) {
        this.dict_id = dict_id;
    }
    public String getDict_type_code() {
        return dict_type_code;
    }
    public void setDict_type_code(String dict_type_code) {
        this.dict_type_code = dict_type_code;
    }
    public String getDict_type_name() {
        return dict_type_name;
    }
    public void setDict_type_name(String dict_type_name) {
        this.dict_type_name = dict_type_name;
    }
    public String getDict_item_name() {
        return dict_item_name;
    }
    public void setDict_item_name(String dict_item_name) {
        this.dict_item_name = dict_item_name;
    }
    public String getDict_item_code() {
        return dict_item_code;
    }
    public void setDict_item_code(String dict_item_code) {
        this.dict_item_code = dict_item_code;
    }
    public Integer getDict_sort() {
        return dict_sort;
    }
    public void setDict_sort(Integer dict_sort) {
        this.dict_sort = dict_sort;
    }
    public String getDict_enable() {
        return dict_enable;
    }
    public void setDict_enable(String dict_enable) {
        this.dict_enable = dict_enable;
    }
    public String getDict_memo() {
        return dict_memo;
    }
    public void setDict_memo(String dict_memo) {
        this.dict_memo = dict_memo;
    }
    
}

6.2.2. mapper

BaseDictDao.java

package cn.itcast.crm.mapper;

import java.util.List;

import cn.itcast.crm.pojo.BaseDict;

public interface BaseDictDao {
    public List<BaseDict> selectBaseDictListByCode(String code);
}

BaseDictDao.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">
<mapper namespace="cn.itcast.crm.mapper.BaseDictDao">
<!-- 查询 -->
<select >
select * from base_dict where dict_type_code=#{value}
</select>
</mapper>

6.3. 实现Service开发

6.3.1. 接口类

package cn.itcast.crm.service;

import java.util.List;

import cn.itcast.crm.pojo.BaseDict;

public interface BaseDictService {
    public List<BaseDict> selectBaseDictListByCode(String code);
}

6.3.2. 实现类

package cn.itcast.crm.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.itcast.crm.mapper.BaseDictDao;
import cn.itcast.crm.pojo.BaseDict;

@Service
public class BaseDictServiceImpl implements BaseDictService {

    @Autowired
    private BaseDictDao dao;
    @Override
    public List<BaseDict> selectBaseDictListByCode(String code) {
        return dao.selectBaseDictListByCode(code);
    }

}

6.4. 实现Controller开发

CustomerController.java

package cn.itcast.crm.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import cn.itcast.crm.pojo.BaseDict;
import cn.itcast.crm.service.BaseDictService;

@Controller
@RequestMapping("customer")
public class CustomerController {
    
    @Autowired
    private BaseDictService service;
    
    @RequestMapping("list")
    public String list(Model model){
        List<BaseDict> fromType = service.selectBaseDictListByCode("002");
        List<BaseDict> industryType = service.selectBaseDictListByCode("001");
        List<BaseDict> levelType = service.selectBaseDictListByCode("006");
        model.addAttribute("fromType",fromType);
        model.addAttribute("industryType",industryType);
        model.addAttribute("levelType",levelType);
        return "customer";
    }
}

6.5. 效果

SSM综合练习

7. 客户列表展示

7.1. 需求

展示客户列表,并且可以根据查询条件过滤查询结果,并且实现分页。

SSM综合练习

7.2. pojo

package cn.itcast.crm.pojo;

import java.util.Date;

public class Customer {
    private Long cust_id;
    private String cust_name;
    private Long cust_user_id;
    private Long cust_create_id;
    private String cust_source;
    private String cust_industry;
    private String cust_level;
    private String cust_linkman;
    private String cust_phone;
    private String cust_mobile;
    private String cust_zipcode;
    private String cust_address;
    private Date cust_createtime;
    public Long getCust_id() {
        return cust_id;
    }
    public void setCust_id(Long cust_id) {
        this.cust_id = cust_id;
    }
    public String getCust_name() {
        return cust_name;
    }
    public void setCust_name(String cust_name) {
        this.cust_name = cust_name;
    }
    public Long getCust_user_id() {
        return cust_user_id;
    }
    public void setCust_user_id(Long cust_user_id) {
        this.cust_user_id = cust_user_id;
    }
    public Long getCust_create_id() {
        return cust_create_id;
    }
    public void setCust_create_id(Long cust_create_id) {
        this.cust_create_id = cust_create_id;
    }
    public String getCust_source() {
        return cust_source;
    }
    public void setCust_source(String cust_source) {
        this.cust_source = cust_source;
    }
    public String getCust_industry() {
        return cust_industry;
    }
    public void setCust_industry(String cust_industry) {
        this.cust_industry = cust_industry;
    }
    public String getCust_level() {
        return cust_level;
    }
    public void setCust_level(String cust_level) {
        this.cust_level = cust_level;
    }
    public String getCust_linkman() {
        return cust_linkman;
    }
    public void setCust_linkman(String cust_linkman) {
        this.cust_linkman = cust_linkman;
    }
    public String getCust_phone() {
        return cust_phone;
    }
    public void setCust_phone(String cust_phone) {
        this.cust_phone = cust_phone;
    }
    public String getCust_mobile() {
        return cust_mobile;
    }
    public void setCust_mobile(String cust_mobile) {
        this.cust_mobile = cust_mobile;
    }
    public String getCust_zipcode() {
        return cust_zipcode;
    }
    public void setCust_zipcode(String cust_zipcode) {
        this.cust_zipcode = cust_zipcode;
    }
    public String getCust_address() {
        return cust_address;
    }
    public void setCust_address(String cust_address) {
        this.cust_address = cust_address;
    }
    public Date getCust_createtime() {
        return cust_createtime;
    }
    public void setCust_createtime(Date cust_createtime) {
        this.cust_createtime = cust_createtime;
    }
}

7.3. Dao开发

分析:

  1. 前台发起请求,需要接收请求过来的查询条件数据,可以使用pojo接收数据。需要依此编写查询逻辑。
  2. 前台需要分页显示,根据准备好的分页实现,应该返回分页类Page,而创建Page分页类需要数据总条数,所以也需要查询数据总条数的逻辑。

 

根据分析,DAO需要编写两个方法:

  1. 需要根据条件分页查询客户信息
  2. 需要根据条件查询数据总条数

7.3.1. pojo

package cn.itcast.crm.pojo;

public class QueryVo {
    private String custName;
    private String custSource;
    private String custIndustry;
    private String custLevel;
    // 当前页码数
    private Integer page = 1;
    // 数据库从哪一条数据开始查
    private Integer start=0;
    // 每页显示数据条数
    private Integer rows = 5;
    public String getCustName() {
        return custName;
    }
    public void setCustName(String custName) {
        this.custName = custName;
    }
    public String getCustSource() {
        return custSource;
    }
    public void setCustSource(String custSource) {
        this.custSource = custSource;
    }
    public String getCustIndustry() {
        return custIndustry;
    }
    public void setCustIndustry(String custIndustry) {
        this.custIndustry = custIndustry;
    }
    public String getCustLevel() {
        return custLevel;
    }
    public void setCustLevel(String custLevel) {
        this.custLevel = custLevel;
    }
    public Integer getPage() {
        return page;
    }
    public void setPage(Integer page) {
        this.page = page;
    }
    public Integer getStart() {
        return start;
    }
    public void setStart(Integer start) {
        this.start = start;
    }
    public Integer getRows() {
        return rows;
    }
    public void setRows(Integer rows) {
        this.rows = rows;
    }
    
}

CustomerDao.java

package cn.itcast.crm.mapper;

import java.util.List;

import cn.itcast.crm.pojo.Customer;
import cn.itcast.crm.pojo.QueryVo;

public interface CustomerDao {
    
    //根据queryVo分页查询数据
    public List<Customer> queryCustomer(QueryVo vo);
    //查询总条数
    public Integer queryCount(QueryVo vo);
}

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">
<mapper namespace="cn.itcast.crm.mapper.CustomerDao">
    <select id="queryCustomer" parameterType="cn.itcast.crm.pojo.QueryVo" resultType="cn.itcast.crm.pojo.Customer">
        SELECT c.cust_id,c.cust_name,
        b.dict_item_name cust_source,
        bb.dict_item_name cust_industry,
        bbb.dict_item_name cust_level,
        c.cust_phone,c.cust_mobile 
        FROM customer c 
        LEFT JOIN base_dict b ON c.cust_source=b.dict_id
        LEFT JOIN base_dict bb ON c.cust_industry=bb.dict_id
        LEFT JOIN base_dict bbb ON c.cust_level=bbb.dict_id
        <where>
            <if test="custName!=null and custName!=''">
                c.cust_name like "%"#{custName}"%"
            </if>
            <if test="custSource!=null and custSource!=''">
                and cust_source = #{custSource}
            </if>
            <if test="custIndustry!=null and custIndustry!=''">
                and cust_industry = #{custIndustry}
            </if>
            <if test="custLevel!=null and custLevel!=''">
                and cust_level = #{custLevel}
            </if>
        </where>
        <if test="start != null">
            LIMIT #{start}, #{rows}
        </if>
    </select>

    <select id="queryCount" parameterType="cn.itcast.crm.pojo.QueryVo" resultType="int">
        select count(1) from customer 
        <where>
            <if test="custName!=null and custName!=''">
                cust_name like "%"#{custName}"%"
            </if>
            <if test="custSource!=null and custSource!=''">
                and cust_source = #{custSource}
            </if>
            <if test="custIndustry!=null and custIndustry!=''">
                and cust_industry = #{custIndustry}
            </if>
            <if test="custLevel!=null and custLevel!=''">
                and cust_level = #{custLevel}
            </if>
        </where>
    </select>
</mapper>

7.4. Service开发

7.4.1. 接口类

package cn.itcast.crm.service;

import cn.itcast.common.utils.Page;
import cn.itcast.crm.pojo.Customer;
import cn.itcast.crm.pojo.QueryVo;

public interface CustomerService {
    public Page<Customer> queryCustomer(QueryVo vo);
}

7.4.2. 实现类

package cn.itcast.crm.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.itcast.common.utils.Page;
import cn.itcast.crm.mapper.CustomerDao;
import cn.itcast.crm.pojo.Customer;
import cn.itcast.crm.pojo.QueryVo;
@Service
public class CustomerServiceImpl implements CustomerService {

    @Autowired
    private CustomerDao dao;
    @Override
    public Page<Customer> queryCustomer(QueryVo vo) {
        vo.setStart((vo.getPage()-1)*vo.getRows());
        
        List<Customer> rows = dao.queryCustomer(vo);
        
        int total=dao.queryCount(vo);
        Page<Customer> page=new Page<>();
        page.setTotal(total);
        page.setSize(vo.getRows());
        page.setPage(vo.getPage());
        page.setRows(rows);
        return page;
    }
    
}

7.5. 实现Controller

package cn.itcast.crm.controller;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;



import cn.itcast.common.utils.Page;
import cn.itcast.crm.pojo.BaseDict;
import cn.itcast.crm.pojo.Customer;
import cn.itcast.crm.pojo.QueryVo;
import cn.itcast.crm.service.BaseDictService;
import cn.itcast.crm.service.CustomerService;

@Controller
@RequestMapping("customer")
public class CustomerController {
    

    
    @Autowired
    private BaseDictService service;
    @Autowired
    private CustomerService cs;
    
    @RequestMapping("list")
    public String list(Model model,QueryVo vo){

        List<BaseDict> fromType = service.selectBaseDictListByCode("002");
        List<BaseDict> industryType = service.selectBaseDictListByCode("001");
        List<BaseDict> levelType = service.selectBaseDictListByCode("006");
        model.addAttribute("fromType",fromType);
        model.addAttribute("industryType",industryType);
        model.addAttribute("levelType",levelType);
        Page<Customer> page = cs.queryCustomer(vo);
        model.addAttribute("page",page);
        return "customer";
    }
}

7.6. 效果

SSM综合练习

8. 修改客户信息

8.1. 需求

页面效果如下图:

SSM综合练习

1、客户列表中点击“修改”按钮弹出客户信息修改窗,并初始化客户信息

2、点击“保存修改”按钮将修改后的结果保存到数据库中

8.2. 实现编辑数据回显

复制请求路径中的edit.action,在customer.jsp页面中搜索,找到请求逻辑

找到的代码如下图:

SSM综合练习

发现这里是一个Ajax请求,根据这个请求我们可以开发后台逻辑,提供给前端页面进行调用

 

8.3. 回显功能实现

8.3.1. Mapper接口

SSM综合练习

8.3.2. Mapper.xml

 SSM综合练习

8.3.3. service接口

SSM综合练习

8.3.4. service实现类

SSM综合练习

8.3.5. controller

 SSM综合练习

8.4. 实现编辑客户数据

8.4.1. Mapper接口

SSM综合练习

8.4.2. Mapper.xml

 SSM综合练习

 

8.4.3. service接口

 public void updateCustomer(Customer c);

8.4.4. service实现类

@Override
    public void updateCustomer(Customer c) {
        dao.updateCustomer(c);    
    }

 

8.4.5. controller

CustomerController编写方法

需要正确的响应,要告诉前端更新成功。返回值有没有都可以。

这里需要加@ResponseBody注解,使其不走视图解析器。

 

    @RequestMapping("update")
    @ResponseBody
    public String updateCustomerById(Customer customer) {
        cs.updateCustomer(customer);
        return "OK";
    }

 

9. 删除客户

9.1. 需求分析

点击客户列表中的删除按钮,提示“警告信息”,如下图

SSM综合练习

9.2. 功能开发

9.2.1. Mapper接口

//删除数据
    public void deleteCustomer(Long id);

9.2.2. Mapper.xml

   <delete id="deleteCustomer" parameterType="Long"> 
      delete from customer where cust_id=#{value}
    </delete>

9.2.3. service接口

   public void deleteCustomer(Long id);

9.2.4. service实现类

    @Override
    public void deleteCustomer(Long id) {
        dao.deleteCustomer(id);
        
    }

9.2.5. controller

    @RequestMapping("delete")
    @ResponseBody
    public String deleteCustomer(Long id) {
        cs.deleteCustomer(id);
        return "OK";
    }

总结

1.遇到问题:Invalid bound statement (not found): cn.itcast.crm.mapper.CustomerDao.queryCustomer

解决:xml配置文件和mapper接口名字不一样

2.遇到问题:Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986

解决:tomcat使用比较低的版本

相关文章: