# SSMproject 流程
# 项目需求分析
非常重要!!!
# 系统架构设计
3 层架构设计
Web 表现层:
该层主要包括 Spring MVC 中的 Controller 类和 JSP 页面。
Controller 类主要负责拦截用户请求,并调用业务逻辑层中相应组件的业务逻辑方法来处理用户请求,然后将相应的结果返回给 JSP 页面。
业务逻辑层(Service 层):
该层由若干 Service 接口和实现类组成。
在本系统中,业务逻辑层的接口统一使用 Service 结尾,其实现类名称统一在接口名后加 Impl。该层主要用于实现系统的业务逻辑。
数据访问层(DAO 层):
由若干 DAO 接口和 MyBatis 映射文件组成。
接口的名称统一以 Dao 结尾,且 MyBatis 的映射文件名称要与接口的名称相同。
持久对象层(也称持久层或持久化层):该层由若干持久化类(实体类)组成。
# 系统环境所需 jar 包
要由于本系统使用的是 SSM 框架开发,因此需要准备这三大框架的 JAR 包,需要准备的 JAR 共计 35 个。
Spring 框架所需的 JAR 包(10 个)
aopalliance-1.0.jar
aspectjweaver-1.8.10.jar
spring-aop-4.3.6.RELEASE.jar
spring-aspects-4.3.6.RELEASE.jar
spring-beans-4.3.6.RELEASE.jar
spring-context-4.3.6.RELEASE.jar
spring-core-4.3.6.RELEASE.jar
spring-expression-4.3.6.RELEASE.jar
spring-jdbc-4.3.6.RELEASE.jar
spring-tx-4.3.6.RELEASE.jar
Spring MVC 框架所需要的 JAR 包(2 个)
spring-web-4.3.6.RELEASE.jar
spring-webmvc-4.3.6.RELEASE.jar
MyBatis 框架所需的 JAR 包(13 个)
ant-1.9.6.jar
ant-launcher-1.9.6.jar
asm-5.1.jar
cglib-3.2.4.jar
commons-logging-1.2.jar
javassist-3.21.0-GA.jar
log4j-1.2.17.jar
log4j-api-2.3.jar
log4j-core-2.3.jar
mybatis-3.4.2.jar
ognl-3.1.12.jar
slf4j-api-1.7.22.jar
slf4j-log4j12-1.7.22.jar
MyBatis 与 Spring 整合的中间 JAR(1 个)
mybatis-spring-1.3.1.jar
数据库驱动 JAR(MySQL,1 个)
mysql-connector-java-5.1.40-bin.jar
数据源所需 JAR(DBCP,2 个)
commons-dbcp2-2.1.1.jar
commons-pool2-2.4.2.jar
JSTL 标签库 JAR(2 个)
taglibs-standard-impl-1.2.5.jar
taglibs-standard-spec-1.2.5.jar
Jackson 框架所需 JAR(3 个)
jackson-annotations-2.8.6.jar
jackson-core-2.8.6.jar
jackson-databind-2.8.6.jar
Java 工具类 JAR(1 个)
commons-lang3-3.4.jar
# 设计数据表结构
全英文一般用下划线 "_" 分隔,例如:
# 配置目录
共 6 个
Spring 配置文件:applicationContext.xml
数据库常量配置文件:db.properties
log4j 配置文件:log4j.properties
MyBatis 配置文件:mybatis-config.xml
资源配置文件:resource.properties
Spring MVC 配置文件 springmvc-config.xml
# 项目开始
- 用户类 User
# 创建持久化类 User.java
用户持久化类
根据数据库表创建
public class User implements Serializable{ | |
private static final long serialVersionUID = 1L; | |
private Integer user_id; // 用户 id | |
private String user_code; // 用户账号 | |
private String user_name; // 用户名称 | |
private String user_password; // 用户密码 | |
private Integer user_state; // 用户状态 | |
} |
# 创建 DAO 层接口 UserDao.java
用户 DAO 层接口 负责处理数据表
例如:通过账号和密码查询用户
public interface UserDao { | |
/** | |
* 通过账号和密码查询用户 | |
*/ | |
public User findUser(@Param("usercode") String usercode, @Param("password") String password); | |
} |
# 创建映射文件 UserDao.xml
实现 UserDao.java 中编写的方法
例如:实现查询用户
<mapper namespace="com.itheima.core.dao.UserDao" > | |
<!-- 查询用户 --> | |
<select id="findUser" parameterType="String" resultType="user"> | |
select * from sys_user | |
where user_code = #{usercode} | |
and user_password =#{password} | |
and user_state = '1' | |
</select> | |
</mapper> |
# 创建 Service 层接口 UserService.java
用户 Service 层接口,提供功能服务
例如:业务功能实现
public interface UserService { | |
// 业务功能方法:通过账号和密码查询用户,核对用户的身份信息 | |
public User findUser(String usercode,String password); | |
} |
# 创建 Service 层类 UserServiceImpl.java
用户 Service 接口实现类
例如:UserDao 注入,查询用户
@Service("userService") | |
@Transactional | |
public class UserServiceImpl implements UserService { | |
// 注入 UserDao | |
@Autowired | |
private UserDao userDao; | |
// 通过账号和密码查询用户 | |
@Override | |
public User findUser(String usercode, String password) { | |
User user = this.userDao.findUser(usercode, password); | |
return user; | |
} | |
} |
# 创建用户控制器类 UserController.java (核心代码)
接收客户端表单传过来的数据
例如:依赖注入,调用查询方法,并返回一个界面
@Controller | |
public class UserController { | |
// 依赖注入 | |
@Autowired | |
private UserService userService; | |
/** | |
* 用户登录 | |
*/ | |
@RequestMapping(value = "/login.action", method = RequestMethod.POST) | |
public String login(String usercode,String password, Model model, HttpSession session) { | |
// 通过账号和密码查询用户 | |
User user = userService.findUser(usercode, password); | |
if(user != null){ | |
// 将用户对象添加到 Session | |
session.setAttribute("USER_SESSION", user); | |
// 跳转到主页面 | |
// return "customer"; | |
return "redirect:customer/list.action"; | |
} | |
model.addAttribute("msg", "账号或密码错误,请重新输入!"); | |
// 返回到登录页面 | |
return "login"; | |
} | |
/** | |
* 模拟其他类中跳转到客户管理页面的方法 | |
*/ | |
@RequestMapping(value = "/toCustomer.action") | |
public String toCustomer() { | |
return "customer"; | |
} | |
/** | |
* 退出登录 | |
*/ | |
@RequestMapping(value = "/logout.action") | |
public String logout(HttpSession session) { | |
// 清除 Session | |
session.invalidate(); | |
// 重定向到登录页面的跳转方法 | |
return "redirect:login.action"; | |
} | |
/** | |
* 向用户登陆页面跳转 | |
*/ | |
@RequestMapping(value = "/login.action", method = RequestMethod.GET) | |
public String toLogin() { | |
return "login"; | |
} | |
} |
或者使用其他退出登录的方法:
@RequestMapping(value = "/logout.action") | |
public String logout(HttpSession session , Model model) { | |
// 清除 Session | |
session.invalidate(); | |
model.addAttribute("msg", "您可以重新登录系统!"); | |
// 重定向到登录页面的跳转方法 | |
return "login"; | |
} |
# 导入 web 配置文件
文档配置了 spring 的监听器、编码过滤器和 springmvc 的前端控制器等信息
<?xml version="1.0" encoding="UTF-8"?> | |
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xmlns="http://xmlns.jcp.org/xml/ns/javaee" | |
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee | |
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" | |
id="WebApp_ID" version="3.1"> | |
<!-- 配置加载 Spring 文件的监听器 --> | |
<context-param> | |
<param-name>contextConfigLocation</param-name> | |
<param-value>classpath:applicationContext.xml</param-value> | |
</context-param> | |
<listener> | |
<listener-class> | |
org.springframework.web.context.ContextLoaderListener | |
</listener-class> | |
</listener> | |
<!-- 编码过滤器 --> | |
<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>*.action</url-pattern> | |
</filter-mapping> | |
<!-- 配置 Spring MVC 前端核心控制器 --> | |
<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-config.xml</param-value> | |
</init-param> | |
<!-- 配置服务器启动后立即加载 Spring MVC 配置文件 --> | |
<load-on-startup>1</load-on-startup> | |
</servlet> | |
<servlet-mapping> | |
<servlet-name>crm</servlet-name> | |
<url-pattern>*.action</url-pattern> | |
</servlet-mapping> | |
<!-- 系统默认页面 --> | |
<welcome-file-list> | |
<welcome-file>index.jsp</welcome-file> | |
</welcome-file-list> | |
</web-app> |
# 导入 JSP 页面资源:
boot-crm\WebContent\index.jsp 系统默认首页
boot-crm\WebContent\WEB-INF\jsp\login.jsp 登录页面
boot-crm\WebContent\WEB-INF\jsp\customer.jsp 客户信息管理主页面
boot-crm\WebContent\WEB-INF\tld\ commons.tld 分页标签文件
# 系统登录页面
默认首页 index.jsp 转发到登录界面 login.jsp
boot-crm\WebContent\index.jsp 系统默认首页
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!-- 转发到登录页面 -->
<jsp:forward page="/WEB-INF/jsp/login.jsp"/>
boot-crm\WebContent\WEB-INF\jsp\login.jsp 系统登录界面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
<head>
<title>登录页面</title>
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
<link href="${pageContext.request.contextPath}/css/style.css" type=text/css rel=stylesheet>
<link href="${pageContext.request.contextPath}/css/boot-crm.css" type=text/css rel=stylesheet>
<script src="${pageContext.request.contextPath}/js/jquery-1.11.3.min.js">
</script>
<meta content="MSHTML 6.00.2600.0" name=GENERATOR>
<script>
// 判断是登录账号和密码是否为空
function check(){
var usercode = $("#usercode").val();
var password = $("#password").val();
if(usercode=="" || password==""){
$("#message").text("账号或密码不能为空!");
return false;
}
return true;
}
</script>
</head>
<body leftMargin=0 topMargin=0 marginwidth="0" marginheight="0"
background="${pageContext.request.contextPath}/images/rightbg.jpg">
<div ALIGN="center">
<table border="0" width="1140px" cellspacing="0" cellpadding="0" id="table1">
<tr>
<td height="93"></td>
<td></td>
</tr>
<tr>
<td background="${pageContext.request.contextPath}/images/rights.jpg" width="740" height="412">
</td>
<td class="login_msg" width="400" align="center">
<!-- margin:0px auto; 控制当前标签居中 -->
<fieldset style="width: auto; margin: 0px auto;">
<legend>
<font style="font-size:15px" face="宋体">
欢迎使用BOOT客户管理系统
</font>
</legend>
<font color="red">
<%-- 提示信息--%>
<span id="message">${msg}</span>
</font>
<%-- 提交后的位置:/WEB-INF/jsp/customer.jsp--%>
<form action="${pageContext.request.contextPath }/login.action" method="post" onsubmit="return check()">
<br /><br />
账 号:<input id="usercode" type="text" name="usercode" />
<br /><br />
密 码:<input id="password" type="password" name="password" />
<br /><br />
<center><input type="submit" value="登录" /></center>
</form>
</fieldset>
</td>
</tr>
</table>
</div>
</body>
</html>
# 用户信息管理页面
客户信息管理系统主界面 customer.jsp
boot-crm\WebContent\WEB-INF\jsp\customer.jsp 客户管理主界面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="itheima" uri="http://itheima.com/common/"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName()
+ ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>客户管理-BootCRM</title>
<!-- 引入css样式文件 -->
<!-- Bootstrap Core CSS -->
<link href="<%=basePath%>css/bootstrap.min.css" rel="stylesheet" />
<!-- MetisMenu CSS -->
<link href="<%=basePath%>css/metisMenu.min.css" rel="stylesheet" />
<!-- DataTables CSS -->
<link href="<%=basePath%>css/dataTables.bootstrap.css" rel="stylesheet" />
<!-- Custom CSS -->
<link href="<%=basePath%>css/sb-admin-2.css" rel="stylesheet" />
<!-- Custom Fonts -->
<link href="<%=basePath%>css/font-awesome.min.css" rel="stylesheet" type="text/css" />
<link href="<%=basePath%>css/boot-crm.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="wrapper">
<!-- 导航栏部分 -->
<nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
<div class="navbar-header">
<a class="navbar-brand" href="<%=basePath%>customer/list.action">BOOT客户管理系统 v2.0</a>
</div>
<!-- 导航栏右侧图标部分 -->
<ul class="nav navbar-top-links navbar-right">
<!-- 邮件通知 start -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-envelope fa-fw"></i>
<i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu dropdown-messages">
<li>
<a href="#">
<div>
<strong>张经理</strong> <span class="pull-right text-muted">
<em>昨天</em>
</span>
</div>
<div>今天晚上开会,讨论一下下个月工作的事...</div>
</a>
</li>
<li class="divider"></li>
<li>
<a class="text-center" href="#">
<strong>查看全部消息</strong>
<i class="fa fa-angle-right"></i>
</a>
</li>
</ul>
</li>
<!-- 邮件通知 end -->
<!-- 任务通知 start -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-tasks fa-fw"></i>
<i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu dropdown-tasks">
<li>
<a href="#">
<div>
<p>
<strong>任务 1</strong>
<span class="pull-right text-muted">完成40%</span>
</p>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-success"
role="progressbar" aria-valuenow="40" aria-valuemin="0"
aria-valuemax="100" style="width: 40%">
<span class="sr-only">完成40%</span>
</div>
</div>
</div>
</a>
</li>
<li class="divider"></li>
<li>
<a href="#">
<div>
<p>
<strong>任务 2</strong>
<span class="pull-right text-muted">完成20%</span>
</p>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-info" role="progressbar"
aria-valuenow="20" aria-valuemin="0" aria-valuemax="100"
style="width: 20%">
<span class="sr-only">完成20%</span>
</div>
</div>
</div>
</a>
</li>
<li class="divider"></li>
<li>
<a class="text-center" href="#">
<strong>查看所有任务</strong>
<i class="fa fa-angle-right"></i>
</a>
</li>
</ul>
</li>
<!-- 任务通知 end -->
<!-- 消息通知 start -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-bell fa-fw"></i>
<i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu dropdown-alerts">
<li>
<a href="#">
<div>
<i class="fa fa-comment fa-fw"></i> 新回复
<span class="pull-right text-muted small">4分钟之前</span>
</div>
</a>
</li>
<li class="divider"></li>
<li>
<a href="#">
<div>
<i class="fa fa-envelope fa-fw"></i> 新消息
<span class="pull-right text-muted small">4分钟之前</span>
</div>
</a>
</li>
<li class="divider"></li>
<li>
<a href="#">
<div>
<i class="fa fa-tasks fa-fw"></i> 新任务
<span class="pull-right text-muted small">4分钟之前</span>
</div>
</a>
</li>
<li class="divider"></li>
<li>
<a href="#">
<div>
<i class="fa fa-upload fa-fw"></i> 服务器重启
<span class="pull-right text-muted small">4分钟之前</span>
</div>
</a>
</li>
<li class="divider"></li>
<li>
<a class="text-center" href="#">
<strong>查看所有提醒</strong>
<i class="fa fa-angle-right"></i>
</a>
</li>
</ul>
</li>
<!-- 消息通知 end -->
<!-- 用户信息和系统设置 start -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-user fa-fw"></i>
<i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#"><i class="fa fa-user fa-fw"></i>
用户:${USER_SESSION.user_name}
</a>
</li>
<li><a href="#"><i class="fa fa-gear fa-fw"></i> 系统设置</a></li>
<li class="divider"></li>
<li>
<a href="${pageContext.request.contextPath }/logout.action">
<i class="fa fa-sign-out fa-fw"></i>退出登录
</a>
</li>
</ul>
</li>
<!-- 用户信息和系统设置结束 -->
</ul>
<!-- 左侧显示列表部分 start-->
<div class="navbar-default sidebar" role="navigation">
<div class="sidebar-nav navbar-collapse">
<ul class="nav" id="side-menu">
<li class="sidebar-search">
<div class="input-group custom-search-form">
<input type="text" class="form-control" placeholder="查询内容...">
<span class="input-group-btn">
<button class="btn btn-default" type="button">
<i class="fa fa-search" style="padding: 3px 0 3px 0;"></i>
</button>
</span>
</div>
</li>
<li>
<a href="${pageContext.request.contextPath }/customer/list.action" class="active">
<i class="fa fa-edit fa-fw"></i> 客户管理
</a>
</li>
<li>
<a href="#">
<i class="fa fa-dashboard fa-fw" ></i> 客户拜访
</a>
</li>
</ul>
</div>
</div>
<!-- 左侧显示列表部分 end-->
</nav>
<!-- 客户列表查询部分 start-->
<div id="page-wrapper">
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">客户管理</h1>
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
<div class="panel panel-default">
<div class="panel-body">
<form class="form-inline" method="get"
action="${pageContext.request.contextPath }/customer/list.action">
<div class="form-group">
<label for="customerName">客户名称</label>
<input type="text" class="form-control" id="customerName"
value="${custName }" name="custName" />
</div>
<div class="form-group">
<label for="customerFrom">客户来源</label>
<select class="form-control" id="customerFrom" 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>
<button type="submit" class="btn btn-primary">查询</button>
</form>
</div>
</div>
<a href="#" class="btn btn-primary" data-toggle="modal"
data-target="#newCustomerDialog" onclick="clearCustomer()">新建</a>
<div class="row">
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-heading">客户信息列表</div>
<!-- /.panel-heading -->
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>编号</th>
<th>客户名称</th>
<th>客户来源</th>
<th>客户所属行业</th>
<th>客户级别</th>
<th>固定电话</th>
<th>手机</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${page.rows}" var="row">
<tr>
<td>${row.cust_id}</td>
<td>${row.cust_name}</td>
<td>${row.cust_source}</td>
<td>${row.cust_industry}</td>
<td>${row.cust_level}</td>
<td>${row.cust_phone}</td>
<td>${row.cust_mobile}</td>
<td>
<a href="#" class="btn btn-primary btn-xs" data-toggle="modal" data-target="#customerEditDialog" onclick= "editCustomer(${row.cust_id})">修改</a>
<a href="#" class="btn btn-danger btn-xs" onclick="deleteCustomer(${row.cust_id})">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
<div class="col-md-12 text-right">
<itheima:page url="${pageContext.request.contextPath }/customer/list.action" />
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
<!-- /.col-lg-12 -->
</div>
</div>
<!-- 客户列表查询部分 end-->
</div>
<!-- 创建客户模态框 -->
<div class="modal fade" id="newCustomerDialog" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="myModalLabel">新建客户信息</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" id="new_customer_form">
<div class="form-group">
<label for="new_customerName" class="col-sm-2 control-label">
客户名称
</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="new_customerName" placeholder="客户名称" name="cust_name" />
</div>
</div>
<div class="form-group">
<label for="new_customerFrom" style="float:left;padding:7px 15px 0 27px;">客户来源</label>
<div class="col-sm-10">
<select class="form-control" id="new_customerFrom" name="cust_source">
<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>
<div class="form-group">
<label for="new_custIndustry" style="float:left;padding:7px 15px 0 27px;">所属行业</label>
<div class="col-sm-10">
<select class="form-control" id="new_custIndustry" name="cust_industry">
<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>
<div class="form-group">
<label for="new_custLevel" style="float:left;padding:7px 15px 0 27px;">客户级别</label>
<div class="col-sm-10">
<select class="form-control" id="new_custLevel" name="cust_level">
<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>
</div>
<div class="form-group">
<label for="new_linkMan" class="col-sm-2 control-label">联系人</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="new_linkMan" placeholder="联系人" name="cust_linkman" />
</div>
</div>
<div class="form-group">
<label for="new_phone" class="col-sm-2 control-label">固定电话</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="new_phone" placeholder="固定电话" name="cust_phone" />
</div>
</div>
<div class="form-group">
<label for="new_mobile" class="col-sm-2 control-label">移动电话</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="new_mobile" placeholder="移动电话" name="cust_mobile" />
</div>
</div>
<div class="form-group">
<label for="new_zipcode" class="col-sm-2 control-label">邮政编码</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="new_zipcode" placeholder="邮政编码" name="cust_zipcode" />
</div>
</div>
<div class="form-group">
<label for="new_address" class="col-sm-2 control-label">联系地址</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="new_address" placeholder="联系地址" name="cust_address" />
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" onclick="createCustomer()">创建客户</button>
</div>
</div>
</div>
</div>
<!-- 修改客户模态框 -->
<div class="modal fade" id="customerEditDialog" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="myModalLabel">修改客户信息</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" id="edit_customer_form">
<input type="hidden" id="edit_cust_id" name="cust_id"/>
<div class="form-group">
<label for="edit_customerName" class="col-sm-2 control-label">客户名称</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="edit_customerName" placeholder="客户名称" name="cust_name" />
</div>
</div>
<div class="form-group">
<label for="edit_customerFrom" style="float:left;padding:7px 15px 0 27px;">客户来源</label>
<div class="col-sm-10">
<select class="form-control" id="edit_customerFrom" name="cust_source">
<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>
<div class="form-group">
<label for="edit_custIndustry" style="float:left;padding:7px 15px 0 27px;">所属行业</label>
<div class="col-sm-10">
<select class="form-control" id="edit_custIndustry" name="cust_industry">
<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>
<div class="form-group">
<label for="edit_custLevel" style="float:left;padding:7px 15px 0 27px;">客户级别</label>
<div class="col-sm-10">
<select class="form-control" id="edit_custLevel" name="cust_level">
<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>
</div>
<div class="form-group">
<label for="edit_linkMan" class="col-sm-2 control-label">联系人</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="edit_linkMan" placeholder="联系人" name="cust_linkman" />
</div>
</div>
<div class="form-group">
<label for="edit_phone" class="col-sm-2 control-label">固定电话</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="edit_phone" placeholder="固定电话" name="cust_phone" />
</div>
</div>
<div class="form-group">
<label for="edit_mobile" class="col-sm-2 control-label">移动电话</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="edit_mobile" placeholder="移动电话" name="cust_mobile" />
</div>
</div>
<div class="form-group">
<label for="edit_zipcode" class="col-sm-2 control-label">邮政编码</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="edit_zipcode" placeholder="邮政编码" name="cust_zipcode" />
</div>
</div>
<div class="form-group">
<label for="edit_address" class="col-sm-2 control-label">联系地址</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="edit_address" placeholder="联系地址" name="cust_address" />
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" onclick="updateCustomer()">保存修改</button>
</div>
</div>
</div>
</div>
<!-- 引入js文件 -->
<!-- jQuery -->
<script src="<%=basePath%>js/jquery-1.11.3.min.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="<%=basePath%>js/bootstrap.min.js"></script>
<!-- Metis Menu Plugin JavaScript -->
<script src="<%=basePath%>js/metisMenu.min.js"></script>
<!-- DataTables JavaScript -->
<script src="<%=basePath%>js/jquery.dataTables.min.js"></script>
<script src="<%=basePath%>js/dataTables.bootstrap.min.js"></script>
<!-- Custom Theme JavaScript -->
<script src="<%=basePath%>js/sb-admin-2.js"></script>
<!-- 编写js代码 -->
<script type="text/javascript">
//清空新建客户窗口中的数据
function clearCustomer() {
$("#new_customerName").val("");
$("#new_customerFrom").val("")
$("#new_custIndustry").val("")
$("#new_custLevel").val("")
$("#new_linkMan").val("");
$("#new_phone").val("");
$("#new_mobile").val("");
$("#new_zipcode").val("");
$("#new_address").val("");
}
// 创建客户
function createCustomer() {
$.post("<%=basePath%>customer/create.action",
$("#new_customer_form").serialize(),function(data){
if(data =="OK"){
alert("客户创建成功!");
window.location.reload();
}else{
alert("客户创建失败!");
window.location.reload();
}
});
}
// 通过id获取修改的客户信息
function editCustomer(id) {
$.ajax({
type:"get",
url:"<%=basePath%>customer/getCustomerById.action",
data:{"id":id},
success:function(data) {
$("#edit_cust_id").val(data.cust_id);
$("#edit_customerName").val(data.cust_name);
$("#edit_customerFrom").val(data.cust_source)
$("#edit_custIndustry").val(data.cust_industry)
$("#edit_custLevel").val(data.cust_level)
$("#edit_linkMan").val(data.cust_linkman);
$("#edit_phone").val(data.cust_phone);
$("#edit_mobile").val(data.cust_mobile);
$("#edit_zipcode").val(data.cust_zipcode);
$("#edit_address").val(data.cust_address);
}
});
}
// 执行修改客户操作
function updateCustomer() {
$.post("<%=basePath%>customer/update.action",$("#edit_customer_form").serialize(),function(data){
if(data =="OK"){
alert("客户信息更新成功!");
window.location.reload();
}else{
alert("客户信息更新失败!");
window.location.reload();
}
});
}
// 删除客户
function deleteCustomer(id) {
if(confirm('确实要删除该客户吗?')) {
$.post("<%=basePath%>customer/delete.action",{"id":id},
function(data){
if(data =="OK"){
alert("客户删除成功!");
window.location.reload();
}else{
alert("删除客户失败!");
window.location.reload();
}
});
}
}
</script>
</body>
</html>
# 分页标记文件代码
分页标签文件 commons.tld
boot-crm\WebContent\WEB-INF\tld\ commons.tld 分页标签文件
<?xml version="1.0" encoding="UTF-8" ?> | |
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" | |
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> | |
<taglib> | |
<!-- 指定标签库的版本号 --> | |
<tlib-version>2.0</tlib-version> | |
<!-- 指定 JSP 的版本号 --> | |
<jsp-version>1.2</jsp-version> | |
<!-- 指定标签库的名称 --> | |
<short-name>common</short-name> | |
<!-- 指定标签库的 URI --> | |
<uri>http://itheima.com/common/</uri> | |
<!-- 指定标签库的显示名称 --> | |
<display-name>Common Tag</display-name> | |
<!-- 指定标签库的描述 --> | |
<description>Common Tag library</description> | |
<!-- 注册一个自定义标签 --> | |
<tag> | |
<!-- 指定注册的自定义标签名称 --> | |
<name>page</name> | |
<!-- 指定自定义标签的标签处理器类 --> | |
<tag-class>com.itheima.common.utils.NavigationTag</tag-class> | |
<!-- 指定标签体类型 --> | |
<body-content>JSP</body-content> | |
<!-- 描述 --> | |
<description>create navigation for paging</description> | |
<!-- 指定标签中的属性 --> | |
<attribute> | |
<!-- 指定属性名称 --> | |
<name>url</name> | |
<!-- 该属性为 true 时表示其指定是属性为必须属性 --> | |
<required>true</required> | |
<!-- 该属性用于指定能不能使用表达式来动态指定数据,为 true 时表示可以 --> | |
<rtexprvalue>true</rtexprvalue> | |
</attribute> | |
<attribute> | |
<name>bean</name> | |
<rtexprvalue>true</rtexprvalue> | |
</attribute> | |
<attribute> | |
<name>number</name> | |
<rtexprvalue>true</rtexprvalue> | |
</attribute> | |
</tag> | |
</taglib> |
# 导入图片文件
文件目录:/boot-crm/WebContent/images
# 导入 config 配置文件:
# spring 配置文件:applicationContext.xml
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> | |
<!DOCTYPE HTML> | |
<html> | |
<head> | |
<title>登录页面</title> | |
<meta http-equiv=Content-Type content="text/html; charset=utf-8"> | |
<link href="${pageContext.request.contextPath}/css/style.css" type=text/css rel=stylesheet> | |
<link href="${pageContext.request.contextPath}/css/boot-crm.css" type=text/css rel=stylesheet> | |
<script src="${pageContext.request.contextPath}/js/jquery-1.11.3.min.js"> | |
</script> | |
<meta content="MSHTML 6.00.2600.0" name=GENERATOR> | |
<script> | |
// 判断是登录账号和密码是否为空 | |
function check(){ | |
var usercode = $("#usercode").val(); | |
var password = $("#password").val(); | |
if(usercode=="" || password==""){ | |
$("#message").text("账号或密码不能为空!"); | |
return false; | |
} | |
return true; | |
} | |
</script> | |
</head> | |
<body leftMargin=0 topMargin=0 marginwidth="0" marginheight="0" | |
background="${pageContext.request.contextPath}/images/rightbg.jpg"> | |
<div ALIGN="center"> | |
<table border="0" width="1140px" cellspacing="0" cellpadding="0" id="table1"> | |
<tr> | |
<td height="93"></td> | |
<td></td> | |
</tr> | |
<tr> | |
<td background="${pageContext.request.contextPath}/images/rights.jpg" width="740" height="412"> | |
</td> | |
<td class="login_msg" width="400" align="center"> | |
<!-- margin:0px auto; 控制当前标签居中 --> | |
<fieldset style="width: auto; margin: 0px auto;"> | |
<legend> | |
<font style="font-size:15px" face="宋体"> | |
欢迎使用BOOT客户管理系统 | |
</font> | |
</legend> | |
<font color="red"> | |
<%-- 提示信息--%> | |
<span id="message">${msg}</span> | |
</font> | |
<%-- 提交后的位置:/WEB-INF/jsp/customer.jsp--%> | |
<form action="${pageContext.request.contextPath }/login.action" method="post" onsubmit="return check()"> | |
<br /><br /> | |
账 号:<input id="usercode" type="text" name="usercode" /> | |
<br /><br /> | |
密 码:<input id="password" type="password" name="password" /> | |
<br /><br /> | |
| |
<center><input type="submit" value="登录" /></center> | |
</form> | |
</fieldset> | |
</td> | |
</tr> | |
</table> | |
</div> | |
</body> | |
</html> |
# 数据库常量配置文件:db.properties
jdbc.driver=com.mysql.jdbc.Driver | |
jdbc.url=jdbc:mysql://localhost:3306/boot_crm | |
jdbc.username=root | |
jdbc.password=root | |
jdbc.maxTotal=30 | |
jdbc.maxIdle=10 | |
jdbc.initialSize=5 |
# log4j 配置文件:log4j.properties
# Global logging configuration | |
log4j.rootLogger=ERROR, stdout | |
# MyBatis logging configuration... | |
log4j.logger.com.itheima.core=DEBUG | |
# Console output... | |
log4j.appender.stdout=org.apache.log4j.ConsoleAppender | |
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout | |
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n |
# 资源配置文件:resource.properties
customer.from.type=002 | |
customer.industry.type=001 | |
customer.level.type=006 |
# MyBatis 配置文件: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> | |
<!-- 别名定义 --> | |
<typeAliases> | |
<package name="com.itheima.core.po" /> | |
</typeAliases> | |
</configuration> |
# Spring MVC 配置文件 springmvc-config.xml
<beans xmlns="http://www.springframework.org/schema/beans" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xmlns:mvc="http://www.springframework.org/schema/mvc" | |
xmlns:context="http://www.springframework.org/schema/context" | |
xmlns:aop="http://www.springframework.org/schema/aop" | |
xmlns:tx="http://www.springframework.org/schema/tx" | |
xsi:schemaLocation="http://www.springframework.org/schema/beans | |
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd | |
http://www.springframework.org/schema/mvc | |
http://www.springframework.org/schema/mvc/spring-mvc-4.3.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"> | |
<!-- 加载属性文件 --> | |
<context:property-placeholder location="classpath:resource.properties" /> | |
<!-- 配置扫描器 --> | |
<context:component-scan base-package="com.itheima.core.web.controller" /> | |
<!-- 注解驱动:配置处理器映射器和适配器 --> | |
<mvc:annotation-driven /> | |
<!-- 配置静态资源的访问映射,此配置中的文件,将不被前端控制器拦截 --> | |
<mvc:resources location="/js/" mapping="/js/**" /> | |
<mvc:resources location="/css/" mapping="/css/**" /> | |
<mvc:resources location="/fonts/" mapping="/fonts/**" /> | |
<mvc:resources location="/images/" mapping="/images/**" /> | |
<!-- 配置视图解释器 ViewResolver --> | |
<bean id="jspViewResolver" class= | |
"org.springframework.web.servlet.view.InternalResourceViewResolver"> | |
<property name="prefix" value="/WEB-INF/jsp/" /> | |
<property name="suffix" value=".jsp" /> | |
</bean> | |
<!-- 配置拦截器 --> | |
<mvc:interceptors> | |
<mvc:interceptor> | |
<mvc:mapping path="/**" /> | |
<bean class="com.itheima.core.interceptor.LoginInterceptor" /> | |
</mvc:interceptor> | |
</mvc:interceptors> | |
</beans> |
# 登录拦截器类:LoginInterceptor.java
提升系统的安全性,只有已登录用户的请求才能够通过,而对于未登录用户的请求,系统会将请求转发到登录页面,并提示用户登录。
package com.itheima.core.interceptor; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletResponse; | |
import javax.servlet.http.HttpSession; | |
import org.springframework.web.servlet.HandlerInterceptor; | |
import org.springframework.web.servlet.ModelAndView; | |
import com.itheima.core.po.User; | |
/** | |
* 登录拦截器 | |
*/ | |
public class LoginInterceptor implements HandlerInterceptor { | |
@Override | |
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) | |
throws Exception { | |
// 获取请求的 URL | |
String url = request.getRequestURI(); | |
// URL: 除了登录请求外,其他的 URL 都进行拦截控制 | |
if (url.indexOf("/login.action") >= 0) { | |
return true; | |
} | |
// 获取 Session | |
HttpSession session = request.getSession(); | |
User user = (User) session.getAttribute("USER_SESSION"); | |
// 判断 Session 中是否有用户数据,如果有,则返回 true, 继续向下执行 | |
if (user != null) { | |
return true; | |
} | |
// 不符合条件的给出提示信息,并转发到登录页面 | |
request.setAttribute("msg", "您还没有登录,请先登录!"); | |
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response); | |
return false; | |
} | |
@Override | |
public void postHandle(HttpServletRequest request, | |
HttpServletResponse response, Object handler, | |
ModelAndView modelAndView) throws Exception { | |
} | |
@Override | |
public void afterCompletion(HttpServletRequest request, | |
HttpServletResponse response, Object handler, Exception ex) | |
throws Exception { | |
} | |
} |
# 配置拦截器
spring-mvc-config.xml 文件中,配置拦截器信息
<!-- 配置拦截器 --> | |
<mvc:interceptors> | |
<mvc:interceptor> | |
<mvc:mapping path="/**" /> | |
<bean class="com.itheima.core.interceptor.LoginInterceptor" /> | |
</mvc:interceptor> | |
</mvc:interceptors> |
# 客户类:Customer
# 创建客户持久化类
boot-crm\src\com\itheima\core\po\Customer.java
package com.itheima.core.po; | |
import java.io.Serializable; | |
import java.util.Date; | |
/** | |
* 客户持久化类 | |
*/ | |
public class Customer implements Serializable { | |
private static final long serialVersionUID = 1L; | |
private Integer cust_id; // 客户编号 | |
private String cust_name; // 客户名称 | |
private Integer cust_user_id; // 负责人 id | |
private Integer cust_create_id; // 创建人 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; // 创建时间 | |
private Integer start; // 起始行 | |
private Integer rows; // 所取行数 | |
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 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; | |
} | |
public Integer getCust_id() { | |
return cust_id; | |
} | |
public void setCust_id(Integer 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 Integer getCust_user_id() { | |
return cust_user_id; | |
} | |
public void setCust_user_id(Integer cust_user_id) { | |
this.cust_user_id = cust_user_id; | |
} | |
public Integer getCust_create_id() { | |
return cust_create_id; | |
} | |
public void setCust_create_id(Integer 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 Date getCust_createtime() { | |
return cust_createtime; | |
} | |
public void setCust_createtime(Date cust_createtime) { | |
this.cust_createtime = cust_createtime; | |
} | |
} |
# 创建 DAO 层的客户数据处理类
boot-crm\src\com\itheima\core\dao\ CustomerDao.java
package com.itheima.core.dao; | |
import java.util.List; | |
import com.itheima.core.po.Customer; | |
/** | |
* Customer 接口 | |
*/ | |
public interface CustomerDao { | |
// 客户列表 | |
public List<Customer> selectCustomerList(Customer customer); | |
// 客户数 | |
public Integer selectCustomerListCount(Customer customer); | |
// 创建客户 | |
public int createCustomer(Customer customer); | |
// 通过 id 查询客户 | |
public Customer getCustomerById(Integer id); | |
// 更新客户信息 | |
public int updateCustomer(Customer customer); | |
// 删除客户 | |
int deleteCustomer (Integer id); | |
} |
# 创建客户数据处理类的映射文件
boot-crm\src\com\itheima\core\dao\ 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="com.itheima.core.dao.CustomerDao"> | |
<!--SQL 片段 --> | |
<sql id="selectCustomerListWhere"> | |
<where> | |
<if test="cust_name != null" > | |
cust_name like "%"#{cust_name}"%" | |
</if> | |
<if test="cust_source != null" > | |
and cust_source = #{cust_source} | |
</if> | |
<if test="cust_industry != null" > | |
and cust_industry = #{cust_industry} | |
</if> | |
<if test="cust_level != null" > | |
and cust_level = #{cust_level} | |
</if> | |
</where> | |
</sql> | |
<!-- 查询客户列表 --> | |
<select id="selectCustomerList" parameterType="customer" resultType="customer"> | |
SELECT | |
cust_id, | |
cust_name, | |
cust_user_id, | |
cust_create_id, | |
b.dict_item_name cust_source, | |
c.dict_item_name cust_industry, | |
d.dict_item_name cust_level, | |
cust_linkman, | |
cust_phone, | |
cust_mobile, | |
cust_createtime | |
FROM | |
customer a | |
LEFT JOIN ( | |
SELECT | |
dict_id, | |
dict_item_name | |
FROM | |
base_dict | |
WHERE | |
dict_type_code = '002' | |
) b ON a.cust_source = b.dict_id | |
LEFT JOIN ( | |
SELECT | |
dict_id, | |
dict_item_name | |
FROM | |
base_dict | |
WHERE | |
dict_type_code = '001' | |
) c ON a.cust_industry = c.dict_id | |
LEFT JOIN ( | |
SELECT | |
dict_id, | |
dict_item_name | |
FROM | |
base_dict | |
WHERE | |
dict_type_code = '006' | |
) d ON a.cust_level = d.dict_id | |
<include refid="selectCustomerListWhere"/> | |
<!-- 执行分页查询 --> | |
<if test="start !=null and rows != null"> | |
limit #{start},#{rows} | |
</if> | |
</select> | |
<!-- 查询客户总数 --> | |
<select id="selectCustomerListCount" parameterType="customer" | |
resultType="Integer"> | |
select count(*) from customer | |
<include refid="selectCustomerListWhere"/> | |
</select> | |
<!-- 添加客户 --> | |
<insert id="createCustomer" parameterType="customer"> | |
insert into customer( | |
cust_name, | |
cust_user_id, | |
cust_create_id, | |
cust_source, | |
cust_industry, | |
cust_level, | |
cust_linkman, | |
cust_phone, | |
cust_mobile, | |
cust_zipcode, | |
cust_address, | |
cust_createtime | |
) | |
values(#{cust_name}, | |
#{cust_user_id}, | |
#{cust_create_id}, | |
#{cust_source}, | |
#{cust_industry}, | |
#{cust_level}, | |
#{cust_linkman}, | |
#{cust_phone}, | |
#{cust_mobile}, | |
#{cust_zipcode}, | |
#{cust_address}, | |
#{cust_createtime} | |
) | |
</insert> | |
<!-- 根据 id 获取客户信息 --> | |
<select id="getCustomerById" parameterType="Integer" | |
resultType="customer"> | |
select * from customer where cust_id = #{id} | |
</select> | |
<!-- 更新客户 --> | |
<update id="updateCustomer" parameterType="customer"> | |
update customer | |
<set> | |
<if test="cust_name!=null"> | |
cust_name=#{cust_name}, | |
</if> | |
<if test="cust_user_id!=null"> | |
cust_user_id=#{cust_user_id}, | |
</if> | |
<if test="cust_create_id!=null"> | |
cust_create_id=#{cust_create_id}, | |
</if> | |
<if test="cust_source!=null"> | |
cust_source=#{cust_source}, | |
</if> | |
<if test="cust_industry!=null"> | |
cust_industry=#{cust_industry}, | |
</if> | |
<if test="cust_level!=null"> | |
cust_level=#{cust_level}, | |
</if> | |
<if test="cust_linkman!=null"> | |
cust_linkman=#{cust_linkman}, | |
</if> | |
<if test="cust_phone!=null"> | |
cust_phone=#{cust_phone}, | |
</if> | |
<if test="cust_mobile!=null"> | |
cust_mobile=#{cust_mobile}, | |
</if> | |
<if test="cust_zipcode!=null"> | |
cust_zipcode=#{cust_zipcode}, | |
</if> | |
<if test="cust_address!=null"> | |
cust_address=#{cust_address}, | |
</if> | |
<if test="cust_createtime!=null"> | |
cust_createtime=#{cust_createtime}, | |
</if> | |
</set> | |
where cust_id=#{cust_id} | |
</update> | |
<!-- 删除客户 --> | |
<delete id="deleteCustomer" parameterType="Integer"> | |
delete from customer where cust_id=#{id} | |
</delete> | |
</mapper> |
# 创建客户的 service 层接口
boot-crm\src\com\itheima\core\service\ CustomerService.java
package com.itheima.core.service; | |
import com.itheima.common.utils.Page; | |
import com.itheima.core.po.Customer; | |
public interface CustomerService { | |
// 查询客户列表 | |
public Page<Customer> findCustomerList(Integer page, Integer rows, | |
String custName,String custSource, | |
String custIndustry,String custLevel); | |
public int createCustomer(Customer customer); | |
// 通过 id 查询客户 | |
public Customer getCustomerById(Integer id); | |
// 更新客户 | |
public int updateCustomer(Customer customer); | |
// 删除客户 | |
public int deleteCustomer(Integer id); | |
} |
# 创建客户的 service 层的实现类
boot-crm\src\com\itheima\core\service\impl\ CustomerServiceImpl.java
package com.itheima.core.service.impl; | |
import java.util.List; | |
import org.apache.commons.lang3.StringUtils; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.stereotype.Service; | |
import org.springframework.transaction.annotation.Transactional; | |
import com.itheima.common.utils.Page; | |
import com.itheima.core.dao.CustomerDao; | |
import com.itheima.core.po.Customer; | |
import com.itheima.core.service.CustomerService; | |
/** | |
* 客户管理 | |
*/ | |
@Service("customerService") | |
@Transactional | |
public class CustomerServiceImpl implements CustomerService { | |
// 声明 DAO 属性并注入 | |
@Autowired | |
private CustomerDao customerDao; | |
// 客户列表 | |
public Page<Customer> findCustomerList(Integer page, Integer rows, | |
String custName, String custSource,String custIndustry, String custLevel) { | |
// 创建客户对象 | |
Customer customer = new Customer(); | |
// 判断客户名称 | |
if(StringUtils.isNotBlank(custName)){ | |
customer.setCust_name(custName); | |
} | |
// 判断客户信息来源 | |
if(StringUtils.isNotBlank(custSource)){ | |
customer.setCust_source(custSource); | |
} | |
// 判断客户所属行业 | |
if(StringUtils.isNotBlank(custIndustry)){ | |
customer.setCust_industry(custIndustry); | |
} | |
// 判断客户级别 | |
if(StringUtils.isNotBlank(custLevel)){ | |
customer.setCust_level(custLevel); | |
} | |
// 当前页 | |
customer.setStart((page-1) * rows) ; | |
// 每页数 | |
customer.setRows(rows); | |
// 查询客户列表 | |
List<Customer> customers = customerDao.selectCustomerList(customer); | |
// 查询客户列表总记录数 | |
Integer count = customerDao.selectCustomerListCount(customer); | |
// 创建 Page 返回对象 | |
Page<Customer> result = new Page<>(); | |
result.setPage(page); | |
result.setRows(customers); | |
result.setSize(rows); | |
result.setTotal(count); | |
return result; | |
} | |
/** | |
* 创建客户 | |
*/ | |
@Override | |
public int createCustomer(Customer customer) { | |
return customerDao.createCustomer(customer); | |
} | |
/** | |
* 通过 id 查询客户 | |
*/ | |
@Override | |
public Customer getCustomerById(Integer id) { | |
Customer customer = customerDao.getCustomerById(id); | |
return customer; | |
} | |
/** | |
* 更新客户 | |
*/ | |
@Override | |
public int updateCustomer(Customer customer) { | |
return customerDao.updateCustomer(customer); | |
} | |
/** | |
* 删除客户 | |
*/ | |
@Override | |
public int deleteCustomer(Integer id) { | |
return customerDao.deleteCustomer(id); | |
} | |
} |
# 创建客户控制器类
boot-crm\src\com\itheima\core\web\controller\ CustomerController.java
package com.itheima.core.web.controller; | |
import java.sql.Timestamp; | |
import java.util.Date; | |
import java.util.List; | |
import javax.servlet.http.HttpSession; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.beans.factory.annotation.Value; | |
import org.springframework.stereotype.Controller; | |
import org.springframework.ui.Model; | |
import org.springframework.web.bind.annotation.RequestMapping; | |
import org.springframework.web.bind.annotation.RequestParam; | |
import org.springframework.web.bind.annotation.ResponseBody; | |
import com.itheima.common.utils.Page; | |
import com.itheima.core.po.BaseDict; | |
import com.itheima.core.po.Customer; | |
import com.itheima.core.po.User; | |
import com.itheima.core.service.BaseDictService; | |
import com.itheima.core.service.CustomerService; | |
/** | |
* 客户管理控制器类 | |
*/ | |
@Controller | |
public class CustomerController { | |
// 依赖注入 | |
@Autowired | |
private CustomerService customerService; | |
@Autowired | |
private BaseDictService baseDictService; | |
// 客户来源 | |
@Value("${customer.from.type}") | |
private String FROM_TYPE; | |
// 客户所属行业 | |
@Value("${customer.industry.type}") | |
private String INDUSTRY_TYPE; | |
// 客户级别 | |
@Value("${customer.level.type}") | |
private String LEVEL_TYPE; | |
/** | |
* 客户列表 | |
*/ | |
@RequestMapping(value = "/customer/list.action") | |
public String list(@RequestParam(defaultValue="1")Integer page, | |
@RequestParam(defaultValue="10")Integer rows, | |
String custName, String custSource, String custIndustry, | |
String custLevel, Model model) { | |
// 条件查询所有客户 | |
Page<Customer> customers = customerService | |
.findCustomerList(page, rows, custName, | |
custSource, custIndustry,custLevel); | |
model.addAttribute("page", customers); | |
// 客户来源 | |
List<BaseDict> fromType = baseDictService.findBaseDictByTypeCode(FROM_TYPE); | |
// 客户所属行业 | |
List<BaseDict> industryType = baseDictService.findBaseDictByTypeCode(INDUSTRY_TYPE); | |
// 客户级别 | |
List<BaseDict> levelType = baseDictService.findBaseDictByTypeCode(LEVEL_TYPE); | |
// 添加参数 | |
model.addAttribute("fromType", fromType); | |
model.addAttribute("industryType", industryType); | |
model.addAttribute("levelType", levelType); | |
model.addAttribute("custName", custName); | |
model.addAttribute("custSource", custSource); | |
model.addAttribute("custIndustry", custIndustry); | |
model.addAttribute("custLevel", custLevel); | |
return "customer"; | |
} | |
/** | |
* 创建客户 | |
*/ | |
@RequestMapping("/customer/create.action") | |
@ResponseBody | |
public String customerCreate(Customer customer,HttpSession session) { | |
// 获取 Session 中的当前用户信息 | |
User user = (User) session.getAttribute("USER_SESSION"); | |
// 将当前用户 id 存储在客户对象中 | |
customer.setCust_create_id(user.getUser_id()); | |
// 创建 Date 对象 | |
Date date = new Date(); | |
// 得到一个 Timestamp 格式的时间,存入 mysql 中的时间格式 “yyyy/MM/dd HH:mm:ss” | |
Timestamp timeStamp = new Timestamp(date.getTime()); | |
customer.setCust_createtime(timeStamp); | |
// 执行 Service 层中的创建方法,返回的是受影响的行数 | |
int rows = customerService.createCustomer(customer); | |
if(rows > 0){ | |
return "OK"; | |
}else{ | |
return "FAIL"; | |
} | |
} | |
/** | |
* 通过 id 获取客户信息 | |
*/ | |
@RequestMapping("/customer/getCustomerById.action") | |
@ResponseBody | |
public Customer getCustomerById(Integer id) { | |
Customer customer = customerService.getCustomerById(id); | |
return customer; | |
} | |
/** | |
* 更新客户 | |
*/ | |
@RequestMapping("/customer/update.action") | |
@ResponseBody | |
public String customerUpdate(Customer customer) { | |
int rows = customerService.updateCustomer(customer); | |
if(rows > 0){ | |
return "OK"; | |
}else{ | |
return "FAIL"; | |
} | |
} | |
/** | |
* 删除客户 | |
*/ | |
@RequestMapping("/customer/delete.action") | |
@ResponseBody | |
public String customerDelete(Integer id) { | |
int rows = customerService.deleteCustomer(id); | |
if(rows > 0){ | |
return "OK"; | |
}else{ | |
return "FAIL"; | |
} | |
} | |
} |
# 查询客户信息
包括按条件查询、查询所有客户信息,以及分页查询
# 创建条件查询
# 总前端配置 customer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="itheima" uri="http://itheima.com/common/"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName()
+ ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>客户管理-BootCRM</title>
<!-- 引入css样式文件 -->
<!-- Bootstrap Core CSS -->
<link href="<%=basePath%>css/bootstrap.min.css" rel="stylesheet" />
<!-- MetisMenu CSS -->
<link href="<%=basePath%>css/metisMenu.min.css" rel="stylesheet" />
<!-- DataTables CSS -->
<link href="<%=basePath%>css/dataTables.bootstrap.css" rel="stylesheet" />
<!-- Custom CSS -->
<link href="<%=basePath%>css/sb-admin-2.css" rel="stylesheet" />
<!-- Custom Fonts -->
<link href="<%=basePath%>css/font-awesome.min.css" rel="stylesheet" type="text/css" />
<link href="<%=basePath%>css/boot-crm.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="wrapper">
<!-- 导航栏部分 -->
<nav class="navbar navbar-default navbar-static-top" role="navigation"
style="margin-bottom: 0">
<div class="navbar-header">
<a class="navbar-brand" href="<%=basePath%>customer/list.action">BOOT客户管理系统 v2.0</a>
</div>
<!-- 导航栏右侧图标部分 -->
<ul class="nav navbar-top-links navbar-right">
<!-- 邮件通知 start -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-envelope fa-fw"></i>
<i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu dropdown-messages">
<li>
<a href="#">
<div>
<strong>张经理</strong> <span class="pull-right text-muted">
<em>昨天</em>
</span>
</div>
<div>今天晚上开会,讨论一下下个月工作的事...</div>
</a>
</li>
<li class="divider"></li>
<li>
<a class="text-center" href="#">
<strong>查看全部消息</strong>
<i class="fa fa-angle-right"></i>
</a>
</li>
</ul>
</li>
<!-- 邮件通知 end -->
<!-- 任务通知 start -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-tasks fa-fw"></i>
<i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu dropdown-tasks">
<li>
<a href="#">
<div>
<p>
<strong>任务 1</strong>
<span class="pull-right text-muted">完成40%</span>
</p>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-success"
role="progressbar" aria-valuenow="40" aria-valuemin="0"
aria-valuemax="100" style="width: 40%">
<span class="sr-only">完成40%</span>
</div>
</div>
</div>
</a>
</li>
<li class="divider"></li>
<li>
<a href="#">
<div>
<p>
<strong>任务 2</strong>
<span class="pull-right text-muted">完成20%</span>
</p>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-info" role="progressbar"
aria-valuenow="20" aria-valuemin="0" aria-valuemax="100"
style="width: 20%">
<span class="sr-only">完成20%</span>
</div>
</div>
</div>
</a>
</li>
<li class="divider"></li>
<li>
<a class="text-center" href="#">
<strong>查看所有任务</strong>
<i class="fa fa-angle-right"></i>
</a>
</li>
</ul>
</li>
<!-- 任务通知 end -->
<!-- 消息通知 start -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-bell fa-fw"></i>
<i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu dropdown-alerts">
<li>
<a href="#">
<div>
<i class="fa fa-comment fa-fw"></i> 新回复
<span class="pull-right text-muted small">4分钟之前</span>
</div>
</a>
</li>
<li class="divider"></li>
<li>
<a href="#">
<div>
<i class="fa fa-envelope fa-fw"></i> 新消息
<span class="pull-right text-muted small">4分钟之前</span>
</div>
</a>
</li>
<li class="divider"></li>
<li>
<a href="#">
<div>
<i class="fa fa-tasks fa-fw"></i> 新任务
<span class="pull-right text-muted small">4分钟之前</span>
</div>
</a>
</li>
<li class="divider"></li>
<li>
<a href="#">
<div>
<i class="fa fa-upload fa-fw"></i> 服务器重启
<span class="pull-right text-muted small">4分钟之前</span>
</div>
</a>
</li>
<li class="divider"></li>
<li>
<a class="text-center" href="#">
<strong>查看所有提醒</strong>
<i class="fa fa-angle-right"></i>
</a>
</li>
</ul>
</li>
<!-- 消息通知 end -->
<!-- 用户信息和系统设置 start -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-user fa-fw"></i>
<i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#"><i class="fa fa-user fa-fw"></i>
用户:${USER_SESSION.user_name}
</a>
</li>
<li><a href="#"><i class="fa fa-gear fa-fw"></i> 系统设置</a></li>
<li class="divider"></li>
<li>
<a href="${pageContext.request.contextPath }/logout.action">
<i class="fa fa-sign-out fa-fw"></i>退出登录
</a>
</li>
</ul>
</li>
<!-- 用户信息和系统设置结束 -->
</ul>
<!-- 左侧显示列表部分 start-->
<div class="navbar-default sidebar" role="navigation">
<div class="sidebar-nav navbar-collapse">
<ul class="nav" id="side-menu">
<li class="sidebar-search">
<div class="input-group custom-search-form">
<input type="text" class="form-control" placeholder="查询内容...">
<span class="input-group-btn">
<button class="btn btn-default" type="button">
<i class="fa fa-search" style="padding: 3px 0 3px 0;"></i>
</button>
</span>
</div>
</li>
<li>
<a href="${pageContext.request.contextPath }/customer/list.action" class="active">
<i class="fa fa-edit fa-fw"></i> 客户管理
</a>
</li>
<li>
<a href="#">
<i class="fa fa-dashboard fa-fw" ></i> 客户拜访
</a>
</li>
</ul>
</div>
</div>
<!-- 左侧显示列表部分 end-->
</nav>
<!-- 客户列表查询部分 start-->
<div id="page-wrapper">
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">客户管理</h1>
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
<div class="panel panel-default">
<div class="panel-body">
<form class="form-inline" method="get"
action="${pageContext.request.contextPath }/customer/list.action">
<div class="form-group">
<label for="customerName">客户名称</label>
<input type="text" class="form-control" id="customerName"
value="${custName }" name="custName" />
</div>
<div class="form-group">
<label for="customerFrom">客户来源</label>
<select class="form-control" id="customerFrom" 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>
<button type="submit" class="btn btn-primary">查询</button>
</form>
</div>
</div>
<a href="#" class="btn btn-primary" data-toggle="modal"
data-target="#newCustomerDialog" onclick="clearCustomer()">新建</a>
<div class="row">
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-heading">客户信息列表</div>
<!-- /.panel-heading -->
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>编号</th>
<th>客户名称</th>
<th>客户来源</th>
<th>客户所属行业</th>
<th>客户级别</th>
<th>固定电话</th>
<th>手机</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${page.rows}" var="row">
<tr>
<td>${row.cust_id}</td>
<td>${row.cust_name}</td>
<td>${row.cust_source}</td>
<td>${row.cust_industry}</td>
<td>${row.cust_level}</td>
<td>${row.cust_phone}</td>
<td>${row.cust_mobile}</td>
<td>
<a href="#" class="btn btn-primary btn-xs" data-toggle="modal" data-target="#customerEditDialog" onclick= "editCustomer(${row.cust_id})">修改</a>
<a href="#" class="btn btn-danger btn-xs" onclick="deleteCustomer(${row.cust_id})">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
<div class="col-md-12 text-right">
<itheima:page url="${pageContext.request.contextPath }/customer/list.action" />
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
<!-- /.col-lg-12 -->
</div>
</div>
<!-- 客户列表查询部分 end-->
</div>
<!-- 创建客户模态框 -->
<div class="modal fade" id="newCustomerDialog" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="myModalLabel">新建客户信息</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" id="new_customer_form">
<div class="form-group">
<label for="new_customerName" class="col-sm-2 control-label">
客户名称
</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="new_customerName" placeholder="客户名称" name="cust_name" />
</div>
</div>
<div class="form-group">
<label for="new_customerFrom" style="float:left;padding:7px 15px 0 27px;">客户来源</label>
<div class="col-sm-10">
<select class="form-control" id="new_customerFrom" name="cust_source">
<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>
<div class="form-group">
<label for="new_custIndustry" style="float:left;padding:7px 15px 0 27px;">所属行业</label>
<div class="col-sm-10">
<select class="form-control" id="new_custIndustry" name="cust_industry">
<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>
<div class="form-group">
<label for="new_custLevel" style="float:left;padding:7px 15px 0 27px;">客户级别</label>
<div class="col-sm-10">
<select class="form-control" id="new_custLevel" name="cust_level">
<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>
</div>
<div class="form-group">
<label for="new_linkMan" class="col-sm-2 control-label">联系人</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="new_linkMan" placeholder="联系人" name="cust_linkman" />
</div>
</div>
<div class="form-group">
<label for="new_phone" class="col-sm-2 control-label">固定电话</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="new_phone" placeholder="固定电话" name="cust_phone" />
</div>
</div>
<div class="form-group">
<label for="new_mobile" class="col-sm-2 control-label">移动电话</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="new_mobile" placeholder="移动电话" name="cust_mobile" />
</div>
</div>
<div class="form-group">
<label for="new_zipcode" class="col-sm-2 control-label">邮政编码</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="new_zipcode" placeholder="邮政编码" name="cust_zipcode" />
</div>
</div>
<div class="form-group">
<label for="new_address" class="col-sm-2 control-label">联系地址</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="new_address" placeholder="联系地址" name="cust_address" />
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" onclick="createCustomer()">创建客户</button>
</div>
</div>
</div>
</div>
<!-- 修改客户模态框 -->
<div class="modal fade" id="customerEditDialog" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="myModalLabel">修改客户信息</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" id="edit_customer_form">
<input type="hidden" id="edit_cust_id" name="cust_id"/>
<div class="form-group">
<label for="edit_customerName" class="col-sm-2 control-label">客户名称</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="edit_customerName" placeholder="客户名称" name="cust_name" />
</div>
</div>
<div class="form-group">
<label for="edit_customerFrom" style="float:left;padding:7px 15px 0 27px;">客户来源</label>
<div class="col-sm-10">
<select class="form-control" id="edit_customerFrom" name="cust_source">
<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>
<div class="form-group">
<label for="edit_custIndustry" style="float:left;padding:7px 15px 0 27px;">所属行业</label>
<div class="col-sm-10">
<select class="form-control" id="edit_custIndustry" name="cust_industry">
<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>
<div class="form-group">
<label for="edit_custLevel" style="float:left;padding:7px 15px 0 27px;">客户级别</label>
<div class="col-sm-10">
<select class="form-control" id="edit_custLevel" name="cust_level">
<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>
</div>
<div class="form-group">
<label for="edit_linkMan" class="col-sm-2 control-label">联系人</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="edit_linkMan" placeholder="联系人" name="cust_linkman" />
</div>
</div>
<div class="form-group">
<label for="edit_phone" class="col-sm-2 control-label">固定电话</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="edit_phone" placeholder="固定电话" name="cust_phone" />
</div>
</div>
<div class="form-group">
<label for="edit_mobile" class="col-sm-2 control-label">移动电话</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="edit_mobile" placeholder="移动电话" name="cust_mobile" />
</div>
</div>
<div class="form-group">
<label for="edit_zipcode" class="col-sm-2 control-label">邮政编码</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="edit_zipcode" placeholder="邮政编码" name="cust_zipcode" />
</div>
</div>
<div class="form-group">
<label for="edit_address" class="col-sm-2 control-label">联系地址</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="edit_address" placeholder="联系地址" name="cust_address" />
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" onclick="updateCustomer()">保存修改</button>
</div>
</div>
</div>
</div>
<!-- 引入js文件 -->
<!-- jQuery -->
<script src="<%=basePath%>js/jquery-1.11.3.min.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="<%=basePath%>js/bootstrap.min.js"></script>
<!-- Metis Menu Plugin JavaScript -->
<script src="<%=basePath%>js/metisMenu.min.js"></script>
<!-- DataTables JavaScript -->
<script src="<%=basePath%>js/jquery.dataTables.min.js"></script>
<script src="<%=basePath%>js/dataTables.bootstrap.min.js"></script>
<!-- Custom Theme JavaScript -->
<script src="<%=basePath%>js/sb-admin-2.js"></script>
<!-- 编写js代码 -->
<script type="text/javascript">
//清空新建客户窗口中的数据
function clearCustomer() {
$("#new_customerName").val("");
$("#new_customerFrom").val("")
$("#new_custIndustry").val("")
$("#new_custLevel").val("")
$("#new_linkMan").val("");
$("#new_phone").val("");
$("#new_mobile").val("");
$("#new_zipcode").val("");
$("#new_address").val("");
}
// 创建客户
function createCustomer() {
$.post("<%=basePath%>customer/create.action",
$("#new_customer_form").serialize(),function(data){
if(data =="OK"){
alert("客户创建成功!");
window.location.reload();
}else{
alert("客户创建失败!");
window.location.reload();
}
});
}
// 通过id获取修改的客户信息
function editCustomer(id) {
$.ajax({
type:"get",
url:"<%=basePath%>customer/getCustomerById.action",
data:{"id":id},
success:function(data) {
$("#edit_cust_id").val(data.cust_id);
$("#edit_customerName").val(data.cust_name);
$("#edit_customerFrom").val(data.cust_source)
$("#edit_custIndustry").val(data.cust_industry)
$("#edit_custLevel").val(data.cust_level)
$("#edit_linkMan").val(data.cust_linkman);
$("#edit_phone").val(data.cust_phone);
$("#edit_mobile").val(data.cust_mobile);
$("#edit_zipcode").val(data.cust_zipcode);
$("#edit_address").val(data.cust_address);
}
});
}
// 执行修改客户操作
function updateCustomer() {
$.post("<%=basePath%>customer/update.action",$("#edit_customer_form").serialize(),function(data){
if(data =="OK"){
alert("客户信息更新成功!");
window.location.reload();
}else{
alert("客户信息更新失败!");
window.location.reload();
}
});
}
// 删除客户
function deleteCustomer(id) {
if(confirm('确实要删除该客户吗?')) {
$.post("<%=basePath%>customer/delete.action",{"id":id},
function(data){
if(data =="OK"){
alert("客户删除成功!");
window.location.reload();
}else{
alert("删除客户失败!");
window.location.reload();
}
});
}
}
</script>
</body>
</html>
# 创建分页查询
# 实现分页功能
自定义标签文件主要用于实现分页功能:commons.tld
<?xml version="1.0" encoding="UTF-8" ?> | |
<!DOCTYPE taglib | |
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" | |
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> | |
<taglib> | |
<!-- 指定标签库的版本号 --> | |
<tlib-version>2.0</tlib-version> | |
<!-- 指定 JSP 的版本号 --> | |
<jsp-version>1.2</jsp-version> | |
<!-- 指定标签库的名称 --> | |
<short-name>common</short-name> | |
<!-- 指定标签库的 URI --> | |
<uri>http://itheima.com/common/</uri> | |
<!-- 指定标签库的显示名称 --> | |
<display-name>Common Tag</display-name> | |
<!-- 指定标签库的描述 --> | |
<description>Common Tag library</description> | |
<!-- 注册一个自定义标签 --> | |
<tag> | |
<!-- 指定注册的自定义标签名称 --> | |
<name>page</name> | |
<!-- 指定自定义标签的标签处理器类 --> | |
<tag-class>com.itheima.common.utils.NavigationTag</tag-class> | |
<!-- 指定标签体类型 --> | |
<body-content>JSP</body-content> | |
<!-- 描述 --> | |
<description>create navigation for paging</description> | |
<!-- 指定标签中的属性 --> | |
<attribute> | |
<!-- 指定属性名称 --> | |
<name>url</name> | |
<!-- 该属性为 true 时表示其指定是属性为必须属性 --> | |
<required>true</required> | |
<!-- 该属性用于指定能不能使用表达式来动态指定数据,为 true 时表示可以 --> | |
<rtexprvalue>true</rtexprvalue> | |
</attribute> | |
<attribute> | |
<name>bean</name> | |
<rtexprvalue>true</rtexprvalue> | |
</attribute> | |
<attribute> | |
<name>number</name> | |
<rtexprvalue>true</rtexprvalue> | |
</attribute> | |
</tag> | |
</taglib> |
# 引入分页标签类
- Page.java
boot-crm\src\com\itheima\common\utils\Page.java
package com.itheima.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; | |
} | |
} |
- NavigationTag.java
boot-crm\src\com\itheima\common\utils\ NavigationTag.java
package com.itheima.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\">"); | |
// 首页链接路径 | |
String homeUrl = append(url, "page", 1); | |
// 末页链接路径 | |
String backUrl = append(url, "page", pageCount); | |
// 显示 “上一页” 按钮 | |
if (page.getPage() > 1) { | |
String preUrl = append(url, "page", page.getPage() - 1); | |
preUrl = append(preUrl, "rows", page.getSize()); | |
writer.print("<li><a href=\"" + homeUrl + "\">" + "首页</a></li>"); | |
writer.print("<li><a href=\"" + preUrl + "\">" + "上一页</a></li>"); | |
} else { | |
writer.print("<li class=\"disabled\"><a href=\"#\">" + "首页 </a></li>"); | |
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 =1; | |
if(page.getPage() - 2 <=0){ | |
indexPage=1; | |
}else if(pageCount-page.getPage() <=2){ | |
indexPage=pageCount-4; | |
}else{ | |
indexPage= page.getPage() - 2; | |
} | |
for (int i= 1;i <= number && indexPage <= pageCount;indexPage++,i++){ | |
if (indexPage == page.getPage()) { | |
writer.print("<li class=\"active\"><a href=\"#\">" + indexPage | |
+"<spanclass=\"sr-only\"></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>"); | |
writer.print("<li><a href=\"" + backUrl + "\">" + "尾页</a></li>"); | |
} else { | |
writer.print("<li class=\"disabled\"><a href=\"#\">" + "下一页</a></li>"); | |
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 参加参数对儿 | |
*/ | |
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 + "&" + key + "=" + value; | |
} | |
} | |
return url; | |
} | |
/** | |
* 为 url 添加翻页请求参数 | |
*/ | |
private String resolveUrl(String url, | |
javax.servlet.jsp.PageContext pageContext) throws JspException { | |
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; | |
} | |
} |
# 项目小结
整体来看,基本功能(增删改查)都已较为熟练。例如:
- 增加一个功能的流程
- 在 Dao 层接口里定义方法,xml 映射里编写 SQL 语句,用于实现方法
- 在 Service 层接口,为服务端添加方法,并在 Impl 实现类中实现方法
- 在前端界面 customer 中,添加触发器,用于客户使用,测试方法
- 在控制器类 Controller 中,调用方法,并放回数据。(利用注释:返回界面)
前端技术,开始看 KuangStudy 的学习视频;
后端技术,对于分页查询还有一部分不会的地方,有待把握。