数据库_jdbc_分页案例

CustomerDao位于dao

package cn.itcast.dao;
import java.util.List;
import cn.itcast.domain.Customer;
import cn.itcast.domain.QueryResult;
public interface CustomerDao {
  //方法1:添加一个Customer到数据库,返回值为void
  void add(Customer c);
  //方法2:更新一个Customer到数据库,返回值为void
  void update(Customer c);
  //方法3:删除一个Customer从数据库,返回值为void
  void delete(Customer c);
  //方法4:通过id查询并返回一个封装好数据的Customer
  Customer find(String id);
  //方法5:返回一个封装了所有Customer的集合
  List<Customer> getAll();
  //方法6:两条SQL,先从数据库第N条开始查询M条记录,参数(N,M),
  //再统计总的记录数,封装到QueryResult对象并返回!
  public QueryResult pageQuery(int startIndex,int pageSize);
}


CustomerDaoImpl位于dao.impl

package cn.itcast.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import cn.itcast.dao.CustomerDao;
import cn.itcast.domain.Customer;
import cn.itcast.domain.QueryResult;
import cn.itcast.exception.DaoException;
import cn.itcast.utils.JdbcUtils;
public class CustomerDaoImpl implements CustomerDao {
  //方法1:添加一个Customer到数据库,返回值为void
  public void add(Customer c){
      Connection conn=null;
      PreparedStatement st=null;
      ResultSet rs=null;
      try {
        conn=JdbcUtils.getConnection();
        //先准备String sql,再通过连接准备PreparedStatement
        String fields="id,name,gender,birthday,cellphone,email,preference,type,description";
        String sql="insert into customer("+fields+") values(?,?,?,?,?,?,?,?,?)";
        st=conn.prepareStatement(sql);
        st.setString(1, c.getId());
        st.setString(2, c.getName());
        st.setString(3, c.getGender());
        //特别注意,setDate需要一个子类sql.Date
        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) {
        //自定义Dao异常,是为了方便定义错误出在哪一层!
        throw new DaoException();
    }finally{
      JdbcUtils.release(conn, st, rs);
    }
  }
  //方法2:更新一个Customer到数据库,返回值为void
  public void update(Customer c){
    Connection conn=null;
      PreparedStatement st=null;
      ResultSet rs=null;
      try {
        conn=JdbcUtils.getConnection();
        //先准备String sql,再通过连接准备PreparedStatement
        String fields="name=?,gender=?,birthday=?,cellphone=?,email=?,preference=?,type=?,description=?";
        String sql="update customer set "+fields+" where id=?";
        st=conn.prepareStatement(sql);
        st.setString(1, c.getName());
        st.setString(2, c.getGender());
        //特别注意,setDate需要一个子类sql.Date
        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();
    }finally{
      JdbcUtils.release(conn, st, rs);
    }
  }
  //方法3:删除一个Customer从数据库,返回值为void
  public void delete(Customer c){
    Connection conn=null;
      PreparedStatement st=null;
      ResultSet rs=null;
      try {
        conn=JdbcUtils.getConnection();
        //先准备String sql,再通过连接准备PreparedStatement
        String sql="delete from customer where id=?";
        st=conn.prepareStatement(sql);
        st.setString(1, c.getId());
        st.executeUpdate();
      }catch (Exception e) {
        throw new DaoException();
    }finally{
      JdbcUtils.release(conn, st, rs);
    }
  }
  //方法4:通过id查询并返回一个封装好数据的Customer
  public Customer find(String id){
    Connection conn=null;
      PreparedStatement st=null;
      ResultSet rs=null;
      try {
        conn=JdbcUtils.getConnection();
        //先准备String sql,再通过连接准备PreparedStatement
        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.setId(rs.getString("id"));
        c.setName(rs.getString("name"));
        c.setGender(rs.getString("gender"));
        //形参是个父类util.Date,传参是个子类sql.Date,多态!
        c.setBirthday(rs.getDate("birthday"));
        c.setCellphone(rs.getString("cellphone"));
        c.setEmail(rs.getString("email"));
        c.setPreference(rs.getString("preference"));
        c.setType(rs.getString("type"));
        c.setDescription(rs.getString("description"));
        return c;
        }
        return null;
      }catch (Exception e) {
        throw new DaoException();
    }finally{
      JdbcUtils.release(conn, st, rs);
    }
  }
  //方法5:返回一个封装了所有Customer的集合
  public List<Customer> getAll(){
      Connection conn=null;
      PreparedStatement st=null;
      ResultSet rs=null;
      try {
        conn=JdbcUtils.getConnection();
        //先准备String sql,再通过连接准备PreparedStatement
        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.setId(rs.getString("id"));
        c.setName(rs.getString("name"));
        c.setGender(rs.getString("gender"));
        //形参是个父类util.Date,传参是个子类sql.Date,多态!
        c.setBirthday(rs.getDate("birthday"));
        c.setCellphone(rs.getString("cellphone"));
        c.setEmail(rs.getString("email"));
        c.setPreference(rs.getString("preference"));
        c.setType(rs.getString("type"));
        c.setDescription(rs.getString("description"));
        list.add(c);
       }
        return list;
      }catch (Exception e) {
        throw new DaoException();
    }finally{
      JdbcUtils.release(conn, st, rs);
    }
  }
  //方法6:两条SQL,先从数据库第N条开始查询M条记录,参数(N,M),先装list
  //再统计总的记录数,两个SQL语句的结果都封装到QueryResult对象并返回!
  public QueryResult pageQuery(int startIndex,int pageSize){
    //SQL查询模板代码(sql_s)
    Connection conn = null;
    PreparedStatement st = null;
    ResultSet rs = null;
    QueryResult qr = null;
    try {
      conn = JdbcUtils.getConnection();
      //第1个?索引从条记录开始,第2个?代表取多少条记录
      String sql = "select * from customer limit ?,?";
      st = conn.prepareStatement(sql);
      st.setInt(1, startIndex);
      st.setInt(2, pageSize);
      rs = st.executeQuery();
      //将第1句SQL查询结果封装到list,再将集合添加到QueryResult(结果对象)
       List<Customer> list=new ArrayList<Customer>();
      while (rs.next()) {
        Customer c=new Customer();
        c.setId(rs.getString("id"));
        c.setName(rs.getString("name"));
        c.setGender(rs.getString("gender"));
        //形参是个父类util.Date,传参是个子类sql.Date,多态!
        c.setBirthday(rs.getDate("birthday"));
        c.setCellphone(rs.getString("cellphone"));
        c.setEmail(rs.getString("email"));
        c.setPreference(rs.getString("preference"));
        c.setType(rs.getString("type"));
        c.setDescription(rs.getString("description"));
        list.add(c);
      }
      //再将list添加到QueryResult(结果对象)
      qr=new QueryResult();
      qr.setList(list);  
      //执行第2条sql,将总记录数,封装到QueryResult
      sql="select count(*) from customer";
      st=conn.prepareStatement(sql);
      rs=st.executeQuery();
      //因只有一列,所以用if
      if (rs.next()) {
        //总记录数 封装到QueryResult(结果对象)
        qr.setTotalRecord(rs.getInt(1));//注意是int类型
        //也可以使用列名rs.getInt("count(*)");
        //qr.setTotalRecord(rs.getInt("count(*)"));
      }
      //返回封装好所有数据(list,总记录数目)的QueryResult(结果对象)
      return qr;      
    } catch (Exception e) {
      throw new DaoException(e);
    } finally {
      JdbcUtils.release(conn, st, rs);
    }
  }
}
/*JDBCIMPL模板代码!
      Connection conn=null;
      PreparedStatement st=null;
      ResultSet rs=null;
      try {
        conn=JdbcUtils.getConnection();
        //先准备String sql,再通过连接准备PreparedStatement
        String sql="?";
        st=conn.prepareStatement(sql);
        st.setString(1, "");
        int num=st.executeUpdate();
        rs=st.executeQuery();
      }catch (Exception e) {
        throw new DaoException();
    }finally{
      JdbcUtils.release(conn, st, rs);
    }
*/


