JDBC实现客户关系管理
这是一个使用JDBC技术来实现客户关系管理系统的案例废话不多说直接进入demo项目步骤很多建议一步一步的跟着做当然大神略过。
创建Web项目采用最简单的MVC三层架构
在Eclipse中新创建一个customer项目,导入项目所需要的开发包(jar包),创建项目所需要的包,在java开发中,架构的层次是以包的形式体现出来的。
项目所需要的开发包(jar包):
序号 | 开发包名称 | 描述 |
---|---|---|
1 | stl-1.2.jar | jstl标签库和EL表达式依赖包 |
2 | mysql-connector-java-5.1.38-bin.jar | MySQL数据库驱动包 |
3 | commons-beanutils-1.9.2.jar | 工具类,用于处理bean对象 |
4 | commons-logging-1.2.jar | commons-beanutils-1.9.2.jar的依赖jar包 |
5 | commons-collections-3.2.2.jar | commons-beanutils-1.9.2.jar的依赖jar包 |
项目所需要的包及类:
以上就是根据此项目的实际情况创建的包,可能还需要创建其他的包,这个得根据项目的需要来定了。
为应用创建相应库和表:
建表SQL语句
create database customer character set utf8 collate utf8_general_ci;
use customer;
create table customer
(
id varchar(40) primary key,
name varchar(40) not null,
gender varchar(4) not null,
birthday date,
cellphone varchar(20),
email varchar(40),
preference varchar(255),
type varchar(100) not null,
description varchar(255)
);
除此之外,还应在src目录下创建一个db.properties文件,在db.properties中编写MySQL数据库的连接信息,内容如下所示:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/customer
username=root
password=xxx 记得改成你自己的密码
在WEB-INF目录下创建一个jsp目录,jsp目录存放系统的一些受保护(不允许用户直接通过URL地址访问)的jsp页面,用户要想访问这些受保护的jsp页面,我们可以在程序中进行控制跳转。
创建好的项目架构如下图所示:提示我使用的是idea工具,lib包没有自动创建,是手动创建的并且手动依赖jar包。
分层架构的代码编写
分层架构的代码也是按照【域模型层(domain)】→【数据访问层(dao、dao.impl)】→【业务逻辑层(service、service.impl)】→【表现层(web.controller、web.filter、web.listener)】→【工具类(util)】→【测试类(junit.test)】的顺序进行编写的。
为了让你不忘记配置Servlet先直接把web.xml配置展现出来。按开发流程应该是创建一个Servlet配置一个。当然你可以抽取怎么简单怎么来。web.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>AddCustomerServlet</servlet-name>
<servlet-class>cn.bjyy.controller.AddCustomerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AddCustomerServlet</servlet-name>
<url-pattern>/AddCustomerServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ListCustomerServlet</servlet-name>
<servlet-class>cn.bjyy.controller.ListCustomerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ListCustomerServlet</servlet-name>
<url-pattern>/ListCustomerServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>EditCustomerServlet</servlet-name>
<servlet-class>cn.bjyy.controller.EditCustomerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>EditCustomerServlet</servlet-name>
<url-pattern>/EditCustomerServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>DelCustomerServlet</servlet-name>
<servlet-class>cn.bjyy.controller.DelCustomerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DelCustomerServlet</servlet-name>
<url-pattern>/DelCustomerServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ServletDemo</servlet-name>
<servlet-class>cn.bjyy.controller.ServletDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo</servlet-name>
<url-pattern>/ServletDemo</url-pattern>
</servlet-mapping>
</web-app>
开发domain层
在cn.bjyy.domain包下创建一个Customer类。为了给分页做准备我们一步到位先创建所需的实体类,要用的时候直接用就行了。
Customer类具体代码如下:
package cn.bjyy.domain;
import java.util.Date;
/**
* Created by YYBJ on 2018/9/26.
* ZCL
*/
public class Customer {
private String id;
private String name;
private String gender;
private Date birthday;
private String cellphone;
private String email;
private String preference;
private String type;
private String description;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getCellphone() {
return cellphone;
}
public void setCellphone(String cellphone) {
this.cellphone = cellphone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPreference() {
return preference;
}
public void setPreference(String preference) {
this.preference = preference;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "Customer{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", birthday=" + birthday +
", cellphone='" + cellphone + '\'' +
", email='" + email + '\'' +
", preference='" + preference + '\'' +
", type='" + type + '\'' +
", description='" + description + '\'' +
'}';
}
}
pageBean类;
package cn.bjyy.domain;
import java.util.List;
/**
* Created by YYBJ on 2018/10/9.
* ZCL
*/
public class PageBean {
private List list;
private int totalrecord;
private int pagesize;
private int totalpage;
private int currentpage;
private int previouspage;
private int nextpage;
private int[] pagebar;
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public int getTotalrecord() {
return totalrecord;
}
public void setTotalrecord(int totalrecord) {
this.totalrecord = totalrecord;
}
public int getPagesize() {
return pagesize;
}
public void setPagesize(int pagesize) {
this.pagesize = pagesize;
}
public int getTotalpage() {
// 100 每页显示5 20页
// 101 每页显示5 21页
// 99 每页显示5 20页
if (this.totalrecord%this.pagesize==0) {
this.totalpage = this.totalrecord / this.pagesize;
} else {
this.totalpage = this.totalrecord / this.pagesize + 1;
}
return totalpage;
}
public int getCurrentpage() {
return currentpage;
}
public void setCurrentpage(int currentpage) {
this.currentpage = currentpage;
}
public int getPreviouspage() {
if (this.currentpage - 1 < 1) {
this.previouspage = 1;
} else {
this.previouspage = this.currentpage - 1;
}
return previouspage;
}
public int getNextpage() {
if (this.currentpage + 1 >= this.totalpage) {
this.nextpage = this.totalpage;
} else {
this.nextpage = this.currentpage + 1;
}
return nextpage;
}
public int[] getPagebar() {
int[] pagebar = null;
int startpage; // 起始页码
int endpage; // 结束页码
if (this.totalpage <= 10) {
pagebar = new int[this.totalpage];
startpage = 1;
endpage = this.totalpage;
} else {
pagebar = new int[10];
startpage = this.currentpage - 4;
endpage = this.currentpage + 5;
// 总页数=30,假设看的是第3页,则startpage=-1
// 总页数=30,假设看的是第29页,则endpage=34
if (startpage < 1) {
startpage = 1;
endpage = 10;
}
if (endpage > this.totalpage) {
endpage = this.totalpage;
startpage = this.totalpage - 9;
}
}
int index = 0;
for (int i = startpage; i <= endpage; i++) {
pagebar[index++] = i;
}
this.pagebar = pagebar;
return this.pagebar;
}
}
QueryInfo实体类:
package cn.bjyy.domain;
/**
* Created by YYBJ on 2018/10/9.
* ZCL
*/
public class QueryInfo {
private int currentpage = 1; // 用户当前看的页
private int pagesize = 6; // 记住用户想看的页面大小
private int startindex; // 记住用户看的页的数据在数据库表中的起始位置
public int getCurrentpage() {
return currentpage;
}
public void setCurrentpage(int currentpage) {
this.currentpage = currentpage;
}
public int getPagesize() {
return pagesize;
}
public void setPagesize(int pagesize) {
this.pagesize = pagesize;
}
public int getStartindex() {
this.startindex = (this.currentpage-1)*this.pagesize;
return startindex;
}
}
QueryResult实体类:
package cn.bjyy.domain;
import java.util.List;
/**
* Created by YYBJ on 2018/10/9.
* ZCL
*/
public class QueryResult {
private List list; // 记住用户看的页的数据
private int totalrecord; // 记住总记录数
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public int getTotalrecord() {
return totalrecord;
}
public void setTotalrecord(int totalrecord) {
this.totalrecord = totalrecord;
}
}
开发数据访问层(dao、dao.impl)
在开发数据访问层时,由于要编写得到MySQL数据库链接和释放资源这些性质的操作,所以应该把他们放在一个工具类JdbcUtils中。在cn.bjyy.utils包下创建一个JdbcUtils类。
JdbcUtils类的具体代码如下:
package cn.bjyy.utils;
import java.sql.*;
import java.util.Properties;
/**
* Created by YYBJ on 2018/9/20.
* ZCL
*/
public class JdbcUtils {
private static Properties config=new Properties();
//静态代码块只执行一次,因为静态代码块在类加载时执行,类永远只加载一次
// 静态代码块只执行一次,因为静态代码块在类加载时执行,类永远只加载一次
static {
try {
config.load(JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties"));
Class.forName(config.getProperty("driver"));
} catch (Exception e) {
/*
* db.properties文件都无法读取,那么整个应用程序无法连接数据库;
* 驱动都加载不了,那么整个应用程序都无法工作,
* 所以都应该抛一个错误(ExceptionInInitializerError)
*/
throw new ExceptionInInitializerError(e);
}
}
public static Connection getConnection() throws SQLException {
Connection conn = DriverManager.getConnection(config.getProperty("url"), config.getProperty("username"), config.getProperty("password"));
return conn;
}
public static void release(Connection conn, PreparedStatement st, ResultSet rs) {
if (rs!=null) {
try {
rs.close(); // 假设throw异常
} catch (Exception e) {
e.printStackTrace(); // 只需在后台记录异常
}
rs = null; // 假设rs对象没有释放,将其置为null,该对象就变成垃圾,由Java垃圾回收器回收
}
if (st!=null) {
try {
st.close(); // 假设throw异常
} catch (Exception e) {
e.printStackTrace(); // 只需在后台记录异常
}
st = null;
}
if (conn!=null) {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace(); // 只需在后台记录异常
}
}
conn = null;
}
}
在cn.bjyy.dao包下创建一个CustomerDao接口类。
CustomerDao接口的具体代码如下:
package cn.bjyy.dao;
import cn.bjyy.domain.Customer;
import cn.bjyy.domain.QueryResult;
import java.util.List;
/**
* Created by YYBJ on 2018/9/26.
* ZCL
*/
public interface CustomerDao {
void add(Customer c);
void update(Customer c);
void delete(String id);
Customer find(String id);
List<Customer> getAll();
QueryResult PageQuery(int startindex, int pagesize);
}
接着应该编写CustomerDao接口的实现类CustomerDaoImpl:注意这里我把分页的代码也一并展现了,先不用管他先把基本的增删改查搞定:
package cn.bjyy.dao.impl;
import cn.bjyy.dao.CustomerDao;
import cn.bjyy.domain.Customer;
import cn.bjyy.domain.QueryResult;
import cn.bjyy.exception.DaoException;
import cn.bjyy.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
/**
* Created by YYBJ on 2018/9/26.
* ZCL
*/
public class CustomerDaoImpl implements CustomerDao {
@Override
public void add(Customer c) {
Connection conn=null;
PreparedStatement st=null;
ResultSet rs=null;
try {
conn = JdbcUtils.getConnection();
String sql = "insert into customer(id, name,gender,birthday,cellphone,email,preference,type,description) values(?,?,?,?,?,?,?,?,?)";
st = conn.prepareStatement(sql);
st.setString(1, c.getId());
st.setString(2, c.getName());
st.setString(3, c.getGender());
st.setDate(4, new java.sql.Date(c.getBirthday().getTime()));
st.setString(5, c.getCellphone());
st.setString(6, c.getEmail());
st.setString(7, c.getPreference());
st.setString(8, c.getType());
st.setString(9, c.getDescription());
st.executeUpdate();
}catch (Exception e){
throw new DaoException(e);
}finally {
JdbcUtils.release(conn,st,rs);
}
}
@Override
public void update(Customer c) {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
String sql = "update customer set name=?,gender=?,birthday=?,cellphone=?,email=?,preference=?,type=?,description=? where id=?";
st = conn.prepareStatement(sql);
st.setString(1, c.getName());
st.setString(2, c.getGender());
st.setDate(3, new java.sql.Date(c.getBirthday().getTime()));
st.setString(4, c.getCellphone());
st.setString(5, c.getEmail());
st.setString(6, c.getPreference());
st.setString(7, c.getType());
st.setString(8, c.getDescription());
st.setString(9, c.getId());
st.executeUpdate();
} catch (Exception e) {
throw new DaoException(e);
} finally {
JdbcUtils.release(conn, st, rs);
}
}
@Override
public void delete(String id) {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
String sql = "delete from customer where id=?";
st = conn.prepareStatement(sql);
st.setString(1, id);
st.executeUpdate();
} catch (Exception e) {
throw new DaoException(e);
} finally {
JdbcUtils.release(conn, st, rs);
}
}
@Override
public Customer find(String id) {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
String sql = "select * from customer where id=?";
st = conn.prepareStatement(sql);
st.setString(1, id);
rs = st.executeQuery();
if (rs.next()) {
Customer c = new Customer();
c.setBirthday(rs.getDate("birthday"));
c.setCellphone(rs.getString("cellphone"));
c.setDescription(rs.getString("description"));
c.setEmail(rs.getString("email"));
c.setGender(rs.getString("gender"));
c.setId(rs.getString("id"));
c.setName(rs.getString("name"));
c.setPreference(rs.getString("preference"));
c.setType(rs.getString("type"));
return c;
}
return null;
} catch (Exception e) {
throw new DaoException(e);
} finally {
JdbcUtils.release(conn, st, rs);
}
}
@Override
public List<Customer> getAll() {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
String sql = "select * from customer";
st = conn.prepareStatement(sql);
rs = st.executeQuery();
List<Customer> list = new ArrayList<Customer>();
while (rs.next()) {
Customer c = new Customer();
c.setBirthday(rs.getDate("birthday"));
c.setCellphone(rs.getString("cellphone"));
c.setDescription(rs.getString("description"));
c.setEmail(rs.getString("email"));
c.setGender(rs.getString("gender"));
c.setId(rs.getString("id"));
c.setName(rs.getString("name"));
c.setPreference(rs.getString("preference"));
c.setType(rs.getString("type"));
list.add(c);
}
return list;
} catch (Exception e) {
throw new DaoException(e);
} finally {
JdbcUtils.release(conn, st, rs);
}
}
@Override
public QueryResult PageQuery(int startindex, int pagesize) {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
QueryResult qr = new QueryResult();
try {
conn = JdbcUtils.getConnection();
String sql = "select * from customer limit ?,?";
st = conn.prepareStatement(sql);
st.setInt(1,startindex);
st.setInt(2,pagesize);
rs = st.executeQuery();
List<Customer> list = new ArrayList<Customer>();
while(rs.next()) {
Customer c = new Customer();
c.setBirthday(rs.getDate("birthday"));
c.setCellphone(rs.getString("cellphone"));
c.setDescription(rs.getString("description"));
c.setEmail(rs.getString("email"));
c.setGender(rs.getString("gender"));
c.setId(rs.getString("id"));
c.setName(rs.getString("name"));
c.setPreference(rs.getString("preference"));
c.setType(rs.getString("type"));
list.add(c);
}
qr.setList(list);
sql = "select count(*) from customer";
rs = conn.prepareStatement(sql).executeQuery();
if (rs.next()) {
qr.setTotalrecord(rs.getInt(1));
}
return qr;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
JdbcUtils.release(conn, st, rs);
}
}
}
无论业务是否简单或者复杂难免会发生异常,所以在实际开发中,最好每一个层都编写一个自定义异常这样有助于快速定位错误或者说提高你对代码的理解,例如在Dao层(数据访问层)自定义一个异常类DaoException。
在cn.bjyy.exception包中创建异常类DaoException,如下:
DaoException类的具体代码如下:
package cn.bjyy.exception;
/**
* Created by YYBJ on 2018/9/26.
* ZCL
*/
public class DaoException extends RuntimeException {
public DaoException(){
}
public DaoException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public DaoException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
public DaoException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public DaoException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
}
开发service层(service层对web层提供所有的业务服务)
在cn.bjyy.service包下创建一个BusinessService接口类。
BusinessService接口类的具体代码如下:
package cn.bjyy.service;
import cn.bjyy.domain.Customer;
import cn.bjyy.domain.PageBean;
import cn.bjyy.domain.QueryInfo;
import java.util.List;
/**
* Created by YYBJ on 2018/9/26.
* ZCL
*/
public interface BusinessService {
void addCustomer(Customer c);
void updateCustomer(Customer c);
void deleteCustomer(String id);
Customer findCustomer(String id);
List<Customer> getAllCustomer();
PageBean pageQuery(QueryInfo info);
}
接着在cn.bjyy.service.impl包下编写BusinessService接口的一个实现类BusinessServiceImpl。
BusinessServiceImpl实现类的具体代码如下:
package cn.bjyy.service.impl;
import cn.bjyy.dao.CustomerDao;
import cn.bjyy.dao.impl.CustomerDaoImpl;
import cn.bjyy.domain.Customer;
import cn.bjyy.domain.PageBean;
import cn.bjyy.domain.QueryInfo;
import cn.bjyy.domain.QueryResult;
import cn.bjyy.service.BusinessService;
import java.util.List;
/**
* Created by YYBJ on 2018/9/30.
* ZCL
*/
public class BusinessServiceImpl implements BusinessService {
private CustomerDao customerDao=new CustomerDaoImpl();
@Override
public void addCustomer(Customer c) {
customerDao.add(c);
}
@Override
public void updateCustomer(Customer c) {
customerDao.update(c);
}
@Override
public void deleteCustomer(String id) {
customerDao.delete(id);
}
@Override
public Customer findCustomer(String id) {
return customerDao.find(id);
}
@Override
public List<Customer> getAllCustomer() {
return customerDao.getAll();
}
@Override
public PageBean pageQuery(QueryInfo info) {
QueryResult qr=customerDao.PageQuery(info.getStartindex(),info.getPagesize());
PageBean bean = new PageBean();
bean.setCurrentpage(info.getCurrentpage());
bean.setList(qr.getList());
bean.setPagesize(info.getPagesize());
bean.setTotalrecord(qr.getTotalrecord());
return bean;
}
}
同理,开发完业务逻辑层,一定要对程序已编写好的部分代码进行测试。
开发Web层
在一个项目中,开发Web层是最麻烦的,我们一定要有耐心哟。此客户关系管理系统的首页index.jsp,我们是采用分帧的方式来设计的,index.jsp代码如下:
<%--
Created by IntelliJ IDEA.
User: YYBJ
Date: 2018/9/20
Time: 17:42
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<!-- 分帧(横向) -->
<frameset rows="25%,75%" >
<frame name="head" src="/head.jsp">
<frame name="main" src="#">
</frameset>
</html>
接着我们创建head.jsp页面,head.jsp代码如下:
<%--
Created by IntelliJ IDEA.
User: YYBJ
Date: 2018/9/30
Time: 10:54
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body style="text-align: center;">
<h1>客户关系管理系统</h1>
<br/>
<!-- target="main"意思是结果显示到name为main的frame中 -->
<a href="/AddCustomerServlet" target="main">添加客户</a>
<a href="/ListCustomerServlet" target="main">查看客户</a>
</body>
</html>
通过页面简单测试:
接着开发添加客户的功能
在cn.bjyy.utils包下创建一个WebUtils工具类,该工具类的功能就是封装客户端提交的表单数据到Customer对象中。
WebUtils工具类的具体代码如下:
package cn.bjyy.utils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import org.apache.taglibs.standard.lang.jstl.parser.ParseException;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
/**
* Created by YYBJ on 2018/9/30.
* ZCL
*/
public class WebUtils {
public static <E> E request2Bean(HttpServletRequest request, Class<E> beanClass) {
try {
E bean = beanClass.newInstance();
// 得到request里面所有数据
Map<String, String[]> map = request.getParameterMap();
// 注册一个转换器
ConvertUtils.register(new Converter() {
@Override
public Object convert(Class aClass, Object value) {
if (value==null) {
return null;
}
String str = (String)value;
if (str.trim().equals("")) {
return null;
}
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try {
return (Object) df.parse(str);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}, Date.class);
BeanUtils.populate(bean, map); // map{name=aa,password=abc,birthday=1990-10-09} bean(name=aa,password=abc,birthday=Date)
return bean;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 产生全球唯一的id
public static String generateID() {
return UUID.randomUUID().toString(); // UUID算法根据你系统的网卡的xx地址、CPU、机器的型号等等生成一个128位长的字符串,可以确保是全球唯一的。
}
}
当我们访问该客户关系管理系统首页时,要完成添加客户的功能,只须点击添加客户超链接,照理说,我们应该在cn.bjyy.controller包下创建一个Servlet,诸如这样:
package cn.bjyy.controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Created by YYBJ on 2018/9/30.
* ZCL
*/
public class ServletDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getRequestDispatcher("/WEB-INF/jsp/addcustomer.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
}
给用户提供一个添加客户界面。其实还有一种更偷懒的方法,我们大可不必编写如上的Servlet,只须编写一个Servlet,doGet方法用来给用户提供一个添加客户界面,doPost方法用来接收表单的添加客户请求(post),并处理用户的添加请求,这样不是更好嘛!
现在我们来编写添加客户界面addcustomer.jsp,第一次编写该界面代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- 注意:laydate.js所在文件夹应放在WebRoot里,WEB-INF外!!!并且它的使用很简单 -->
<script type="text/javascript" src="${pageContext.request.contextPath }/layDate-v5.0.9/laydate/laydate.js"></script>
<link rel="stylesheet" href="/layDate-v5.0.9/laydate/theme/default/laydate.css">
<title>添加用户的视图</title>
</head>
<body style="text-align: center;">
<br/>
<form id="form" action="${pageContext.request.contextPath }/AddCustomerServlet" method="post">
<table border="1" width="50%" align="center">
<tr>
<td>客户姓名</td>
<td>
<input type="text" name="name">
</td>
</tr>
<tr>
<td>客户性别</td>
<td>
<input type="radio" name="gender" value="男">男
<input type="radio" name="gender" value="女">女
<input type="radio" name="gender" value="人妖">人妖
</td>
</tr>
<tr>
<td>生日</td>
<td>
<input type="text" name="birthday" id="birthday">
</td>
</tr>
<tr>
<td>手机</td>
<td>
<input type="text" name="cellphone">
</td>
</tr>
<tr>
<td>邮箱</td>
<td>
<input type="text" name="email">
</td>
</tr>
<tr>
<td>爱好</td>
<td>
<input type="checkbox" name="pre" value="唱歌">唱歌
<input type="checkbox" name="pre" value="跳舞">跳舞
<input type="checkbox" name="pre" value="逛夜店">逛夜店
</td>
</tr>
<tr>
<td>客户类型</td>
<td>
<input type="radio" name="type" value="VIP客户">VIP客户
<input type="radio" name="type" value="重点客户">重点客户
<input type="radio" name="type" value="一般客户">一般客户
</td>
</tr>
<tr>
<td>客户备注</td>
<td>
<textarea rows="5" cols="60" name="description"></textarea>
</td>
</tr>
<tr>
<td>
<input type="reset" value="重置">
</td>
<td>
<input type="submit" value="添加客户">
</td>
</tr>
</table>
</form>
</body>
<script type="text/javascript">
//执行一个laydate实例
laydate.render({
elem: document.getElementById("birthday") //指定元素
});
</script>
</html>
由于生日输入框中要输入日期,所以可以从网上随便扒下一个日期控件我使用的是layDate-v5.0.9日期插件,该日期控件的使用方法简单实用当然啦你有更好的日期控件也可以:
-
在生日输入框使用该日期控件
<!--引入日期控件--> <script type="text/javascript" src="${pageContext.request.contextPath }/layDate-v5.0.9/laydate/laydate.js"></script> <link rel="stylesheet" href="/layDate-v5.0.9/laydate/theme/default/laydate.css"> <input type="text" name="birthday" id="birthday"> <!--使用--> <script type="text/javascript"> //执行一个laydate实例 laydate.render({ elem: document.getElementById("birthday") //指定元素 }); </script>
日期控件的实例显示:
以上添加客户界面addcustomer.jsp,是我们最终所需要的吗?显然不是,因为客户性别、爱好、客户类型等等都是写死在程序中的,在实际开发中,页面到底输出几个性别,不是在页面中显示的,而是由一个程序维护的,这个程序有几个性别,页面中就输出几个性别。也就是说客户性别、爱好、客户类型等输入选项在数据库里面都有各自对应的表,我们要从数据库里面读取出来并显示在页面中。我们也不必搞得这么麻烦,可编写一个java类来模拟。
在cn.bjyy.utils包中创建一个Globals类,如下:
Globals类的具体代码如下:
public class Globals {
// 一般用枚举来表示性别
public static String[] genders = {"男","女","人妖"};
// 在实际开发中,在数据库里面应有一个爱好表,爱好是由一个表来维护的。但在此案例中,不会设计的这么复杂,所以在程序里写死来维护
public static String[] preferences = {"唱歌","跳舞","桑拿","打麻将","看凤姐","夜生活","爬山"};
public static String[] types = {"VIP客户","重点客户","普通客户"};
}
接下来就在cn.bjyy.controller包中创建一个Servlet,该Servlet既用来给用户提供一个添加客户界面,又用来接收表单的添加客户请求(post),并处理用户的添加请求。
但现在我们只编写Servlet用来给用户提供一个添加客户界面的代码。
package cn.bjyy.controller;
import cn.bjyy.domain.Customer;
import cn.bjyy.service.impl.BusinessServiceImpl;
import cn.bjyy.utils.Globals;
import cn.bjyy.utils.WebUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Created by YYBJ on 2018/9/30.
* ZCL
*/
public class AddCustomerServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("AddCustomerServlet=====");
req.setAttribute("genders", Globals.genders);
req.setAttribute("preferences",Globals.preferences);
req.setAttribute("types",Globals.types);
req.getRequestDispatcher("/WEB-INF/jsp/addcustomer.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
req.setCharacterEncoding("UTF-8");
//在实际开发中一定要对表单进行校验
//把表单数据封装到customer对象中
Customer customer = WebUtils.request2Bean(req, Customer.class);
customer.setId(WebUtils.generateID());
BusinessServiceImpl service = new BusinessServiceImpl();
service.addCustomer(customer);
req.setAttribute("message","添加成功!!!");
}catch (Exception e){
e.printStackTrace();
req.setAttribute("message","添加失败!!!");
}
req.getRequestDispatcher("/message.jsp").forward(req,resp);
}
}
此时修改添加客户界面addcustomer.jsp。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="${pageContext.request.contextPath }/layDate-v5.0.9/laydate/laydate.js"></script>
<link rel="stylesheet" href="/layDate-v5.0.9/laydate/theme/default/laydate.css">
<title>添加用户的视图</title>
</head>
<body style="text-align: center;">
<br/>
<form id="form" action="${pageContext.request.contextPath }/AddCustomerServlet" method="post" onsubmit="return makepre()">
<table border="1" width="50%" align="center">
<tr>
<td>客户姓名</td>
<td>
<input type="text" name="name">
</td>
</tr>
<tr>
<td>客户性别</td>
<td>
<!--
页面到底输出几个性别,不是在页面中显示的,而是由一个程序维护的,这个程序有几个性别,页面中就输出几个性别
<input type="radio" name="gender" value="男">男
<input type="radio" name="gender" value="女">女
-->
<c:forEach var="gender" items="${genders }">
<input type="radio" name="gender" value="${gender }">${gender }
</c:forEach>
</td>
</tr>
<tr>
<td>生日</td>
<td>
<input type="text" name="birthday" id="birthday">
</td>
</tr>
<tr>
<td>手机</td>
<td>
<input type="text" name="cellphone">
</td>
</tr>
<tr>
<td>邮箱</td>
<td>
<input type="text" name="email">
</td>
</tr>
<tr>
<td>爱好</td>
<td>
<c:forEach var="p" items="${preferences }">
<input type="checkbox" name="pre" id="pre" value="${p }">${p }
</c:forEach>
</td>
</tr>
<tr>
<td>客户类型</td>
<td>
<c:forEach var="type" items="${types }">
<input type="radio" name="type" value="${type }">${type }
</c:forEach>
</td>
</tr>
<tr>
<td>客户备注</td>
<td>
<textarea rows="5" cols="60" name="description"></textarea>
</td>
</tr>
<tr>
<td>
<input type="reset" value="重置">
</td>
<td>
<input type="submit" value="添加客户">
</td>
</tr>
</table>
</form>
</body>
<script type="text/javascript">
//执行一个laydate实例
laydate.render({
elem: document.getElementById("birthday") //指定元素
});
function makepre() {
var pres = document.getElementsByName("pre");
var preference = "";
for(var i=0;i<pres.length;i++) {
var input = pres[i];
if(input.checked==true) {
preference = preference + input.value + ",";
}
}
preference = preference.substring(0, preference.length-1); // preference="唱歌,跳舞,夜生活";
console.log("爱好内容===="+preference)
// 在form表单创建一个input隐藏输入项,如:<input type="hidden" name="preference" value="唱歌,跳舞,夜生活,...">
var form = document.getElementById("form");
var input = document.createElement("input");
input.type = "hidden";
input.name = "preference";
input.value = preference;
form.appendChild(input);
return true;
}
</script>
</html>
填写完客户信息,点击添加客户按钮,将表单数据提交到AddCustomerServlet中,在提交爱好这一选项中的数据时,提交的是像这样的数据:
- pre=”唱歌”
- pre=”跳舞”
而存到数据库里面的是一串字符串,如:”唱歌,跳舞”。所以我们应该对提交的爱好数据进行相应地处理,即可在服务器端进行处理,又可在客户端进行处理,我们选择在客户端进行处理。在addcustomer.jsp中添加如下的javascript代码:
<script type="text/javascript">
function makepre() {
var pres = document.getElementsByName("pre");
var preference = "";
for(var i=0;i<pres.length;i++) {
var input = pres[i];
if(input.checked==true) {
preference = preference + input.value + ",";
}
}
preference = preference.substring(0, preference.length-1); // preference="唱歌,跳舞,夜生活";
// 在form表单创建一个input隐藏输入项,如:<input type="hidden" name="preference" value="唱歌,跳舞,夜生活,...">
var form = document.getElementById("form");
var input = document.createElement("input");
input.type = "hidden";
input.name = "preference";
input.value = preference;
form.appendChild(input);
return true;
}
</script>
在实际开发中,一定要对表单提交过来的数据进行校验,为了简单在此客户关系管理系统中我们省略这一步。
最后创建全局消息显示页面message.jsp,代码如下:
<%--
Created by IntelliJ IDEA.
User: YYBJ
Date: 2018/9/30
Time: 14:05
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>全局消息显示页面</title>
</head>
<body>
${requestScope.message }
</body>
</html>
测试开发好的添加客户功能。
添加成功即没有任何问题。
接着开发查看客户的功能
在cn.bjyy.controller包下编写ListCustomerServlet,用于得到所有客户并跳转到jsp页面显示。
ListCustomerServlet类的具体代码如下:
package cn.bjyy.controller;
import cn.bjyy.domain.Customer;
import cn.bjyy.domain.PageBean;
import cn.bjyy.domain.QueryInfo;
import cn.bjyy.service.impl.BusinessServiceImpl;
import cn.bjyy.utils.WebUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
* Created by YYBJ on 2018/10/8.
* ZCL
*/
public class ListCustomerServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
BusinessServiceImpl service = new BusinessServiceImpl();
QueryInfo info = WebUtils.request2Bean(req, QueryInfo.class);
PageBean pageBean=service.pageQuery(info);
List<Customer> list = service.getAllCustomer();
for (Customer c:list) {
System.out.println(c);
}
//req.setAttribute("pagebean",pageBean);
req.setAttribute("list",list);
req.getRequestDispatcher("/WEB-INF/jsp/listcustomer.jsp").forward(req,resp);
}catch (Exception e){
e.printStackTrace();
req.setAttribute("message","查看客服失败!!!");
req.getRequestDispatcher("/message.jsp").forward(req,resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
}
接下来我们创建listcustomer.jsp,用于展示所有客户信息。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>列出所有客户</title>
</head>
<style type="text/css">
.even {background-color: #FFF000}
.odd {background-color: #FFCCFF}
tr:HOVER {background-color: #FF99FF} /* 注意需要更高版本的文档声明 */
</style>
<body style="text-align: center;">
<table frame="border" width="85%">
<tr>
<td>客户姓名</td>
<td>性别</td>
<td>生日</td>
<td>手机</td>
<td>邮箱</td>
<td>爱好</td>
<td>类型</td>
<td>备注</td>
<td>操作</td>
</tr>
<c:forEach var="c" items="${requestScope.list }" varStatus="status">
<tr class="${status.count%2==0?'even':'odd' }">
<td>${c.name }</td>
<td>${c.gender }</td>
<td>${c.birthday }</td> <!-- birthday是Date类型的对象,虽然取出来的是Date类型的对象,但el表达式非常聪明,它会自动调用此对象的toString()方法,将其变成一个字符串,并且它内部会根据你到底是哪个国家和地区而去选用相对应的toString()方法 -->
<td>${c.cellphone }</td>
<td>${c.email }</td>
<td>${c.preference }</td>
<td>${c.type }</td>
<td>${c.description }</td>
<td>
<a href="#">修改</a>
<a href="#">删除</a>
</td>
</tr>
</c:forEach>
</table>
<br/>
</body>
</html>
在listcustomer.jsp页面中,我们使用<c:foreach>
实现表格间色显示。
测试开发好的查看客户功能。
至此,查看客户功能完成了一小半,还有很多细节没实现。
问题:有些客户的爱好和备注里面的内容会很多,这样显示出来并不好,所以必须截取几个字符,后面加上......
来显示,这样才会好一些。现在我们有这样的需求,那该怎么办呢?
答:先去EL函数库里面寻找有没有实现这一需求的函数,结果是发现并没有这样的函数,所以我们可以开发自定义函数,以调用Java类的方法。
-
在cn.bjyy.utils包中编写MyEL类,如下:
在MyEL类里编写一个静态处理方法——若一个字符串的长度大于10,则截取其前10个字符,后面加上......
并返回。public class MyEL { public static String sub(String str) { if (str.length()>10) { return str.substring(0, 10)+"......"; } return str; } }
-
在WEB-INF目录下编写标签库描述符(tld)文件,在tld文件中描述自定义函数。
bjyy.tld的代码如下:<?xml version="1.0" encoding="UTF-8" ?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0"> <description>JSTL 1.1 functions library</description> <display-name>JSTL functions</display-name> <tlib-version>1.1</tlib-version> <short-name>fn</short-name> <uri>/bjyy</uri> <function> <name>sub</name> <function-class> cn.bjyy.utils.MyEL</function-class> <function-signature>java.lang.String sub(java.lang.String)</function-signature> </function> </taglib>
-
在listcustomer.jsp页面中导入和使用自定义函数。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="/bjyy" prefix="bjyy" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>列出所有客户</title> <style type="text/css"> .even {background-color: #FFF000} .odd {background-color: #FFCCFF} tr:HOVER {background-color: #FF99FF} /* 注意需要更高版本的文档声明 */ </style> </head> <body style="text-align: center;"> <table frame="border" width="85%"> <tr> <td>客户姓名</td> <td>性别</td> <td>生日</td> <td>手机</td> <td>邮箱</td> <td>爱好</td> <td>类型</td> <td>备注</td> <td>操作</td> </tr> <c:forEach var="c" items="${requestScope.list }" varStatus="status"> <tr class="${status.count%2==0?'even':'odd' }"> <td>${c.name }</td> <td>${c.gender }</td> <td>${c.birthday }</td> <!-- birthday是Date类型的对象,虽然取出来的是Date类型的对象,但el表达式非常聪明,它会自动调用此对象的toString()方法,将其变成一个字符串,并且它内部会根据你到底是哪个国家和地区而去选用相对应的toString()方法 --> <td>${c.cellphone }</td> <td>${c.email }</td> <td>${bjyy:sub(c.preference) }</td> <td>${c.type }</td> <td>${bjyy:sub(c.description) }</td> <td> <a href="#">修改</a> <a href="#">删除</a> </td> </tr> </c:forEach> </table> <br/> </body> </html>
再次测试开发好的查看客户功能。
现在又产生一个问题,那就是如果数据库表里面有一千万条客户记录,那不是一个页面就要显示一千万条客户信息,这样做显然是非常愚蠢的,所以我们就要实现分页显示。为了减少篇章实现分页显示将在下一篇博客里面详细介绍。
开发修改客户的功能
将listcustomer.jsp页面中操作那一栏中的修改超链接,由
<a href="#">修改</a>
修改为:
<a href="${pageContext.request.contextPath }/EditCustomerServlet?id=${c.id }">修改</a>
同开发添加客户的功能一样,我们也只须编写一个Servlet,doGet方法用来给用户提供一个修改客户界面,doPost方法用来接收表单的修改客户请求(post),并处理用户的修改请求。
接下来就在cn.itcast.web.controller包中创建一个Servlet,该Servlet既用来给用户提供一个修改客户界面,又用来接收表单的修改客户请求(post),并处理用户的修改请求。
但现在我们只编写Servlet用来给用户提供一个修改客户界面的代码。
package cn.bjyy.controller;
import cn.bjyy.domain.Customer;
import cn.bjyy.service.impl.BusinessServiceImpl;
import cn.bjyy.utils.Globals;
import cn.bjyy.utils.WebUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Created by YYBJ on 2018/10/9.
* ZCL
*/
public class EditCustomerServlet extends HttpServlet {
//根据Id获取要修改的客户信息
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String id = req.getParameter("id");
BusinessServiceImpl service = new BusinessServiceImpl();
Customer customer = service.findCustomer(id);
req.setAttribute("genders", Globals.genders);
req.setAttribute("preferences",Globals.preferences);
req.setAttribute("types",Globals.types);
req.setAttribute("c",customer);
req.getRequestDispatcher("/WEB-INF/jsp/editcustomer.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
try {
Customer customer = WebUtils.request2Bean(req, Customer.class);
BusinessServiceImpl service = new BusinessServiceImpl();
service.updateCustomer(customer);
req.setAttribute("message","更新成功!!!");
}catch (Exception e){
e.printStackTrace();
req.setAttribute("message","更新失败!!!");
}
req.getRequestDispatcher("/message.jsp").forward(req,resp);
}
}
下面我们就来编写修改客户界面(editcustomer.jsp),修改客户界面(editcustomer.jsp)和添加客户界面(addcustomer.jsp)非常非常相似,所不同的是增加了数据回显功能。editcustomer.jsp页面的代码为:
<%--
Created by IntelliJ IDEA.
User: YYBJ
Date: 2018/10/9
Time: 10:05
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="${pageContext.request.contextPath }/layDate-v5.0.9/laydate/laydate.js"></script>
<link rel="stylesheet" href="/layDate-v5.0.9/laydate/theme/default/laydate.css">
<title>修改客户信息</title>
<script type="text/javascript">
</script>
</head>
<body style="text-align: center;">
<br>
<form id="form" action="/EditCustomerServlet" method="post" onsubmit="return makepre()">
<table border="1" width="50%" align="center">
<input type="hidden" name="id" value="${c.id }">
<tr>
<td>客户姓名</td>
<td>
<input type="text" name="name" value="${c.name }">
</td>
</tr>
<tr>
<td>客户性别</td>
<td>
<!--
页面到底输出几个性别,不是在页面中显示的,而是由一个程序维护的,这个程序有几个性别,页面中就输出几个性别
<input type="radio" name="gender" value="男">男
<input type="radio" name="gender" value="女">女
-->
<c:forEach var="gender" items="${genders }">
<input type="radio" name="gender" value="${gender }" ${c.gender==gender?'checked':'' }>${gender }
</c:forEach>
</td>
</tr>
<tr>
<td>生日</td>
<td>
<input type="text" name="birthday" id="birthday" value="${c.birthday }">
</td>
</tr>
<tr>
<td>手机</td>
<td>
<input type="text" name="cellphone" value="${c.cellphone }">
</td>
</tr>
<tr>
<td>邮箱</td>
<td>
<input type="text" name="email" value="${c.email }">
</td>
</tr>
<tr>
<td>爱好</td>
<td>
<c:forEach var="p" items="${preferences }">
<input type="checkbox" name="pre" value="${p }" ${fn:contains(c.preference,p)?'checked':'' }>${p }
</c:forEach>
</td>
</tr>
<tr>
<td>客户类型</td>
<td> <!-- c.type='VIP客户' -->
<c:forEach var="type" items="${types }">
<input type="radio" name="type" value="${type }" ${c.type==type?'checked':'' }>${type }
</c:forEach>
</td>
</tr>
<tr>
<td>客户备注</td>
<td>
<textarea rows="5" cols="60" name="description">${c.description }</textarea>
</td>
</tr>
<tr>
<td>
<input type="reset" value="重置">
</td>
<td>
<input type="submit" value="修改客户">
</td>
</tr>
</table>
</form>
</body>
<script type="text/javascript">
laydate.render({
elem: document.getElementById("birthday") //指定元素
});
function makepre() {
var pres = document.getElementsByName("pre");
var preference = "";
for(var i=0;i<pres.length;i++) {
var input = pres[i];
if(input.checked==true) {
preference = preference + input.value + ","; // preference="唱歌,跳舞,夜生活";
}
}
preference = preference.substring(0, preference.length-1);
var form = document.getElementById("form");
var input = document.createElement("input");
input.type = "hidden";
input.name = "preference";
input.value = preference;
form.appendChild(input);
return true;
}
</script>
</html>
测试开发好的修改客户功能。点击修改页面出现回显数据这样才是比较规范的修改:
到此,开发修改客户的功能算是圆满完成。
开发删除客户的功能
将listcustomer.jsp页面中操作那一栏中的删除超链接,由
<a href="#">删除</a>
修改为:
<a href="javascript:void(0)" onclick="del('${c.id}')">删除</a>
注意:有时候javascript函数获取不到传递过来的参数,可将传递过来的参数加上单引号(''
)。
当点击删除超链接时,肯定要给人一个提示,例如弹出一个对话框,告诉人家是否要确定删除吗?不然的话,这个代码就是一个垃圾!
所以应在listcustomer.jsp页面中添加如下javascript代码:
function del(id) {
if (window.confirm("您确定删除吗???")) {
location.href = '${pageContext.request.contextPath }/DelCustomerServlet?id='+id;
}
}
这样最终listcustomer.jsp页面的代码为:注意这个页面包含了分页功能显示的。分页下回介绍:
<%--
Created by IntelliJ IDEA.
User: YYBJ
Date: 2018/10/8
Time: 17:28
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="/bjyy" prefix="bjyy" %>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<head>
<title>列出所有客服</title>
</head>
<style type="text/css">
.even {background-color: #FFF000}
.odd {background-color: #FFCCFF}
tr:HOVER {background-color: #FF99FF} /* 注意需要更高版本的文档声明 */
</style>
<body style="text-align: center;">
<table frame="border" width="85%">
<tr>
<td>客户姓名</td>
<td>性别</td>
<td>生日</td>
<td>手机</td>
<td>邮箱</td>
<td>爱好</td>
<td>类型</td>
<td>备注</td>
<td>操作</td>
</tr>
<%----%>
<c:forEach var="c" items="${requestScope.pagebean.list }" varStatus="status">
<tr class="${status.count%2==0?'even':'odd' }">
<td>${c.name }</td>
<td>${c.gender }</td>
<td>${c.birthday }</td> <!-- birthday是Date类型的对象,虽然取出来的是Date类型的对象,但el表达式非常聪明,它会自动调用此对象的toString()方法,将其变成一个字符串,并且它内部会根据你到底是哪个国家和地区而去选用相对应的toString()方法 -->
<td>${c.cellphone }</td>
<td>${c.email }</td>
<td>${bjyy:sub(c.preference ) }</td>
<td>${c.type }</td>
<td>${bjyy:sub(c.description ) }</td>
<td>
<a href="${pageContext.request.contextPath }/EditCustomerServlet?id=${c.id }">修改</a>
<a href="javascript:void(0)" onclick="del('${c.id}')">删除</a> <!-- 注意:有时候javascript函数获取不到传递过来的参数,可将传递过来的参数加上单引号('') -->
</td>
</tr>
</c:forEach>
</table>
<br/>
<script type="text/javascript">
function del(id) {
if (window.confirm("您确定删除吗???")) {
location.href = '${pageContext.request.contextPath }/DelCustomerServlet?id='+id;
}
}
function gotopage(currentpage) {
if ( currentpage < 1 || currentpage != parseInt(currentpage) || currentpage > ${pagebean.totalpage } ) {
alert("请输入有效值!!!");
document.getElementById("pagenum").value='';
} else {
var pagesize = document.getElementById("pagesize").value;
window.location.href = '${pageContext.request.contextPath }/ListCustomerServlet?currentpage='+currentpage+'&pagesize='+pagesize;
}
}
function changesize(pagesize, oldvalue) {
if ( pagesize < 0 || pagesize != parseInt(pagesize) ) {
alert("请输入合法值!!!");
document.getElementById("pagesize").value = oldvalue;
} else {
window.location.href = '${pageContext.request.contextPath }/ListCustomerServlet?pagesize='+pagesize; // 当前页currentpage就不传过去了,也即一改变页面大小,由于没带当前页过去,所以就从第1页开始显示
}
}
</script>
共[${pagebean.totalrecord }]条记录,
<%-- 每页显示<input type="text" id="pagesize" value="${pagebean.pagesize }" onchange="gotopage(${pagebean.currentpage })" style="width:30px" maxlength="2">条, --%>
每页显示<input type="text" id="pagesize" value="${pagebean.pagesize }" onchange="changesize(this.value,${pagebean.pagesize })" style="width:30px" maxlength="2">条,
共[${pagebean.totalpage }]页,
当前第[${pagebean.currentpage }]页
<!--
<a href="${pageContext.request.contextPath }/ListCustomerServlet?currentpage=${pagebean.previouspage }">上一页</a>
<c:forEach var="pagenum" items="${pagebean.pagebar }">
<a href="${pageContext.request.contextPath }/ListCustomerServlet?currentpage=${pagenum }">${pagenum }</a>
</c:forEach>
<a href="${pageContext.request.contextPath }/ListCustomerServlet?currentpage=${pagebean.nextpage }">下一页</a>
-->
<c:if test="${pagebean.currentpage!=1 }">
<a href="javascript:void(0)" onclick="gotopage(${pagebean.previouspage })">上一页</a>
</c:if>
<c:forEach var="pagenum" items="${pagebean.pagebar }">
<c:if test="${pagenum==pagebean.currentpage }">
<font color="red">${pagenum }</font>
</c:if>
<c:if test="${pagenum!=pagebean.currentpage }">
<a href="javascript:void(0)" onclick="gotopage(${pagenum })">${pagenum }</a>
</c:if>
</c:forEach>
<c:if test="${pagebean.currentpage!=pagebean.totalpage }">
<a href="javascript:void(0)" onclick="gotopage(${pagebean.nextpage })">下一页</a>
</c:if>
<input type="text" id="pagenum" style="width: 30px">
<input type="button" value="GO" onclick="gotopage(document.getElementById('pagenum').value)">
</body>
</html>
然后我们在cn.bjyy.controller包中创建一个Servlet——DelCustomerServlet,用于处理删除客户请求。
DelCustomerServlet类的具体代码如下:
package cn.bjyy.controller;
import cn.bjyy.service.impl.BusinessServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Created by YYBJ on 2018/10/9.
* ZCL
*/
public class DelCustomerServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
String id = req.getParameter("id");
BusinessServiceImpl service = new BusinessServiceImpl();
service.deleteCustomer(id);
req.setAttribute("message","删除成功!!!");
}catch (Exception e){
e.printStackTrace();
req.setAttribute("message","删除失败!!!");
}
req.getRequestDispatcher("/message.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req,resp);
}
}
开发删除客户的功能也完成了最终增删改查所有功能结束。
对于出现的问题可以留言:
附上源码地址:https://download.****.net/download/weixin_41092717/10710873
版权声明:本文为博主原创文章,转载请说明转载来源:https://blog.****.net/weixin_41092717/article/details/82992401