Customer位于domain

package cn.itcast.domain;
import java.util.Date;
public class Customer {
  //成员要与表中字段一致,并生成Getter Setter方法
  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;
  }
}


PageBean位于domain

package cn.itcast.domain;

import java.util.List;
/*PageBean是重点,也是难点!
PageBean封装页面需要显示的所有信息,
包括查询条件(QueryInfo的两个成员)和查询的结果(QueryResult的两个成员),
以及根据算法生成的4个成员*/
public class PageBean {
  private List list;//QueryResult的成员,封装select limit 得到的记录
  private int totalRecord;//QueryResult的成员,封装select count(*) 得到的库里客户总数!
  private int pageSize;//QueryInfo的成员,封装每页显示条数
  private int currentPage;//QueryInfo的成员,封装当前页码数
  //下面4个成员无setter,因是算法生成
  private int totalPage;//算法生成(totalRecord,pageSize)!
  private int previousPage;//算法生成(分析currentPage<2)!
  private int nextPage;//算法生成(分析currentPage+1>=totalPage)!
  private int[] pageBar;//难点!算法生成,固定显示10个页码(需分析totalPage,currentPage)
  //实现算法,并生成相应的getter方法!
  public int getTotalPage() {
    //两种算法,首先是简单的,逻辑清晰!
    //共100条   每页显示5    需20页
    //共101条   每页显示5    需21页
    //共99条    每页显示5    还是需20页
    int mod=totalRecord%pageSize;//余数
    if (mod==0) {
      //如果余数为0,即整除,则总页数刚好是A/B
      totalPage=totalRecord/pageSize;
    } else {
      //否则,总页数是A/B+1;
      totalPage=totalRecord/pageSize+1;
    }
    /*第2种算法:
    totalPage = (totalRecord+(pageSize-1))/pageSize;    
     */
    return totalPage;
  }
  public int getPreviousPage() {
    //返回当前页码的上一页,注意特殊情况即可!
    //算法生成(分析currentPage<2)!
    if (currentPage<2) {
      previousPage=1;
    } else {
      previousPage=currentPage-1;
    }
    return previousPage;
  }
  public int getNextPage() {
    //返回当前页码的下一页,注意特殊情况即可!
    //算法生成(分析currentPage+1>=totalPage)!
    if (currentPage+1>=totalPage) {
      nextPage=totalPage;
    } else {
      nextPage=currentPage+1;
    }
    return nextPage;
  }
  public int[] getPageBar() {
  /*算法生成,固定显示10页(需根据totalpage,currentpage分析)
  特殊情况下:即总的页码数不足10条,那么起始就为1,结束页为总页数
  默认情况下:起始页为当前页减4(比如15-4=11)
         结束页为当前页加5(比如15+5=20)
         显示的页码条就是11,12,...19,20
  默认情况又有两种特殊情况:
       1,当前页减4之后的起始页,如果<1,那么起始页为1,结束页为10
       2,当前页加5之后的结束页,如果>总页数,
         那么结束页为总页数,起始页为总页数减9*/  
    int start;
    int end;
    int pb[] = null;
    if(totalPage<=10){
      pb = new int[totalPage];
      start = 1;
      end = totalPage;
    }else{
      pb = new int[10];
      start = currentPage - 4;
      end = currentPage + 5;
      //总页数=30      当前第3页    3-4=-1    1    10
      //总页数=30      当前第29页   29+5=34   21   30
      if(start<1){
        start = 1;
        end = 10;
      }
      if(end>totalPage){
        start = totalPage - 9;
        end = totalPage;        
      }
    }
    //接着再将起始页和结束页一一填充到pageBar数组里,用于页面显示
    int index = 0;
    for(int i=start;i<=end;i++){
      pb[index++] = i;
    }
    this.pageBar = pb;
    return pageBar;
    /*简单方案:将总页数全显示成pagebar[]
    int pb[] = new int[totalPage];
    for(int i=1;i<=totalPage;i++){
      //第1个数组元素,下标为0,值为1;
      pb[i-1] = i;
    }
    this.pageBar = pb;
    return pageBar;
    */
  }
  //生成相应的getter和setter
  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 getCurrentPage() {
    return currentPage;
  }
  public void setCurrentPage(int currentPage) {
    this.currentPage = currentPage;
  }
}


QueryInfo位于domain

package cn.itcast.domain;
//QueryInfo对象封装的是jsp发给servlet的2个请求参数!
public class QueryInfo {
  //注意用户第一次是没有带查询参数过来!要设置默认值!
  private int currentPage=1; //当前页
  private int pageSize=5;//页面大小,即每页显示记录数目
  private int startIndex;//select * from 表名 limit X,Y; 的第1个参数,
  //即查数据库时的起始位置,算法生成(当前页,页面大小)  
  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() {
    //查数据库时的起始位置,算法生成,无setter!
    //select * from 表名 limit 起始位置,记录数;
    startIndex=(currentPage-1)*pageSize;
    //比如第1页,从0开始,显示五条
    //第2页,从5开始,显示五条
    return startIndex;
  }
}


QueryResult位于domain

package cn.itcast.domain;
import java.util.List;
//QueryResult对象封装的是两条SQL语句的查询结果!
public class QueryResult {
  private List list;//保存select * from 表名 limit 起始位置,记录数;
  private int totalRecord;//保存客户总数select count(*) from 表名;
  //分别生成getter setter方法!
  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;
  }
}


DaoException位于exception

package cn.itcast.exception;
public class DaoException extends RuntimeException {
	//1,自定义异常是为了方便查找错误发生在哪一层
	//2,继承运行时异常,是避免给上层带麻烦
  public DaoException() {
  }
  public DaoException(String message) {
    super(message);
  }
  public DaoException(Throwable cause) {
    super(cause);
  }
  public DaoException(String message, Throwable cause) {
    super(message, cause);
  }
  public DaoException(String message, Throwable cause,
      boolean enableSuppression, boolean writableStackTrace) {
    super(message, cause, enableSuppression, writableStackTrace);
  }
}


DaoFactory位于factory

package cn.itcast.factory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class DaoFactory {
/*
 * 1,工厂设计成单例
 * 2,读取src类目录下的dao.properties配置文件
 * 3,参数为键,通过值返回接口的实现类!*/
  private static Properties pro=new Properties();
  //单例第1步,构造函数私有化,仅运行一次
  private DaoFactory(){
    //dao.properties配置文件仅加载1次就欧了
    String pro_name="dao.properties";
    InputStream in=DaoFactory.class.getClassLoader().getResourceAsStream(pro_name);
    try {
      pro.load(in);
    } catch (IOException e) {
      //转型后抛出
      throw new RuntimeException(e);
    }
  }
  //单例第2步,自己创个实例
  private static DaoFactory instance=new DaoFactory();
  //单例第3步,对外提供公开方法
  public static DaoFactory getInstance(){
    return instance;
  }
  //重点!泛型!根据参数(接口名),创建出该接口的实现类的实例对象!
  public <T> T createDao(Class<T> clazz){
    //配置文件中CustomerDao=cn.itcast.dao.impl.CustomerDaoImpl
    //String full_name=clazz.getName();//cn.itcast.dao.CustomerDao
    String simple_name=clazz.getSimpleName();//CustomerDao
    //simple_name即为dao.properties配置文件键名,值impl_name就是实现类的完整名字
    String impl_name=pro.getProperty(simple_name);
    try {
      T dao=(T) Class.forName(impl_name).newInstance();
      //相当于new cn.itcast.dao.impl.CustomerDaoImpl()
      return dao;
    } catch (Exception e) {
      // 转型后抛出
      throw new RuntimeException(e);
    }
  }
}


FormBean位于formbean

package cn.itcast.formbean;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
public class FormBean {
  /*用一个FormBean类封装表单提交过来的数据
   * 表单提交过来全是String */
    private String name;
    private String gender;
    private String birthday;
    private String cellphone;
    private String email;
    private String preference;
    private String type;
    private String description;
  // Map errors  保存所有校验不通过的错误消息
    private Map errors = new HashMap();
    public boolean validate(){
      //默认是真,只要有一个错误,flag为假
      boolean flag = true;
      //1,名字不能为空,只能是2-10位字母 或汉字区间(\u4e00-\u9fa5)
      if(name==null || name.trim().equals("")){
        flag = false;
        errors.put("name", "名字不能为空!");
      }else if(!name.matches("^([\u4e00-\u9fa5]{2,10})$") && !name.matches("[A-Za-z]{2,10}")){
        //既不是中文也不是英文,则为假
          flag = false;
          errors.put("name", "名字必须是2-10位中文或英文!");
      }
      /*2,生日可以为空,不为空时,必须要是一个日期
       * 不能用SimpleDateFormat因为12月32日会转成第2年的
       * 而是用BeanUtils里面的DateLocaleConverter
       * 日期错误转不了,就会抛异常!*/
      if(this.birthday!=null && !this.birthday.trim().equals("")){
        try{
          DateLocaleConverter conv= new DateLocaleConverter();
          conv.convert(this.birthday, "yyyy-MM-dd");
        }catch (Exception e) {
          //日期错误转不了,就会抛异常
          flag = false;
          errors.put("birthday", "日期格式不对!");
        }
      }
    //3,手机可以为空,否则必需是7-11位数字
        if(!this.cellphone.matches("\\d{7,11}") && cellphone!=null && !cellphone.trim().equals("")){
          flag = false;
          errors.put("cellphone", "手机号码为7-11位数字!");
        }
      //4,电子邮箱不能为空,并且要是一个格式合法的邮箱
      if(this.email==null || this.email.trim().equals("")){
          flag = false;
          errors.put("email", "邮箱不能为空!");
        }else{
          if(!this.email.matches("\\w+@\\w+(\\.\\w+)+")){
            flag = false;
            errors.put("email", "邮箱格式错误!");
          }
        }
      return flag;
    }
    //如果要在jsp中用EL${}千万要记得生成 getter and setter方法
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getGender() {
    return gender;
  }
  public void setGender(String gender) {
    this.gender = gender;
  }
  public String getBirthday() {
    return birthday;
  }
  public void setBirthday(String 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;
  }
  public Map getErrors() {
    return errors;
  }
  public void setErrors(Map errors) {
    this.errors = errors;
  }
    
    
}


BusinessService位于service

package cn.itcast.service;
import java.util.List;
import cn.itcast.domain.Customer;
import cn.itcast.domain.PageBean;
import cn.itcast.domain.QueryInfo;
public interface BusinessService {
  //方法1:添加一个Customer到数据库,返回值为void
  void add(Customer c);
  //方法2:更新一个Customer到数据库,返回值为void
  void update(Customer c);
  //方法3:删除一个Customer从数据库,返回值为void
  void delete(Customer c);
  //方法4:通过id查询并返回一个封装好数据的Customer
  Customer find(String id);
  //方法5:返回一个封装了所有Customer的集合
  List<Customer> getAll();
  //方法6:同dao的方法名一样!因为薄薄的业务层全是调用dao的方法!
  //封装好QueryInfo和PageBean里的数据,返回PageBean 以供jsp显示
  public PageBean pageQuery(QueryInfo info);
}


BusinessServiceImpl位于service.impl

package cn.itcast.service.impl;
import java.util.List;
import cn.itcast.dao.CustomerDao;
import cn.itcast.dao.impl.CustomerDaoImpl;
import cn.itcast.domain.Customer;
import cn.itcast.domain.PageBean;
import cn.itcast.domain.QueryInfo;
import cn.itcast.domain.QueryResult;
import cn.itcast.factory.DaoFactory;
import cn.itcast.service.BusinessService;
public class BusinessServiceImpl implements BusinessService {
  /*对web层提供所有的服务,
   * web层收到请求后,统一交给BusinessServiceImpl处理
   * BusinessServiceImpl实际上是交给CustomDao处理
   * 薄薄的业务层!
   * 如果要实现与Dao层完全解耦,则可以使用工厂模式
   * 1,建一个factory包,建一个DaoFactory类(单例)
   * 2,src下建一个dao.properties配置文件,
   * 键为CustomerDao,值为cn.itcast.dao.impl.CustomerDaoImpl
   * 3,DaoFactory类使用泛型方法,参数为CustomerDao接口的字节码名
   * 返回一个dao.properties配置文件中该接口对应的实现类的实例,并返回!
   * 4,在BusinessServiceImpl的成员变量调用上述方法得到CustomerDao*/
  //private CustomerDao dao=new CustomerDaoImpl();
  private CustomerDao dao=DaoFactory.getInstance().createDao(CustomerDao.class);
  //方法1:添加一个Customer到数据库,返回值为void
  public void add(Customer c){
    dao.add(c);
  }
  //方法2:更新一个Customer到数据库,返回值为void
  public void update(Customer c){
    dao.update(c);
  }
  //方法3:删除一个Customer从数据库,返回值为void
  public void delete(Customer c){
    dao.delete(c);
  }
  //方法4:通过id查询并返回一个封装好数据的Customer
  public Customer find(String id){
    return dao.find(id);
  }
  //方法5:返回一个封装了所有Customer的集合
  public List<Customer> getAll(){
    return dao.getAll();
  }
  //方法6:同dao的方法名一样!因为薄薄的业务层全是调用dao的方法!
  //封装好QueryInfo和PageBean里的数据,返回PageBean 以供jsp显示
  public PageBean pageQuery(QueryInfo info){
    int startIndex=info.getStartIndex();
    int pageSize=info.getPageSize();
    //调用dao获取页面查询的结果对象
    QueryResult qr=dao.pageQuery(startIndex, pageSize);
    //装备好PageBean,封装所有数据(包括QueryInfo对象和QueryResult),供jsp页面显示!
    PageBean bean=new PageBean();
    bean.setList(qr.getList());
    bean.setTotalRecord(qr.getTotalRecord());
    bean.setCurrentPage(info.getCurrentPage());
    bean.setPageSize(info.getPageSize());
    return bean;
  }
}


Global位于utils

package cn.itcast.utils;

public class Global {
  public static String genders[] = {"男","女"};
  public static String preferences[] = {"女红","绘画","诗词","对联","喝酒","玩乐","理政","理财"};
  public static String types[] = {"大丫鬟","小丫鬟","嬷嬷","少爷","姑娘","亲戚","老爷","花旦","尼姑"};  
}


JdbcUtils位于utils

package cn.itcast.utils;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JdbcUtils {
  private static Properties pro=new Properties();
  /*
   * 静态成员Properties
   * 静态代码块:加载配置文件,注册驱动
   * 静态方法1:获取连接
   * 静态方法2:释放连接
   * 工具类的异常只管抛,也可以转型后抛
   * db.properties文件位于类目录下即src
   */
  static{
    String pro_name="db.properties";
    InputStream in=JdbcUtils.class.getClassLoader().getResourceAsStream(pro_name);
    try {
      pro.load(in);
      Class.forName(pro.getProperty("driver"));
    } catch (Exception e) {
      // 静态代码块的异常只能转型后抛出
      throw new ExceptionInInitializerError(e);
    }
  }
  //方法1:获取连接
  public static Connection getConnection() throws SQLException{
    String url=pro.getProperty("url");
    String user=pro.getProperty("user");
    String password=pro.getProperty("password");
    Connection conn=DriverManager.getConnection(url, user, password);
    return conn;
  }
  //方法2:释放连接
  public static void release(Connection conn,Statement st,ResultSet rs){
    if (conn!=null) {
      try {
        conn.close();
      }catch (Exception e) {
        //只能记录!一旦抛出,后面的2条if代码就无法执行了
        e.printStackTrace();
      }
      conn=null;
    }
    if (st!=null) {
      try {
        st.close();
      }catch (Exception e) {
        //只能记录!一旦抛出,后面的1条if代码就无法执行了
        e.printStackTrace();
      }
      st=null;
    }
    if (rs!=null) {
      try {
        rs.close();
      }catch (Exception e) {
        e.printStackTrace();
      }
      rs=null;
    }
  }
}


MyEL位于utils

package cn.itcast.utils;
/*自定义EL函数,虽无法代替与web有关的java代码 
 * 1,静态方法
 * 2,tld文件描一把,抄Tomcat的tld抄头抄屁股
 * 3,jsp中taglib导入*/
public class MyEL {
  //我的EL函数库,方法1,取文本左边!
  public static String leftStr(String str,Integer len){
    if(str.trim().length()>len){
      return str.substring(0, len) + "......";
    }
    return str;
  }
}


WebUtils位于utils

package cn.itcast.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;

import sun.misc.BASE64Encoder;
import cn.itcast.formbean.FormBean;
public class WebUtils {
  //方法1说明:将表单数据封装到formbean中,供校验用!先不使用泛型
  public static FormBean request2FormBean(HttpServletRequest request,
      Class<FormBean> beanClass) {
    try{
      //1,创建bean对象实例,用来接收request中的数据!
      FormBean bean=beanClass.newInstance();
      //2,用BeanUtils的方法把request中的数据封装到bean对象中
      Enumeration  e = request.getParameterNames();//参数名列表
       while(e.hasMoreElements()){
              String name = (String) e.nextElement();   //name gender birthday等
              String value = request.getParameter(name); 
              //虽然只支持8种基本数据类型,但是FormBean里成员全是string!
              BeanUtils.setProperty(bean, name, value);
       }
      //3,返回封装了表单数据的FormBean对象
       return bean;
    }catch (Exception e) {
      // 转运行时异常后抛出
      throw new RuntimeException(e);
    }
  }
  //方法2说明:使用泛型 将表单数据封装到formbean中,供校验用!
  public static<T> T request2FormBean(HttpServletRequest request,
      Class<T> beanClass) {
    try{
      //1,创建bean对象实例,用来接收request中的数据!
      T bean=beanClass.newInstance();
      //2,用BeanUtils的方法把request中的数据封装到bean对象中
      Enumeration  e = request.getParameterNames();//参数名列表
      while(e.hasMoreElements()){
        String name = (String) e.nextElement();   //name gender birthday等
        String value = request.getParameter(name); 
        BeanUtils.setProperty(bean, name, value);
      }
      //3,返回封装了表单数据的FormBean对象
      return bean;
    }catch (Exception e) {
      // 转运行时异常后抛出
      throw new RuntimeException(e);
    }
  }
  //方法3说明:将FormBean中的数据(该类成员全是string)封装到domain包的Bean里面
    public static void copyBean(Object src,Object dest){
      //需要注册日期转换器
      //(将FormBean里的字符串转成Bean里的成员:Date日期)
      ConvertUtils.register(new Converter(){
        public Object convert(Class type, Object value) {
          /*方法说明:(将value转成type类型)
          *1,判断value是不是null
          *2,判断value是不是String
          *3,判断value是不是空白字符串
          *4,用SimpleDateFormat parse  
          *5,工具类异常统统往外抛      */
          if(value==null){
            return null;
          }
          String date=(String)value;
          if("".equals(date.trim())){
            return null;
          }
          //指定字符串的格式,转成Date对象
          SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd");
            try {
              return df.parse(date);
            } catch (Exception e) {
              throw new RuntimeException(e);
            }
        }
      }, Date.class);
      try {
        //使用BeanUtils的复制bean方法
        BeanUtils.copyProperties(dest, src);
      } catch (Exception e) {
        throw new RuntimeException(e);
      } 
    }
      //方法4, 直接将表单中的数据封装到domain包的Bean里面
    //使用字节码避免new 对象,使用泛形避免强转
    public static <T> T request2Bean(HttpServletRequest request,Class<T>  beanClass){
      try{
        //1,创建bean对象实例,用来接收request中的数据!
        T bean = beanClass.newInstance();
        //2,得到request里面所有提交的数据(键值对)
        Map map = request.getParameterMap();
        //map{name=aa,password=bb,birthday=1990-09-09}  bean(name=aa,password=dd,birthday=Date)    
        //3,需要注册日期转换器
        //(将表单里的字符串value转成Object即 Customer的成员:Date日期)      
        ConvertUtils.register(new Converter(){
          public Object convert(Class type, Object value) {
            if(value==null){
              return null;
            }
            String str = (String) value;
            if(str.trim().equals("")){
              return null;
            }  
            //指定字符串的格式,转成Date对象        
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            try {
              return df.parse(str);
            } catch (Exception e) {
              //异常不希望给上层带麻烦,就转型后再抛
              throw new RuntimeException(e);
            }
          }
        }, Date.class);
        //4,根据关键字,将map集合里面的数据填充到bean里(即Customer)
        //只支持8种基本数据类型
        BeanUtils.populate(bean, map);  
        //5,返回填充好请求参数的bean      
        return bean;
      }catch (Exception e) {
        throw new RuntimeException(e);
      }
    }
    //方法5, 产生一个唯一的id(UUID.randomUUID().toString())
    public static String generateId(){
      return UUID.randomUUID().toString();
    }
    //方法6,将字符串md5加密后返回!
    public static String md5(String message){
        /*ServiceUtils工具类异常直接抛,异常链不能断
         * 提供md5加密标准4步骤(生成图片验证码曾用到)*/
        try {
          MessageDigest md=MessageDigest.getInstance("md5");
          byte[] md5=md.digest(message.getBytes());
          BASE64Encoder encoder=new BASE64Encoder();
          return encoder.encode(md5);
        } catch (NoSuchAlgorithmException e) {
          throw new RuntimeException(e);
        }
      }
}


AddCustomerServlet位于web.controller

package cn.itcast.web.controller;

import java.io.IOException;

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

import cn.itcast.domain.Customer;
import cn.itcast.formbean.FormBean;
import cn.itcast.service.BusinessService;
import cn.itcast.service.impl.BusinessServiceImpl;
import cn.itcast.utils.Global;
import cn.itcast.utils.WebUtils;

public class AddCustomerServlet extends HttpServlet {

  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    /*点击超链接:给用户提供一个添加界面
     * 1,先将Global的静态成员(可能变化的数据)存到request域内
     * 2,转发到WEB-INF/jsp/addcustomer.jsp*/
    request.setAttribute("genders", Global.genders);
    request.setAttribute("preferences", Global.preferences);
    request.setAttribute("types", Global.types);    
    request.getRequestDispatcher("/WEB-INF/jsp/addcustomer.jsp").forward(request, response);
  }
  //处理表单提交的添加客户请求
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    try {
      //1,处理乱码问题
      request.setCharacterEncoding("utf-8");
      //2,把表单数据封装到FormBean对象,对提交表单的字段进行validate校验
      FormBean form=WebUtils.request2FormBean(request, FormBean.class);
      boolean b=form.validate();
      //2.1 如果校验失败,跳回到表单页面,回显校验失败信息
        if(!b){
          //因为form对象中有一个map errors封装了错误信息
          request.setAttribute("form", form);   
          //request.getRequestDispatcher("/servlet/AddCustomerServlet").forward(request, response);
          doGet(request, response);        
          return;
          //request.setAttribute("message", "validate失败!");
          //request.getRequestDispatcher("/message.jsp").forward(request, response);
        }
        //request.setAttribute("message", "validate成功!");
        //2.2如果校验成功,把表单封装到customer对象中
        Customer c =WebUtils.request2Bean(request, Customer.class);
        c.setDescription(c.getDescription().trim());
      //Customer还差一个成员:id,通过工具类UUID算法生成全球唯一ID
        c.setId(WebUtils.generateId());
      //3,这个时候已经将Customer对象准备好了,调业务层添加客户
        BusinessService service=new BusinessServiceImpl();
        service.add(c);
        request.setAttribute("message", "添加用户成功!");
    } catch (Exception e) {
      //如果添加失败:记录异常,并给友好提示
      e.printStackTrace();
      request.setAttribute("message", "添加用户失败!");
    }
    //无论添加成功或失败,都将跳转到全局消息显示页面
    request.getRequestDispatcher("/message.jsp").forward(request, response);
  }
}


CopyOfListCustomerServlet位于web.controller

package cn.itcast.web.controller;

import java.io.IOException;
import java.util.List;

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

import cn.itcast.service.BusinessService;
import cn.itcast.service.impl.BusinessServiceImpl;

public class CopyOfListCustomerServlet extends HttpServlet {

  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    //谁能保证这儿不抛异常!
    try {
      //所示请求,都通过业务层实现!接口指向实现
      BusinessService service = new BusinessServiceImpl();
      List list = service.getAll();
      //将list集合存到request域带给jsp显示
      request.setAttribute("list", list);
      request.getRequestDispatcher("/WEB-INF/jsp/listcustomer.jsp").forward(request, response);    
    } catch (Exception e) {
      // 出现异常不要紧,记录下来,并给友好提示!
      e.printStackTrace();
      request.setAttribute("message", "查看客户失败!!");
      request.getRequestDispatcher("/message.jsp").forward(request, response);
    }
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doGet(request, response);
  }
}


DeleteCustomerServlet位于web.controller

package cn.itcast.web.controller;
import java.io.IOException;

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

import cn.itcast.service.BusinessService;
import cn.itcast.service.impl.BusinessServiceImpl;


public class DeleteCustomerServlet extends HttpServlet {

  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    //servlet的doPost方法try异常模板代码[try_post]
    //谁能保证这儿不抛异常!
    try {
      String id=request.getParameter("id");
      //调用service处理业务!所示请求,都通过业务层实现!接口指向实现      
      BusinessService service = new BusinessServiceImpl();
      service.delete(service.find(id));
      //业务处理好之后,将message存到request域带给jsp显示!
      request.setAttribute("message", "删除成功");
      request.getRequestDispatcher("/message.jsp").forward(request,
          response);
    } catch (Exception e) {
      //出现异常不要紧,记录下来,并给友好提示!
      e.printStackTrace();
      request.setAttribute("message", "删除失败");
      request.getRequestDispatcher("/message.jsp").forward(request,
          response);
    }
  }

  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doGet(request, response);
  }

}


EditCustomerServlet位于web.controller

package cn.itcast.web.controller;

import java.io.IOException;

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

import cn.itcast.domain.Customer;
import cn.itcast.formbean.FormBean;
import cn.itcast.service.BusinessService;
import cn.itcast.service.impl.BusinessServiceImpl;
import cn.itcast.utils.Global;
import cn.itcast.utils.WebUtils;

public class EditCustomerServlet extends HttpServlet {

  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    /*点击修改超链接:给用户提供一个修改界面
     * 1,先通过参数c.id获取Customer对象,存到request域内
     * 1,再将Global的静态成员(可能变化的数据)存到request域内
     * 2,最后转发到WEB-INF/jsp/editcustomer.jsp*/
    String id=request.getParameter("id");
    //调用业务层处理业务,获得Customer
    BusinessService service=new BusinessServiceImpl();
    Customer c=service.find(id);
    request.setAttribute("c", c);
    //别忘了还要将可能变化的这些动态数据存到域内,传给jsp显示
    request.setAttribute("genders", Global.genders);
    request.setAttribute("preferences", Global.preferences);
    request.setAttribute("types", Global.types);    
    request.getRequestDispatcher("/WEB-INF/jsp/editcustomer.jsp").forward(request, response);
  }

  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    try {
      //1,既然是Post提交上来的数据,首先处理乱码问题!
      request.setCharacterEncoding("utf-8");
      //2,把表单数据封装到FormBean对象,对提交表单的字段进行validate校验
      FormBean form=WebUtils.request2FormBean(request, FormBean.class);
      boolean b=form.validate();
      //2.1 如果校验失败,跳回到表单页面,回显校验失败信息
        if(!b){
          //因为form对象中有一个map errors封装了错误信息
          request.setAttribute("form", form);   
          //request.getRequestDispatcher("/servlet/AddCustomerServlet").forward(request, response);
          doGet(request, response);        
          return;
          //request.setAttribute("message", "validate失败!");
          //request.getRequestDispatcher("/message.jsp").forward(request, response);
        }
        //request.setAttribute("message", "validate成功!");
        //2.2如果校验成功,把表单封装到customer对象中
        Customer c =WebUtils.request2Bean(request, Customer.class);
           //3,这个时候已经将Customer对象准备好了,调业务层更新客户数据
        BusinessService service=new BusinessServiceImpl();
        service.update(c);
        request.setAttribute("message", "更新用户成功!");
    } catch (Exception e) {
      //如果更新失败:记录异常,并给友好提示
      e.printStackTrace();
      request.setAttribute("message", e);
    }
    //无论更新成功或失败,都将跳转到全局消息显示页面
    request.getRequestDispatcher("/message.jsp").forward(request, response);
  }
}


ListCustomerServlet位于web.controller

package cn.itcast.web.controller;

import java.io.IOException;
import java.util.List;

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

import cn.itcast.domain.PageBean;
import cn.itcast.domain.QueryInfo;
import cn.itcast.service.BusinessService;
import cn.itcast.service.impl.BusinessServiceImpl;
import cn.itcast.utils.WebUtils;

public class ListCustomerServlet extends HttpServlet {

  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    //谁能保证这儿不抛异常!
    try {
      //使用工具类,先将请求封装到一个QueryInfo对象中去!
      QueryInfo info=WebUtils.request2Bean(request, QueryInfo.class);
      //所示请求,都通过业务层实现!接口指向实现
      BusinessService service = new BusinessServiceImpl();
      PageBean pb=service.pageQuery(info);
      //PageBean已经封装了所有数据,存到request域带给jsp显示
      request.setAttribute("pb", pb);
      request.getRequestDispatcher("/WEB-INF/jsp/listcustomer.jsp").forward(request, response);    
    } catch (Exception e) {
      // 出现异常不要紧,记录下来,并给友好提示!
      e.printStackTrace();
      request.setAttribute("message", e);
      request.getRequestDispatcher("/message.jsp").forward(request, response);
    }
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doGet(request, response);
  }
}


batchinsert位于junit.test

package junit.test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import cn.itcast.exception.DaoException;
import cn.itcast.utils.JdbcUtils;
import cn.itcast.utils.WebUtils;

public class batchinsert {
  public static void main(String[] args) {
     Connection conn=null;
      PreparedStatement st=null;
      ResultSet rs=null;
    try {
      conn=JdbcUtils.getConnection();
        //先准备String sql,再通过连接准备PreparedStatement
        String fields="id,name,gender,preference,type";
        String sql="insert into customer("+fields+") values(?,?,?,?,?)";
        st=conn.prepareStatement(sql);
       //批量插入
        for(int i=0;i<200;i++){
            st.setString(1, WebUtils.generateId() + i);
            st.setString(2, "妙玉" + i);
            st.setString(3, "女");
            st.setString(4, "诗词");
            st.setString(5, "尼姑");
            st.addBatch();
            if(i%50==0){
              //避免内存溢出,每50条执行一次后清空!
                st.executeBatch();
                st.clearBatch();
            }
        }
        st.executeBatch();
    } catch (Exception e) {
        //自定义Dao异常,是为了方便定义错误出在哪一层!
        throw new DaoException();
    }finally{
      JdbcUtils.release(conn, st, rs);
    }
  }
}
test位于junit.test
package junit.test;

import java.util.HashMap;
import java.util.Map;

public class test {
  private static Map errors=new HashMap();
  public static void main(String[] args) {
    System.out.println(validate("1231232121"));
  }
   public static boolean validate(String cellphone){
        //默认是真,只要有一个错误,flag为假
        boolean flag = true;
      //3,手机是7-11位数字
          if(!cellphone.matches("\\d{7,11}") && cellphone!=null && !cellphone.trim().equals("")){
            flag = false;
            errors.put("cellphone", "手机号码为7-11位数字!");
          }
        // if(!name.matches("^([\u4e00-\u9fa5]+)$") || !name.matches("[A-Za-z]{2,10}"))
        return flag;
      }
   public static boolean validate1(String name){
     //默认是真,只要有一个错误,flag为假
     boolean flag = true;
     //名字不能为空,只能是2-10位字母或汉字区间(\u4e00-\u9fa5)
     if(name==null || name.trim().equals("")){
       flag = false;
       errors.put("name", "名字不能为空!");
     }else if(!name.matches("^([\u4e00-\u9fa5]{2,})$") && !name.matches("[A-Za-z]{2,10}")){
       flag = false;
       errors.put("name", "名字必须是2-10位字母或汉字!");
     }
     // if(!name.matches("^([\u4e00-\u9fa5]+)$") || !name.matches("[A-Za-z]{2,10}"))
     return flag;
   }
}

dao.properties位于src类目录下

CustomerDao=cn.itcast.dao.impl.CustomerDaoImpl
#CustomerDao=cn.itcast.dao.impl.UserDaoXmlImpl


db.properties位于src类目录下

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/day14_customer?useUnicode=true&characterEncoding=utf-8
user=root
password=root
#driver=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:@localhost:1521:orcl
#user=system
#password=itcast


用到的第3方jar包

用到的第三方库

jstl.jar    
standard.jar

commons-beanutils-1.8.0.jar 
commons-logging.jar
MySQL驱动:mysql-connector-java-5.0.8-bin.jar


head.jsp位于WebRoot目录下

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>红楼梦苑</title>
  </head>
  <body style="text-align: center;">
    <h1>红楼梦苑</h1>
    <a href="${pageContext.request.contextPath}/servlet/AddCustomerServlet" target="main">添加红楼十二钗</a>
    <a href="${pageContext.request.contextPath}/servlet/ListCustomerServlet" target="main">查看红楼十二钗</a>
  </body>
</html>


index.jsp位于WebRoot目录下

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>首页</title>
    <!-- 千万注意:frameset和body是同级标签,不能嵌套 -->
  </head>
  
  <frameset rows="20%,*">
      <frame name="head" src="${pageContext.request.contextPath}/head.jsp" scrolling="no" noresize="noresize"/>
      <frame name="main" src="#">
  </frameset>
</html>


message.jsp位于WebRoot目录下

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>您有新的消息,请注意查收</title>
  </head>
  <body>
  ${message }
  ${requestScope.message }
  ${form.errors.name }
  </body>
</html>


ShowCalendar.js位于WebRoot/js目录下

// 日期选择
// By Ziyue(http://www.web-v.com/)
// 使用方法:
// <script type="text/javascript" src="${pageContext.request.contextPath }/js/ShowCalendar.js"></script>
// <input name="birthday" type="text" id="birthday" title="点击选择" onClick="showCalendar(this.id)">
	
var today; 
document.writeln("<div id='Calendar' style='position:absolute; z-index:1; visibility: hidden; filter:\"progid:DXImageTransform.Microsoft.Shadow(direction=135,color=#999999,strength=3)\"'></div>");
	

function getDays(month, year)
{ 
	var daysInMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); 
	//下面的这段代码是判断当前是否是闰年的 
	if (1 == month) 
	return ((0 == year % 4) && (0 != (year % 100))) || (0 == year % 400) ? 29 : 28; 
	else 
	return daysInMonth[month]; 
} 

function getToday() 
{ 
	//得到今天的年,月,日 
	this.now = new Date(); 
	this.year = this.now.getFullYear(); 
	this.month = this.now.getMonth(); 
	this.day = this.now.getDate(); 
}

function getStringDay(str) 
{ 
	//得到输入框的年,月,日
	var str=str.split("-")
	
	this.now = new Date(parseFloat(str[0]),parseFloat(str[1])-1,parseFloat(str[2])); 
	this.year = this.now.getFullYear(); 
	this.month = this.now.getMonth(); 
	this.day = this.now.getDate(); 
}

function newCalendar() { 
	var parseYear = parseInt(document.all.Year.options[document.all.Year.selectedIndex].value); 
	var newCal = new Date(parseYear, document.all.Month.selectedIndex, 1); 
	var day = -1; 
	var startDay = newCal.getDay(); 
	var daily = 0; 
	
	if ((today.year == newCal.getFullYear()) &&(today.month == newCal.getMonth())) 
		day = today.day; 

	var tableCal = document.all.calendar; 
	var intDaysInMonth =getDays(newCal.getMonth(), newCal.getFullYear());

	for (var intWeek = 1; intWeek < tableCal.rows.length;intWeek++) 
		for (var intDay = 0;intDay < tableCal.rows[intWeek].cells.length;intDay++) 
		{ 
			var cell = tableCal.rows[intWeek].cells[intDay]; 
			if ((intDay == startDay) && (0 == daily)) 
				daily = 1; 

			if(day==daily) //今天,调用今天的Class 
			{
				cell.style.background='#6699CC';
				cell.style.color='#FFFFFF';
				//cell.style.fontWeight='bold';
			}
			else if(intDay==6) //周六 
				cell.style.color='green'; 
			else if (intDay==0) //周日 
				cell.style.color='red';

			if ((daily > 0) && (daily <= intDaysInMonth)) 
			{ 
				cell.innerText = daily; 
				daily++; 
			} 
			else 
				cell.innerText = ""; 
		} 
	} 

function GetDate(InputBox)
{ 
	var sDate; 
	//这段代码处理鼠标点击的情况 
	if (event.srcElement.tagName == "TD") 
	if (event.srcElement.innerText != "") 
	{ 
		sDate = document.all.Year.value + "-" + document.all.Month.value + "-" + event.srcElement.innerText;
		eval("document.all."+InputBox).value=sDate;
		HiddenCalendar();
	} 
} 

function HiddenCalendar()
{
	//关闭选择窗口
	document.all.Calendar.style.visibility='hidden';
}

function showCalendar(InputBox)
{
	var months = new Array("一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"); 
	var days = new Array("日","一", "二", "三", "四", "五", "六"); 

	var x,y,intLoop,intWeeks,intDays;
	var DivContent;
	var year,month,day;
	var o=eval("document.all."+InputBox);
	var thisyear; //真正的今年年份
	
	thisyear=new getToday();
	thisyear=thisyear.year;
	
	today = o.value;
	if(isDate(today))
	today = new getStringDay(today);
	else
	today = new getToday(); 
	
	//显示的位置
	x=o.offsetLeft;
	y=o.offsetTop;
	while(o=o.offsetParent)
	{
	x+=o.offsetLeft;
	y+=o.offsetTop;
	}
	document.all.Calendar.style.left=x+2;
	document.all.Calendar.style.top=y+20;
	document.all.Calendar.style.visibility="visible";
	
	//下面开始输出日历表格(border-color:#9DBAF7)
	DivContent="<table border='0' cellspacing='0' style='border:1px solid #0066FF; background-color:#EDF2FC'>";
	DivContent+="<tr>";
	DivContent+="<td style='border-bottom:1px solid #0066FF; background-color:#C7D8FA'>";
	
	//年
	DivContent+="<select name='Year' id='Year' onChange='newCalendar()' style='font-family:Verdana; font-size:12px'>";
	for (intLoop = thisyear - 35; intLoop < (thisyear + 2); intLoop++) 
	DivContent+="<option value= " + intLoop + " " + (today.year == intLoop ? "Selected" : "") + ">" + intLoop + "</option>"; 
	DivContent+="</select>";
	
	//月
	DivContent+="<select name='Month' id='Month' onChange='newCalendar()' style='font-family:Verdana; font-size:12px'>";
	for (intLoop = 0; intLoop < months.length; intLoop++) 
	DivContent+="<option value= " + (intLoop + 1) + " " + (today.month == intLoop ? "Selected" : "") + ">" + months[intLoop] + "</option>"; 
	DivContent+="</select>";
	
	DivContent+="</td>";
	
	DivContent+="<td style='border-bottom:1px solid #0066FF; background-color:#C7D8FA; font-weight:bold; font-family:Wingdings 2,Wingdings,Webdings; font-size:16px; padding-top:2px; color:#4477FF; cursor:hand' align='center' title='关闭' onClick='javascript:HiddenCalendar()'>S</td>";
	DivContent+="</tr>";
	
	DivContent+="<tr><td align='center' colspan='2'>";
	DivContent+="<table id='calendar' border='0' width='100%'>";
	
	//星期
	DivContent+="<tr>";
	for (intLoop = 0; intLoop < days.length; intLoop++) 
	DivContent+="<td align='center' style='font-size:12px'>" + days[intLoop] + "</td>"; 
	DivContent+="</tr>";
	
	//天
	for (intWeeks = 0; intWeeks < 6; intWeeks++)
	{ 
	DivContent+="<tr>"; 
	for (intDays = 0; intDays < days.length; intDays++) 
	DivContent+="<td onClick='GetDate(\"" + InputBox + "\")' style='cursor:hand; border-right:1px solid #BBBBBB; border-bottom:1px solid #BBBBBB; color:#215DC6; font-family:Verdana; font-size:12px' align='center'></td>"; 
	DivContent+="</tr>"; 
	} 
	DivContent+="</table></td></tr></table>";
	
	document.all.Calendar.innerHTML=DivContent;
	newCalendar();
}

function isDate(dateStr)
{ 
	var datePat = /^(\d{4})(\-)(\d{1,2})(\-)(\d{1,2})$/;
	var matchArray = dateStr.match(datePat);
	if (matchArray == null) return false; 
	var month = matchArray[3];
	var day = matchArray[5]; 
	var year = matchArray[1]; 
	if (month < 1 || month > 12) return false; 
	if (day < 1 || day > 31) return false; 
	if ((month==4 || month==6 || month==9 || month==11) && day==31) return false; 
	if (month == 2)
	{
	var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); 
	if (day > 29 || (day==29 && !isleap)) return false; 
	} 
	return true;
}


igg.tld位于WebRoot/WEB-INF目录下

<?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">
    <tlib-version>1.0</tlib-version>
    <short-name>SimpleTagLibrary</short-name>
    <uri>www.igg.com</uri>
    <function>
        <name>leftStr</name>
		<function-class>cn.itcast.utils.MyEL</function-class>
		<function-signature>java.lang.String leftStr( java.lang.String , java.lang.Integer)</function-signature>
    </function>
</taglib>


addcustomer.jsp位于WebRoot/WEB-INF/jsp目录下

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core"  prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>添加人物</title>
    <script type="text/javascript" src="${pageContext.request.contextPath }/js/ShowCalendar.js"></script>
    <script type="text/javascript">
    //js连接喜好选项,成字符串,并作为隐藏选项添加在form表单里
        function joinStr(){
          var o1=document.getElementsByName("pre");
          var str="";
          for(var i=0;i<o1.length;i++){
            //alert(o1[i].value);
            if(o1[i].checked){
              str+=o1[i].value+",";
            }
          }
          str=str.substr(0,str.length-1);
          var form=document.getElementById("form_id");
          var hiddenInput=document.createElement("input");
          hiddenInput.type="hidden";
          hiddenInput.name="preference";
          hiddenInput.value=str;
          //alert(str);
          form.appendChild(hiddenInput);
          return true;
        }
    </script>
  </head>
  <body style="text-align: center;">
  <form id="form_id" action="${pageContext.request.contextPath }/servlet/AddCustomerServlet" method="post" οnsubmit="return joinStr()">
    <table border="1" width="50%">
       <tr>
         <td>人物姓名</td>
         <td>
           <input type="text" name="name" value="${param.name }">
           <span>${form.errors.name }</span>
         </td>
       </tr>
       <tr>
         <td>人物性别</td>
         <td>
           <c:forEach var="g" items="${genders}">
             <input type="radio" name="gender" value="${g }" ${param.gender==g?'checked':'' }/>${g }
           </c:forEach>
         </td>
       </tr>
       <tr>
         <td>生日</td>
         <td>
            <input type="text" name="birthday" id="birthday" onClick="showCalendar(this.id)"  value="${param.birthday }" >
            <span>${form.errors.birthday }</span>
         </td>
       </tr>
       <tr>
         <td>手机</td>
         <td>
           <input type="text" name="cellphone" value="${param.cellphone }">
           <span>${form.errors.cellphone }</span>
         </td>
       </tr>
       <tr>
         <td>邮箱</td>
         <td>
           <input type="text" name="email" value="${param.email }">
           <span>${form.errors.email }</span>
         </td>
       </tr>
       <tr>
         <td>爱好</td>
         <td>
           <c:forEach var="pre" items="${preferences}">
             <input type="checkbox" name="pre" value="${pre }" ${fn:contains(param.preference,pre)?'checked':'' }/>${pre }
           </c:forEach>
         </td>
       </tr>
       <tr>
         <td>人物类型</td>
         <td>
           <c:forEach var="t" items="${types}">
             <input type="radio" name="type" value="${t }" ${param.type==t?'checked':'' }>${t }
           </c:forEach>
         </td>
       </tr>
       <tr>
         <td>备注</td>
         <td>
           <textarea rows="5" cols="60" name="description">
          ${fn:trim(param.description) }
        </textarea>
         </td>
       </tr>
       <tr>
         <td>
           <input type="reset" value="重置">
         </td>
         <td>
           <input type="submit" value="添加客户">
         </td>
       </tr>
     </table>
  </form> 
  </body>
</html>


editcustomer.jsp位于WebRoot/WEB-INF/jsp目录下

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core"  prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>修改人物</title>
    <script type="text/javascript" src="${pageContext.request.contextPath }/js/ShowCalendar.js"></script>
    <script type="text/javascript">
    //js连接喜好选项,成字符串,并作为隐藏选项添加在form表单里
        function joinStr(){
          var o1=document.getElementsByName("pre");
          var str="";
          for(var i=0;i<o1.length;i++){
            //alert(o1[i].value);
            if(o1[i].checked){
              str+=o1[i].value+",";
            }
          }
          str=str.substr(0,str.length-1);
          var form=document.getElementById("form_id");
          var hiddenInput=document.createElement("input");
          hiddenInput.type="hidden";
          hiddenInput.name="preference";
          hiddenInput.value=str;
          //alert(str);
          form.appendChild(hiddenInput);
          return true;
        }
    </script>
  </head>
  <body style="text-align: center;">
  <form id="form_id" action="${pageContext.request.contextPath }/servlet/EditCustomerServlet" method="post" οnsubmit="return joinStr()">
    <table border="1" width="50%">
    <input type="hidden" name="id" value="${c.id }">
       <tr>
         <td>人物姓名</td>
         <td>
           <input type="text" name="name" value="${c.name }">
           <span>${form.errors.name }</span>
         </td>
       </tr>
       <tr>
         <td>人物性别</td>
         <td>
           <c:forEach var="g" items="${genders}">
             <input type="radio" name="gender" value="${g }" ${c.gender==g?'checked':'' }/>${g }
           </c:forEach>
         </td>
       </tr>
       <tr>
         <td>生日</td>
         <td>
            <input type="text" name="birthday" id="birthday" onClick="showCalendar(this.id)"  value="${c.birthday }" >
            <span>${form.errors.birthday }</span>
         </td>
       </tr>
       <tr>
         <td>手机</td>
         <td>
           <input type="text" name="cellphone" value="${c.cellphone }">
           <span>${form.errors.cellphone }</span>
         </td>
       </tr>
       <tr>
         <td>邮箱</td>
         <td>
           <input type="text" name="email" value="${c.email }">
           <span>${form.errors.email }</span>
         </td>
       </tr>
       <tr>
         <td>爱好</td>
         <td>
           <c:forEach var="pre" items="${preferences}">
             <input type="checkbox" name="pre" value="${pre }" ${fn:contains(c.preference,pre)?'checked':'' }/>${pre }
           </c:forEach>
         </td>
       </tr>
       <tr>
         <td>人物类型</td>
         <td>
           <c:forEach var="t" items="${types}">
             <input type="radio" name="type" value="${t }" ${c.type==t?'checked':'' }>${t }
           </c:forEach>
         </td>
       </tr>
       <tr>
         <td>备注</td>
         <td>
           <textarea rows="5" cols="60" name="description">
          ${fn:trim(c.description) }
        </textarea>
         </td>
       </tr>
       <tr>
         <td>
           <input type="reset" value="重置">
         </td>
         <td>
           <input type="submit" value="更新客户">
         </td>
       </tr>
     </table>
  </form> 
  </body>
</html>


listcustomer.jsp位于WebRoot/WEB-INF/jsp目录下

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="/WEB-INF/igg.tld" prefix="igg"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>显示红楼梦所有人物</title>
    <style type="text/css">
      .even{background-color: #FFFF00}
      .odd{background-color: #FFCCFF}
      tr:hover{background-color: #FF99FF}
      a:link{text-decoration: none}
    </style>
    <script type="text/javascript">
        function deleteById(id){
          if(window.confirm("确定删除吗?")){
            window.location.href='${pageContext.request.contextPath}/servlet/DeleteCustomerServlet?id='+id;
          }
        }
    </script>
  </head>
  <body style="text-align: center;">
    <table frame="border" width="86%" >
        <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.pb.list}" varStatus="status">
        <tr class="${status.count%2==0?'even':'odd' }">
          <td>${c.name }</td>
          <td>${c.gender }</td>
          <td>${c.birthday }</td>
          <td>${c.cellphone }</td>
          <td>${c.email }</td>
          <td>${c.preference }</td>
          <td>${c.type }</td>
          <td>${igg:leftStr(c.description,10) }</td>
          <td>
            <a href="${pageContext.request.contextPath }/servlet/EditCustomerServlet?id=${c.id }">修改</a>
            <a href="javascript:void(0)" οnclick="deleteById('${c.id }')">删除</a>
          </td>
        <tr>
      </c:forEach>
    </table>
    <hr/>
  <script type="text/javascript">
    function go(page){
      //如果新的page小于0 或者不是数字 或者大于总页数,就置输入框为''
      var total_page=document.getElementById("totalPage_id").innerHTML;
      //可以直接${pb.totalPage}拿到总页数
      var page_size=document.getElementById("pageSize_id").value;
      //alert(page);
      //alert(total_page);
      //alert(page>parseInt(total_page));
      if(page<1){
        alert("请输入正整数");
        document.getElementById("gotoPage_id").value='';
      }else if(page>${pb.totalPage}){
        alert("请输入"+total_page+"之内的正整数");
        document.getElementById("gotoPage_id").value='';
      }else if(page==parseInt(page)){
        //alert("正准备跳转");
        window.location="${pageContext.request.contextPath}/servlet/ListCustomerServlet?currentPage="+page+"&pageSize="+page_size;
      }              
    }
    function changeSize(oldSize,newSize){
      //如果新的size小于0 或者不是数字 或者大于99,就恢复输入框为oldsize
      
      if(newSize<1){
        alert("请输入正整数");
        document.getElementById("pageSize_id").value=oldSize;
      }else if(newSize>99){
        alert("请输入100以内正整数");
        document.getElementById("pageSize_id").value=oldSize;
      }else if(newSize==parseInt(newSize)){
        //alert("正准备跳转");
        location.href = '${pageContext.request.contextPath}/servlet/ListCustomerServlet?pageSize=' + newSize;
      }                  
    }  
  </script>
    共${pb.totalRecord }条记录
    每页
      <input type="text" id="pageSize_id" value="${pb.pageSize }" style="width: 15px;" maxlength="2" οnchange="changeSize('${pb.pageSize }',this.value)"/>
      条记录
      每页${pb.pageSize }条
      共<span id="totalPage_id">${pb.totalPage }</span>页
      当前第${pb.currentPage}页
          
      <c:if test="${pb.currentPage>5}">
        <a href="javascript:void(0)" οnclick="go(1)">首页</a>
      </c:if>
      <c:if test="${pb.currentPage!=1}">
        <a href="javascript:void(0)" οnclick="go(${pb.previousPage})">上一页</a>
      </c:if>
      <c:forEach var="i" items="${pb.pageBar}">
      <c:if test="${i==pb.currentPage}">
        <font color='red'>${i}</font>
      </c:if>
      <c:if test="${i!=pb.currentPage}">
          <a href="javascript:void(0)" οnclick="go(${i})">
        ${i }</a>
      </c:if>        
      </c:forEach>
      <c:if test="${pb.currentPage!=pb.totalPage}">
        <a href="javascript:void(0)" οnclick="go(${pb.nextPage})">下一页</a>
      </c:if>
      <c:if test="${pb.currentPage<pb.totalPage-5}">
        <a href="javascript:void(0)" οnclick="go(${pb.totalPage} )">末页</a>
      </c:if>
      <input type="text" id="gotoPage_id" style="width: 20px" οnchange="go(this.value)"/>
  </body>
</html>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值