成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【JavaWeb】客戶關(guān)系管理系統(tǒng)

Arno / 558人閱讀

摘要:前言為了鞏固開發(fā)的流程,我們再拿一個客戶關(guān)系管理系統(tǒng)來練手成果圖我們完成的就是下面的項(xiàng)目搭建配置環(huán)境配置導(dǎo)入開發(fā)包建立開發(fā)用到的程序包在數(shù)據(jù)庫創(chuàng)建相對應(yīng)的表開發(fā)實(shí)體開發(fā)實(shí)體十分簡單,對照著數(shù)據(jù)庫的表就行了各種開發(fā)獲取數(shù)據(jù)庫連接池的導(dǎo)入配置文

前言
為了鞏固開發(fā)的流程,我們再拿一個客戶關(guān)系管理系統(tǒng)來練手...!
成果圖

我們完成的就是下面的項(xiàng)目!

搭建配置環(huán)境

配置Tomcat

導(dǎo)入開發(fā)包

建立開發(fā)用到的程序包

在數(shù)據(jù)庫創(chuàng)建相對應(yīng)的表

    CREATE TABLE customer (
    
      id          VARCHAR(40) PRIMARY KEY,
      name        VARCHAR(20) NOT NULL,
      gender      VARCHAR(10) NOT NULL,
      birthday    DATE,
      cellphone   VARCHAR(30) NOT NULL,
      email       VARCHAR(30),
      preference  VARCHAR(200),
      type        VARCHAR(20),
      description VARCHAR(255)
    
    );


開發(fā)實(shí)體

開發(fā)實(shí)體十分簡單,對照著數(shù)據(jù)庫的表就行了!

    private String id;
    private String name ;
    private String gender ;
    private Date birthday ;
    private String cellphone ;
    private String eamil ;
    private String preference ;
    private String type ;
    private String description;


    //....各種setter、getter
開發(fā)獲取數(shù)據(jù)庫連接池的Utils 導(dǎo)入配置文件
    
    
        
            com.mysql.jdbc.Driver
            jdbc:mysql://localhost:3306/zhongfucheng
            root
            root
        
            5
            10
            5
            20
        
        
        
            com.mysql.jdbc.Driver
            jdbc:mysql://localhost:3306/zhongfucheng
            root
            root
        
            5
            10
            5
            20
        
        
        
        
            oracle.jdbc.driver.OracleDriver
            jdbc:oracle:thin:@//localhost:1521/事例名...
            用戶名
            密碼
        
            5
            10
            5
            20
        
    
開發(fā)提供數(shù)據(jù)連接池的工具類
    public class Utils2DB {
    
        private static ComboPooledDataSource comboPooledDataSource = null;
    
            static {
    
                //它會自動尋找配置文件,節(jié)點(diǎn)為mysql的數(shù)據(jù)庫(默認(rèn)就是Mysql)
                comboPooledDataSource = new ComboPooledDataSource();
            }
    
    
        public static DataSource getDataSource() {
            return comboPooledDataSource ;
        }
    
        public static Connection connection() {
            try {
                return comboPooledDataSource.getConnection();
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException("數(shù)據(jù)庫初始化失敗了!");
            }
        }
    }

開發(fā)UUID工具類
    
    public class WebUtils {
    
        public static String makeId() {
            return UUID.randomUUID().toString();
        }
    }
開發(fā)DAO

DAO應(yīng)該提供增加客戶和查詢用戶的功能

增加用戶

    public void addCustomer(Customer customer)  {

        QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());

      
        String sql = "INSERT INTO customer (id,name, gender, birthday, cellphone, preference, type, description) VALUES (?, ?, ?, ?, ?, ?, ?, ?,?)";


        //得到用戶傳遞進(jìn)來的數(shù)據(jù)
        String id = customer.getId();
        String name = customer.getName();
        String gender = customer.getGender();
        String cellphone = customer.getCellphone();
        String email = customer.getEmail();
        String preference = customer.getPreference();
        String type = customer.getType();
        String description = customer.getDescription();

        //對于日期,要轉(zhuǎn)換一下
        Date date = customer.getBirthday();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String birthday = simpleDateFormat.format(date);

        try {
            //向數(shù)據(jù)庫插入數(shù)據(jù)
            queryRunner.update(sql, new Object[]{id, name, gender, birthday, cellphone, email, preference, type, description});

            //插入記錄成功!
        } catch (SQLException e) {

            //如果出現(xiàn)了異常,就拋出Dao異常吧(自定義的異常)
            e.printStackTrace();

            throw new DaoException("添加用戶出錯了!");
        }
    }
測試增加用戶

寫完一個功能,不要急著去寫其他的功能,先測試一下!

    @Test
    public void add() {

        //為了測試的方便,直接使用構(gòu)造函數(shù)了!
        Customer customer = new Customer("1", "zhongfucheng", "男", new Date(), "1234", "[email protected]", "打代碼", "高貴的用戶", "我是個好人");



        CustomerDao customerDao = new CustomerDao();
        customerDao.addCustomer(customer);
        
    }

好的,沒有報錯!再看看數(shù)據(jù)庫-----------只要是中文的數(shù)據(jù),都亂碼了!

解決的辦法,看我另外一篇博文:https://zhongfucheng.bitcron....

查詢用戶

將所有的客戶查詢出來就行了!


    //得到所有的用戶
    public List getAll() {

        QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());


        String sql = "SELECT * FROM customer";
        try {
            List customers = (List) queryRunner.query(sql, new BeanListHandler(Customer.class));

            //如果集合大于個數(shù)大于0,就返回集合,不大于0,就返回null
            return customers.size() > 0 ? customers : null;
            
        } catch (SQLException e) {
            e.printStackTrace();
            throw new DaoException("獲取所有的用戶出錯了!");
        }
        
    }
測試查詢用戶
    @Test
    public void find() {

        CustomerDao customerDao = new CustomerDao();
        List customers = customerDao.getAll();

        for (Customer customer : customers) {

            System.out.println(customer.getName());
        }
    }

修改用戶信息

修改用戶信息首先要知道用戶的信息,在web端,只有id能唯一標(biāo)識用戶,我們需要通過id,獲取用戶全部信息(也就是Customer對象)

    public Customer find(String id) {

        QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());

        String sql = "SELECT * FROM customer WHERE id = ?";

        try {
            Customer customer = (Customer) queryRunner.query(sql, new BeanHandler(Customer.class), new Object[]{id});

            return customer;

        } catch (SQLException e) {
            e.printStackTrace();
            throw new DaoException("查找用戶失敗了");
        }

    }

修改用戶都是外邊傳遞個對象進(jìn)來,Dao層取出對象的數(shù)據(jù),從而對數(shù)據(jù)庫的數(shù)據(jù)進(jìn)行修改!


    public void update(Customer customer) {

        QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());

        String sql = "UPDATE customer set name=?,gender=?,birthday=?,cellphone=?,email=?,preference=?,type=?,description=?  WHERE id = ?";

        try {
            queryRunner.update(sql, new Object[]{customer.getName(), customer.getGender(), customer.getBirthday(),customer.getCellphone(), customer.getEmail(), customer.getPreference(), customer.getType(), customer.getDescription(), customer.getId()});

        } catch (SQLException e) {

            e.printStackTrace();
            throw new DaoException("更新失敗");
        }
    }
測試修改用戶
    @Test
    public void update() {

        CustomerDao customerDao = new CustomerDao();

        //我們已經(jīng)知道了某id,通過id獲取得到用戶信息(Customer)
        String id = "043f7cce-c6f1-4155-b688-ba386cae1636";
        Customer customer = customerDao.find(id);

        //修改用戶信息
        customer.setName("看完博客要點(diǎn)贊");
        customerDao.update(customer);
    }

原來該用戶的名字是d

測試完之后:

刪除用戶

通過外界傳遞進(jìn)來的id,就可以刪除數(shù)據(jù)庫表中的記錄了

    public void delete(String id) {
        QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());

        String sql = "DELETE from  customer WHERE id = ?";
        try {
            queryRunner.update(sql, new Object[]{id});
        } catch (SQLException e) {
            e.printStackTrace();
            throw new DaoException("刪除用戶失敗了");
        }
    }
測試刪除用戶
    @Test
    public void delete() {

        CustomerDao customerDao = new CustomerDao();

        //我們已經(jīng)知道了某id,通過id刪除數(shù)據(jù)庫中的記錄
        String id = "043f7cce-c6f1-4155-b688-ba386cae1636";

        customerDao.delete(id);
    }

數(shù)據(jù)庫已經(jīng)查詢不到id為043f7cce-c6f1-4155-b688-ba386cae1636的記錄了!

開發(fā)service

    public class BusinessService {
    
        CustomerDao customerDao = new CustomerDao();
    
        public List getAll() {
    
            return customerDao.getAll();
        }
    
        public void addCustomer(Customer customer) {
    
            customerDao.addCustomer(customer);
        }

        public void deleteCustomer(String id) {
            customerDao.delete(id); 
        }
    
        public void updateCustomer(Customer customer) {
            customerDao.update(customer);
        }
    
        public Customer findCustomer(String id) {
            return customerDao.find(id);
        }
    }
開發(fā)web 的增加和查詢 提供UI,增加客戶的Servlet
        //直接跳轉(zhuǎn)到顯示增加用戶頁面的jsp
        request.getRequestDispatcher("/WEB-INF/addCustomer.jsp").forward(request, response);
開發(fā)顯示添加客戶頁面
用戶名:
性別:
生日:
電話號碼:
郵箱:
愛好: 唱歌 跳舞 打代碼
客戶類型 VIP 普通客戶 黑名單客戶
描述

效果是這樣子的

我們發(fā)現(xiàn),在日期的下拉框中,只有一個數(shù)據(jù)(因?yàn)槲覀冊趘alue中只寫了一個數(shù)據(jù))

要想在下拉框中可以選擇很多的數(shù)據(jù),那么value的值就不能單單只有一個。當(dāng)然了,也不可能在JSP頁面中寫下面的代碼

                    
                    
                    
                    

我們用javaScript生成下拉框的數(shù)據(jù)就行了??!

獲取年份!

    function makeYear() {
    
        //得到下拉框的控件
        var year = document.getElementById("year");
    
        //要想下拉框有更多的數(shù)據(jù),就需要有更多的option控件
        //js獲取得到年份是getFullYear(),單單的getYear()只是獲取兩位數(shù)
        for (var i=1901; i<= new Date().getFullYear(); i++) {
    
    
            //生成option控件
            var option = document.createElement("option");
    
            //option控件的值和文本內(nèi)容為循環(huán)生成的年分!
            option.value = i;
            option.innerText = i;
    
            //將生成option控件綁定到select控件上
            year.appendChild(option);
        }
    
    }

獲取月份和日也類似

    function makeMonth() {
        var month = document.getElementById("month");
        for (var i = 2; i <= 12; i++) {
            var option = document.createElement("option");
            if (i < 10) {
                option.value = "0" + i;
                option.innerText = "0" + i;
            } else {
                option.value = i;
                option.innerText = i;
            }
            month.appendChild(option);
        }
    }
    
    function makeDay()
    {
        var day = document.getElementById("day");
        for(var i=2;i<=12;i++)
        {
            var option = document.createElement("option");
            if(i<10)
            {
                option.value = "0" + i;
                option.innerText = "0" + i;
            }else{
                option.value = i;
                option.innerText = i;
            }
            day.appendChild(option);
        }
    }

在JSP頁面中導(dǎo)入javascript文件

注意:javasrcipt文件不能放在WEB-INF下面?。。?!否則是獲取不到的?。?!

    

這三個函數(shù)都是在頁面加載時就應(yīng)該被初始化了,所以在body上綁定onload時間即可??!

    function pageInit() {
        makeYear();
        makeMonth();
        makeDay();
    }


    

效果:

JavaScript拼湊數(shù)據(jù)

表單的數(shù)據(jù)非常多,毫無疑問,我們會使用BeanUtils來將數(shù)據(jù)封裝到Bean對象中!

對于表單的數(shù)據(jù),還是有些雜亂的。表單中日期的年月日是分開的,我們要么在客戶端將年月日的數(shù)據(jù)拼湊起來,要么在服務(wù)器端將年月日拼湊起來!同理,客戶的喜好可能不單單有一個,但在Customer對象中,喜好單單用一個String類型來表示的。我們也要把客戶的喜好拼湊起來。

顯然,在客戶端用javaScript做拼湊是非常方便的!

    function makeBirthday() {
    
        //獲取下拉框的數(shù)據(jù),把數(shù)據(jù)拼湊成日期字符串
        var year = document.getElementById("year");
        var month = document.getElementById("month");
        var day = document.getElementById("day");
        var birthday = year + "-" + month + "-" + day;
    
        //想要將拼湊完的字符串提交給服務(wù)器,用隱藏域就行了
        var input = document.createElement("input");
        input.type = "hidden";
        input.value = birthday;
        input.name = "birthday";
    
        //將隱藏域綁定在form下【為了方便,在form中設(shè)置id,id名字為form】
        document.getElementById("form").appendChild(input);
    
    }
    
    function makePreference() {
    
        //獲取喜好的控件
        var hobbies = document.getElementsByName("hobbies");
    
        //定義變量,記住用戶選中的選項(xiàng)
        var preference = "";
    
        //遍歷喜好的控件,看用戶選上了什么!
        for (var i = 0; i < hobbies.length; i++) {
    
            if (hobbies[i].checked == true) {
                preference += hobbies[i].value + ",";
            }
        }
    
        //剛才拼湊的時候,最后一個逗號是多余的,我們要把它去掉
        preference = preference.substr(0, preference.length - 1);
    
        //也是用隱藏域?qū)?shù)據(jù)帶過去給服務(wù)器
        var input = document.createElement("input");
        input.type = "hidden";
        input.value = preference;
        input.name = "preference";
        
        //將隱藏域綁定到form表單上
        document.getElementById("form").appendChild(input);
        
    }

當(dāng)表單提交的時候,觸發(fā)上面兩個函數(shù)就行了!所以在form表單上綁定onsumit事件!

    function makeForm() {
        
        makeBirthday();
        makePreference();
        return true;
        
    }

    
開發(fā)處理表單數(shù)據(jù)的Servlet

將表單的數(shù)據(jù)封裝到Bean對象中,要開發(fā)工具類

    public static  T request2Bean(HttpServletRequest httpServletRequest, Class aClass) {

        try {
            
            //獲取Bean的對象
            T bean = aClass.newInstance();
            
            //獲取表單中所有的名字
            Enumeration enumeration = httpServletRequest.getParameterNames();

            //遍歷表單提交過來的名字
            while (enumeration.hasMoreElements()) {

                //每個名字
                String name = (String) enumeration.nextElement();

                //獲取得到值
                String value = httpServletRequest.getParameter(name);

                //如果用戶提交的數(shù)據(jù)不為空,那么將數(shù)據(jù)封裝到Bean中
                if (!value.equals("") && value != null) {
                    BeanUtils.setProperty(bean, name, value);
                }

              
            }
              return bean;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("封裝數(shù)據(jù)到Bean中,失敗了!");
        }
        
    }

處理表單數(shù)據(jù)的Servlet代碼:

        //將表單的數(shù)據(jù)弄到Bean對象中
        Customer customer = WebUtils.request2Bean(request, Customer.class);


        try {
            //調(diào)用BusinessService層的方法,添加客戶
            BusinessService businessService = new BusinessService();
            businessService.addCustomer(customer);

            //如果執(zhí)行到這里,說明成功了,如果被catch了,說明失敗了。
            request.setAttribute("message", "添加成功!");

        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("message", "添加失敗");
        }
        request.getRequestDispatcher("/message.jsp").forward(request, response);

效果:

提供查詢客戶界面的Servlet
        //跳轉(zhuǎn)到顯示客戶界面信息的jsp
        request.getRequestDispatcher("/WEB-INF/lookCustomer.jsp").forward(request, response);
開發(fā)顯示客戶信息的頁面
    
        對不起,還沒有任何客戶的信息!
    
    
    
        
                
用戶名: 密碼: 性別: 生日: 電話號碼: 郵箱: 類型: 描述:
${customer.name} ${customer.gender} ${customer.birthday} ${customer.cellphone} ${customer.email} ${customer.preference} ${customer.type} ${customer.description}

效果:

將功能拼接在首頁上

采用分貞技術(shù),讓界面更加好看!

index頁面:


  
      
      
  

head頁面:

    
    
    

客戶管理系統(tǒng)!

增添客戶 查看客戶

body頁面:


    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    
        Title
    
    
    
    

效果:

改善顯示頁面

現(xiàn)在問題來了,如果我們客戶信息有非常非常地多,我們不可能把客戶信息全部都擠在同一個頁面上,如果我們這樣做的話,網(wǎng)頁的長度就會非常的長!

于是乎,我們就需要用到了分頁的技術(shù),對于分頁技術(shù)基礎(chǔ)的講解,在我另一篇博文中有介紹: https://zhongfucheng.bitcron....

看完上篇博文,我們知道,首先要做的就是:明確分頁技術(shù)中需要用到的4個變量的值!

查詢總記錄數(shù)

查詢總記錄數(shù)也就是查詢數(shù)據(jù)庫表的記錄有多少條,這是關(guān)于對數(shù)據(jù)庫數(shù)據(jù)的操作,所以肯定是在dao層做!

    public Long getTotalRecord() {

        QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());

        String sql = "SELECT * FROM customer";
        
        try {
            //獲取查詢的結(jié)果
            Long l = (Long) queryRunner.query(sql, new ScalarHandler());
            return l;
           
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException("查詢總記錄數(shù)失敗了!");
        }
        
    }
查詢分頁的數(shù)據(jù)

獲取分頁的數(shù)據(jù)也是查詢數(shù)據(jù)庫的記錄,這也是關(guān)于對數(shù)據(jù)庫的操作,所以也是在Dao層做的!


    /*查詢分頁數(shù)據(jù)*/
    //獲取分頁的數(shù)據(jù)是需要start和end兩個變量的【從哪條開始取,取到哪一條】
    public List getPageData(int start, int end) {

        QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource());

        String sql = "SELECT * FROM customer LIMIT ?,?";

        try {
            List customers = (List) queryRunner.query(sql, new BeanListHandler(Customer.class), new Object[]{start, end});

            return customers;

        } catch (SQLException e) {
            e.printStackTrace();
            throw new DaoException("獲取分頁數(shù)據(jù)失敗了!");
        }
    }

分析

現(xiàn)在我們已經(jīng)可以知道總記錄數(shù)了,對于其他3個變量(每頁顯示記錄數(shù)【由程序員來指定】,當(dāng)前是多少頁【由用戶來指定】,總頁數(shù)【由總記錄數(shù)和每頁顯示記錄數(shù)來算數(shù)來的】)

現(xiàn)在要分析的是,這些變量應(yīng)該放在哪里呢???全部放在Dao層??全部放在Dao層是可以實(shí)現(xiàn)功能的,但是,這樣MVC結(jié)構(gòu)就被破壞掉了(Dao層只用來對數(shù)據(jù)進(jìn)行CRUD操作,4個變量存在Dao層,是不合理的)

最好的做法是這樣的:創(chuàng)建一個實(shí)體Page,將分頁用到的信息全部封裝在Page中實(shí)現(xiàn)!Page就代表著分頁的數(shù)據(jù)這樣就非常符合面向?qū)ο蟮乃枷肓耍?/p> 將數(shù)據(jù)封裝到Page中并在頁面上顯示分頁的數(shù)據(jù)

①:創(chuàng)建Page類


    //保存著分頁的數(shù)據(jù)
    private List list;

    //總記錄數(shù)
    private long totalRecord;

    //每頁顯示記錄數(shù),這里我規(guī)定每頁顯示3條
    private int linesize = 3;

    //總頁數(shù)
    private int totalPageCount;

    //當(dāng)前顯示的頁數(shù)
    private long currentPageCount;

    //...各種的setter、getter

②:BusinessService應(yīng)該提供獲取分頁數(shù)據(jù)的服務(wù)

    //既然Page對象代表是分頁數(shù)據(jù),那么返回Page對象即可!
    //web層應(yīng)該傳入想要看哪一頁數(shù)據(jù)的參數(shù)!
    public Page getPageData(String currentPageCount) {

        Page page = new Page();

        //獲取數(shù)據(jù)庫中有多少條記錄,并封裝到Page對象中
        Long totalRecord = customerDao.getTotalRecord();
        page.setTotalRecord(totalRecord);

        //算出總頁數(shù),并封裝到Page對象中
        int totalPagecount = (int) (totalRecord % page.getLinesize() == 0 ? totalRecord / page.getLinesize() : totalRecord / page.getLinesize() + 1);
        page.setTotalPageCount(totalPagecount);

        int start ;
        int end = page.getLinesize();

        //現(xiàn)在又分兩種情況了,如果傳遞進(jìn)來的參數(shù)是null的,那么說明外界是第一次查詢的
        if (currentPageCount == null) {

            //第一次查詢,就應(yīng)該設(shè)置當(dāng)前頁數(shù)是第一頁
            page.setCurrentPageCount(1);

            start = (int) ((page.getCurrentPageCount() - 1) * page.getLinesize());

            List customers = customerDao.getPageData(start, end);

            page.setList(customers);
        } else {

            //如果不是第一次,就把外界傳遞進(jìn)來的頁數(shù)封裝到Page對象中
            page.setCurrentPageCount(Long.parseLong(currentPageCount));

            start = (int) ((page.getCurrentPageCount() - 1) * page.getLinesize());

            List customers = customerDao.getPageData(start, end);

            page.setList(customers);

        }
        return page;

    }

③:web層調(diào)用BusinessService層的功能,獲取得到Page對象

        //獲取用戶想要看的頁數(shù),如果是第一次,那肯定為null
        String currentPageCount = request.getParameter("currentPageCount");

        //調(diào)用BusinessService的方法,獲取得到所有客戶信息
        BusinessService businessService = new BusinessService();
        Page page  = businessService.getPageData(currentPageCount);

        //把客戶信息帶過去給jsp頁面
        request.setAttribute("page", page);

        //跳轉(zhuǎn)到顯示客戶界面信息的jsp
        request.getRequestDispatcher("/WEB-INF/lookCustomer.jsp").forward(request, response);

④:在JSP頁面中,使用EL表達(dá)式獲取到Page對象,從而輸出數(shù)據(jù)

        
            
                ${customer.name}
                ${customer.gender}
                ${customer.birthday}
                ${customer.cellphone}
                ${customer.email}
                ${customer.preference}
                ${customer.type}
                ${customer.description}
            
        

⑤:在JSP頁面中顯示頁碼,同時把碼數(shù)綁定到超鏈接去!

    <%--提供頁數(shù)的界面--%>
    
        
            ${pageNum}
        
    

效果:

讓分頁的功能更加完善 增加上一步和下一步

一般的分頁不僅僅只有頁碼給你,還有上一步和下一步。我們在JSP頁面上也能添加這樣的功能,其實(shí)這是非常簡單的!


    <%--如果當(dāng)前的頁碼大于1,才顯示上一步--%>
    

        <%--把傳遞過去的頁碼-1就行了--%>
        
            上一步
        
    


    <%--如果當(dāng)前的頁碼小于總頁數(shù),才顯示下一步--%>
    

        <%--把傳遞過去的頁碼-1就行了--%>
        
            下一步
        
    

效果:

顯示當(dāng)前頁數(shù),總頁數(shù),總記錄數(shù)
    當(dāng)前頁數(shù)是:[${page.currentPageCount}]   

    總頁數(shù)是:${page.totalPageCount}  

    總記錄數(shù)是:${page.totalRecord}

效果:

跳轉(zhuǎn)到某頁上
    
    

頁面效果:

我們現(xiàn)在要做的就是:怎么樣才能輸入框輸入內(nèi)容,然后點(diǎn)擊跳轉(zhuǎn)按鈕,將輸入框的數(shù)據(jù)發(fā)送到Servlet上,然后實(shí)現(xiàn)跳轉(zhuǎn)到某頁上功能

明顯地,我們肯定要使用JavaScript代碼!



效果:

記錄JSP頁面的開始頁和結(jié)束頁

為什么我們要記錄JSP頁面的開始頁和結(jié)束頁呢?經(jīng)過上面層層地優(yōu)化,我們感覺不出有什么問題了。那是因?yàn)閿?shù)據(jù)量太少!

我們試著多添加點(diǎn)記錄進(jìn)數(shù)據(jù)庫,再回來看看!

從上面的圖我們可以發(fā)現(xiàn)頁數(shù)有多少,JSP頁面就顯示多少!這明顯不合理的,如果有100頁也顯示100頁嗎?

我們做一個規(guī)定,一次只能顯示10頁的數(shù)據(jù)。那么顯示哪10頁呢?這又是一個問題了,如果我們在看第11頁的數(shù)據(jù),應(yīng)該顯示的是第7到第16頁的數(shù)據(jù)(顯示11附近的頁數(shù)),我們在看第2頁的數(shù)據(jù),應(yīng)該顯示第1到第10頁的數(shù)據(jù)。用戶想要看的頁數(shù)是不明確的,我們顯示附近的頁數(shù)也是不明確的!我們應(yīng)該把用戶想要看的頁數(shù)記錄下來,然后根據(jù)邏輯判斷,顯示附近的頁數(shù)

我們顯示頁數(shù)的代碼是這樣的:

很明顯,我們只要控制了begin和end中的數(shù)據(jù),就控制顯示哪10頁了!

①在Page類中多定義兩個成員變量

    //記錄JSP頁面開始的頁數(shù)和結(jié)束的頁數(shù)
    private int startPage;
    private int endPage;

    //Setter,Getter方法

②開始頁數(shù)和結(jié)束頁數(shù)受用戶想看的頁數(shù)影響,在BusinessService的getPageData()加入下面的邏輯

            //第一次訪問
            page.setStartPage(1);
            page.setEndPage(10);
        


            //不是第一次訪問
            if (page.getCurrentPageCount() <= 10) {
                page.setStartPage(1);
                page.setEndPage(10);
            } else {
                page.setStartPage((int) (page.getCurrentPageCount() - 4));
                page.setEndPage((int) (page.getCurrentPageCount() + 5));

                //如果因?yàn)榧訙p角標(biāo)越界了,那么就設(shè)置最前10頁,或者最后10頁
                if (page.getStartPage() < 1) {
                    page.setStartPage(1);
                    page.setEndPage(10);
                }
                if (page.getEndPage() > page.getTotalPageCount()) {
                    page.setEndPage(page.getTotalPageCount());
                    page.setStartPage(page.getTotalPageCount() - 9);
                }
            }

③:在JSP顯示頁數(shù)時,獲取得到開始頁和結(jié)束頁就行了

    <%--提供頁數(shù)的界面--%>
    
        
                [${pageNum}] 
        
    

效果:

重構(gòu)優(yōu)化 分頁重構(gòu)

我們再回頭看看BusinessService中獲取分頁數(shù)據(jù)的代碼:

    //既然Page對象代表是分頁數(shù)據(jù),那么返回Page對象即可!
    //web層應(yīng)該傳入想要看哪一頁數(shù)據(jù)的參數(shù)!
    public Page getPageData(String currentPageCount) {

        Page page = new Page();

        //獲取數(shù)據(jù)庫中有多少條記錄,并封裝到Page對象中
        Long totalRecord = customerDao.getTotalRecord();
        page.setTotalRecord(totalRecord);

        //算出總頁數(shù),并封裝到Page對象中
        int totalPagecount = (int) (totalRecord % page.getLinesize() == 0 ? totalRecord / page.getLinesize() : totalRecord / page.getLinesize() + 1);
        page.setTotalPageCount(totalPagecount);

        int start ;
        int end = page.getLinesize();

        //現(xiàn)在又分兩種情況了,如果傳遞進(jìn)來的參數(shù)是null的,那么說明外界是第一次查詢的
        if (currentPageCount == null) {

            //第一次查詢,就應(yīng)該設(shè)置當(dāng)前頁數(shù)是第一頁
            page.setCurrentPageCount(1);

            page.setStartPage(1);
            page.setEndPage(10);

            start = (int) ((page.getCurrentPageCount() - 1) * page.getLinesize());

            List customers = customerDao.getPageData(start, end);

            page.setList(customers);
        } else {

            //如果不是第一次,就把外界傳遞進(jìn)來的頁數(shù)封裝到Page對象中
            page.setCurrentPageCount(Long.parseLong(currentPageCount));

            start = (int) ((page.getCurrentPageCount() - 1) * page.getLinesize());

            if (page.getCurrentPageCount() <= 10) {
                page.setStartPage(1);
                page.setEndPage(10);
            } else {
                page.setStartPage((int) (page.getCurrentPageCount() - 4));
                page.setEndPage((int) (page.getCurrentPageCount() + 5));

                //如果因?yàn)榧訙p角標(biāo)越界了,那么就設(shè)置最前10頁,或者最后10頁
                if (page.getStartPage() < 1) {
                    page.setStartPage(1);
                    page.setEndPage(10);
                }
                if (page.getEndPage() > page.getTotalPageCount()) {
                    page.setEndPage(page.getTotalPageCount());
                    page.setStartPage(page.getTotalPageCount() - 9);
                }
            }


            List customers = customerDao.getPageData(start, end);

            page.setList(customers);

        }
        return page;

    }

太太太太太tm復(fù)雜,太太太太tm長了?。。。。∥覀傿usinessService要做的僅僅是調(diào)用Dao層的功能,為web層提供數(shù)據(jù),但我們在方法中使用大量了邏輯判斷,而且這些邏輯判斷都是屬于Page類的!

明確一下:只有獲取數(shù)據(jù)庫總記錄數(shù)是在BusinessService中做的,其他的數(shù)據(jù)變量都是應(yīng)該在Page類中完成!

在BusinessService獲取了總記錄數(shù)之后,我們要對其他變量進(jìn)行初始化(根據(jù)總記錄數(shù),用戶想要看哪一頁的數(shù)據(jù)),算出其他的數(shù)據(jù)(JSP記錄開始頁數(shù)、結(jié)束頁數(shù)、總頁數(shù)等等),最好的辦法就是通過Page的構(gòu)造函數(shù)來實(shí)現(xiàn)初始化!

改良后的BusinessService


    public Page getPageData2(String currentPageCount) {

        //獲取得到總記錄數(shù)
        Long totalPageCount = customerDao.getTotalRecord();

        if (currentPageCount == null) {

            //如果是第一次,那么就將用戶想看的頁數(shù)設(shè)置為1
            Page page = new Page(1, totalPageCount);

            List customers = customerDao.getPageData(page.getStartIndex(), page.getLinesize());

            page.setList(customers);
            return page;

        } else {

            //如果不是第一次,就將獲取得到的頁數(shù)傳遞進(jìn)去
            Page page = new Page(Integer.parseInt(currentPageCount), totalPageCount);

            List customers = customerDao.getPageData(page.getStartIndex(), page.getLinesize());

            page.setList(customers);
            return page;
        }
    }

改良后的Page類(原來的Page類只有成員變量和setter、getter方法)


    public Page(int currentPageCount, long totalRecord) {


        //將傳遞進(jìn)來的currentPageCount初始化
        this.currentPageCount = currentPageCount;

        //總頁數(shù)
        totalPageCount = (int) (totalRecord % linesize == 0 ? totalRecord / linesize : totalRecord / linesize + 1);
        
        //總記錄數(shù)
        this.totalRecord = totalRecord;

        //開始取數(shù)據(jù)的位置
        startIndex = (currentPageCount - 1) * linesize;


        //如果當(dāng)前頁小于10,那么開始頁為1,結(jié)束頁為10就行了
        if (this.currentPageCount <= 10) {
            this.startPage = 1;
            this.endPage = 10;
        } else {
            startPage = this.currentPageCount - 4;
            endPage = this.currentPageCount + 5;

            //加減后頁數(shù)越界的情況
            if (startPage < 1) {
                this.startPage = 1;
                this.endPage = 10;
            }
            if (endPage > totalPageCount) {
                this.startPage = this.currentPageCount - 9;
                this.endPage = this.totalPageCount;
            }
        }

    }
分頁顯示頁面重構(gòu)

分頁的顯示頁面都是永恒不變的,我們可以把代碼重構(gòu)成一個jsp,需要用到分頁顯示頁面的地方,就包含進(jìn)去就行了!

page.jsp


    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%--顯示當(dāng)前頁數(shù)--%>
    當(dāng)前頁數(shù)是:[${page.currentPageCount}]   
    
    <%--如果當(dāng)前的頁碼大于1,才顯示上一步--%>
    
    
        <%--把傳遞過去的頁碼-1就行了--%>
        
            上一步
        
    
    
    <%--提供頁數(shù)的界面--%>
    
        
            [${page}] 
        
    
    
    <%--如果當(dāng)前的頁碼小于總頁數(shù),才顯示下一步--%>
    
    
        <%--把傳遞過去的頁碼-1就行了--%>
        
            下一步
          
    
    
    
    
    
    總頁數(shù)是:${page.totalPageCount}  
    
    總記錄數(shù)是:${page.totalRecord}
    
    
    

用需要用到的地方,導(dǎo)入即可!

    

為了做到更好的通用性,處理分頁數(shù)據(jù)的url應(yīng)該由Servlet傳進(jìn)去給Page類,讓Page類封裝起來!要使用的時候,再用Page取出來就行了。

下面寫法已經(jīng)固定了,不夠靈活!也就是說,下面的url地址不應(yīng)該寫死的

    ${pageContext.request.contextPath}/LookCustomer?currentPageCount=${page.currentPageCount+1}

我們可以這樣做:

在Controller上獲取Servlet的名稱,在傳遞用戶想要看的頁數(shù)的同時,把Servlet的url也傳遞進(jìn)去

        String servletName = this.getServletName();

        //調(diào)用BusinessService的方法,獲取得到所有客戶信息
        BusinessService businessService = new BusinessService();

        //把Servlet的url也傳遞進(jìn)去
        Page page = businessService.getPageData2(currentPageCount, request.getContextPath() + "/" + servletName);

在Page類上,多增加一個成員變量

    private String url;
    public String getUrl() {
        return url;
    }

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

在BusinessService接受到web層傳遞進(jìn)來的url,set到Page對象上就行了!

    page.setUrl(url);

我們在jsp頁面跳轉(zhuǎn)到處理分頁數(shù)據(jù)的Servlet上,就再不用寫死了。直接用Page對象中獲取出來就行了!

    <%--把傳遞過去的頁碼-1就行了--%>
    
        上一步
    

開發(fā)web的刪除和修改

在查詢jsp頁面上,增添刪除和修改的操作鏈接!

開發(fā)處理刪除操作的Servlet

超鏈接綁定要刪除用戶的id,帶過去給Controller

        刪除

controller的代碼也十分簡單:

        String id = request.getParameter("id");
        
        //調(diào)用BusinessService層的功能,就可以完成刪除操作了
        BusinessService businessService = new BusinessService();

        businessService.deleteCustomer(id);

刪除客戶記錄也是一件非常重要的事情,應(yīng)該提供JavaSrcript代碼詢問是否要真的刪除

在超鏈接控件上綁定事件!

       刪除
    function sureDelete() {
        var b = window.confirm("你確定要刪除嗎?");
        
        if(b) {
            return true;
        }else {
            return false;
        }
    }

測試:

修改操作

修改操作的流程是這樣的:點(diǎn)擊修改超鏈接,跳轉(zhuǎn)到該用戶的詳細(xì)信息頁面,在詳細(xì)信息頁面中修改數(shù)據(jù),再提交修改!【跳轉(zhuǎn)到用戶詳細(xì)信息頁面時,用戶的id還在的,在提交數(shù)據(jù)的時候,記得把id也給到服務(wù)器,【id是不包含在表單中的,要我們自己提交過去】!】

   修改
開發(fā)提供用戶詳細(xì)信息的Servlet
        String id = request.getParameter("id");
        BusinessService businessService = new BusinessService();
        
        //通過id獲取得到用戶的詳細(xì)信息
        Customer customer = businessService.findCustomer(id);

        request.setAttribute("customer", customer);
        //跳轉(zhuǎn)到顯示用戶詳細(xì)信息的jsp頁面上
        request.getRequestDispatcher("/WEB-INF/customerInformation").forward(request, response);
開發(fā)顯示用戶信息的JSP【數(shù)據(jù)回顯】

想要日期能夠選擇,記得導(dǎo)入JavaScript代碼,響應(yīng)事件!

注意:在顯示頁面上,一定要把id傳遞過去給處理表單的Servlet,不然服務(wù)器是不知道你要修改哪一條數(shù)據(jù)的!


    用戶詳細(xì)信息
    




    
用戶名:
性別
生日
電話號碼:
郵箱:
愛好: 唱歌 跳舞 打代碼
客戶類型 VIP 普通客戶 黑名單客戶
描述

效果:

處理修改表單數(shù)據(jù)的Servlet

        //將數(shù)據(jù)封裝到Bean中
        Customer customer = WebUtils.request2Bean(request, Customer.class);

        //將id封裝到Customer對象中?。?!不要忘了id?。。≡诒韱沃蝎@取到的數(shù)據(jù)是沒有id的?。。。?!記得?。。。?        customer.setId(request.getParameter("id"));
        
        //調(diào)用Service層的方法,實(shí)現(xiàn)修改
        BusinessService businessService = new BusinessService();
        businessService.updateCustomer(customer);
        
        //修改成功就跳回查看客戶界面
        request.getRequestDispatcher("/LookCustomer").forward(request, response);

效果:

總結(jié)

在dao層中,我們有添加客戶、通過id查找用戶、刪除用戶、修改用戶信息的方法。

日期我們一般用下拉框來給用戶選取,要想下拉框的信息有足夠多的數(shù)據(jù),我們需要用到JavaScript【DOM編程動態(tài)增加和修改數(shù)據(jù)】

javasrcipt文件不能放在WEB-INF目錄下面

日期的數(shù)據(jù)通過下拉框選取,年、月、日是分散的,我們需要把他們拼接,于是我們也用JavaScript來拼接【減低服務(wù)器端的壓力】

開發(fā)工具方法request2Bean,主要用到了BeanUtils框架,這樣就不用在Servlet一個一個封裝了。

在JSP判斷集合是否有元素時,我們可以用EL表達(dá)式${empty(集合)}。

如果記錄數(shù)有很多,我們應(yīng)該使用分頁技術(shù),一般地,我們使用Page類來封裝分頁的數(shù)據(jù)

要使用分頁技術(shù),就必須在數(shù)據(jù)庫用查詢總記錄數(shù),通過總記錄數(shù),就可以算出總頁數(shù)了【每頁顯示多少條記錄由我們說了算】

在dao層還要編寫獲取具體的分頁數(shù)據(jù),從哪里開始,哪里結(jié)束,返回一個List集合,再把List集合封裝到Page對象上

由于獲取分頁數(shù)據(jù)需要當(dāng)前的頁數(shù)是多少,(所以在service中要判斷當(dāng)前頁數(shù)是否存在,如果不存在,那么就設(shè)置為1)【更新,我認(rèn)為在Controller判斷會好一點(diǎn)】

分頁中,我們還支持上一頁和下一頁的功能,如果頁數(shù)大于1,才顯示上一頁,如果頁數(shù)小于1,才顯示下一頁。

給出下拉框進(jìn)行頁數(shù)跳轉(zhuǎn),使用JavaScript事件機(jī)制,獲取頁數(shù),再提交給Servlet處理即可

我們還要控制頁數(shù)的顯示,因?yàn)椴豢赡苡?00頁,我們就顯示100頁,這樣是不可能的。在Page類中維護(hù)兩個變量,startPage,endPage。我們規(guī)定每次只能顯示10頁數(shù)據(jù),如果第一次訪問就顯示1-10頁。如果當(dāng)前頁數(shù)大于10,那么就顯示6-15頁。如果角標(biāo)越界了,那么就顯示前10頁或者后10頁

我們把顯示分頁的頁面封裝成多帶帶的jsp,使用的Servlet連接也可以用url變量來維護(hù)。

前臺數(shù)據(jù)做拼接,最終都是把拼接好的數(shù)據(jù)用一個隱藏域封裝起來,隨后讓form表單一起提交

如果文章有錯的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章的同學(xué),想要獲取更多的Java資源的同學(xué),可以關(guān)注微信公眾號:Java3y

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/68586.html

相關(guān)文章

  • 深入分析JavaWeb Item1 -- JavaWeb開發(fā)入門

    摘要:中主要是使用語言。將的動態(tài)功能和標(biāo)準(zhǔn)的安全性引入大型網(wǎng)絡(luò)應(yīng)用的開發(fā)集成部署和管理之中。提供了一個圖形界面的管理工具,稱為信息服務(wù)管理器,可用于監(jiān)視配置和控制服務(wù)。 一、基本概念 1.1、WEB開發(fā)的相關(guān)知識   WEB,在英語中web即表示網(wǎng)頁的意思,它用于表示Internet主機(jī)上供外界訪問的資源?! nternet上供外界訪問的Web資源分為: 靜態(tài)web資源(如html 頁面...

    tinna 評論0 收藏0
  • JavaWeb從0開始學(xué)(一)-----第一個Web應(yīng)用程序與JSP工作原理

    摘要:當(dāng)后繼請求相同的頁面時,容器加載之前生成的類,并且通知去執(zhí)行已經(jīng)存在的字節(jié)碼,從而省去了轉(zhuǎn)換的過程,這也是第一次執(zhí)行頁面時間較長的原因。 以往學(xué)習(xí)的時候大多是看完書或者看完視頻,動手實(shí)踐一下就OK了。然而過了一段時間我發(fā)現(xiàn)東西都忘差不多了,需要復(fù)習(xí)才能重新掌握?,F(xiàn)在開始學(xué)習(xí)JavaWeb了,我將在這里記錄自己的學(xué)習(xí)的一點(diǎn)一滴,不僅便于自己以后回顧知識點(diǎn),也希望能對JavaWeb初學(xué)者有...

    CloudDeveloper 評論0 收藏0
  • 超詳細(xì)的Java面試題總結(jié)(四 )之JavaWeb基礎(chǔ)知識總結(jié)

    摘要:系列文章請查看超詳細(xì)的面試題總結(jié)一之基礎(chǔ)知識篇超詳細(xì)的面試題總結(jié)二之基礎(chǔ)知識篇超詳細(xì)的面試題總結(jié)三之集合篇常見問題下面的都是自己之前在學(xué)習(xí)的時候總結(jié)的,對于鞏固的基礎(chǔ)知識應(yīng)該有很大幫助。注意多線程的并發(fā)的讀寫類屬性會導(dǎo)致數(shù)據(jù)不同步。 系列文章請查看: 超詳細(xì)的Java面試題總結(jié)(一)之Java基礎(chǔ)知識篇 超詳細(xì)的Java面試題總結(jié)(二)之Java基礎(chǔ)知識篇 超詳細(xì)的Java面試題總結(jié)(...

    Leo_chen 評論0 收藏0
  • Javaweb Q&A

    摘要:方法的參數(shù)不但可以使相對于上下文根的路徑,而且可以是相對于當(dāng)前的路徑。如和都是合法的路徑。 轉(zhuǎn)發(fā)與重定向區(qū)別是什么 在調(diào)用方法上 轉(zhuǎn)發(fā) 調(diào)用 HttpServletRequest 對象的方法 request.getRequestDispatcher(test.jsp).forward(req, resp); 重定向 調(diào)用 HttpServletResponse 對象的方法 res...

    hiyang 評論0 收藏0
  • Nodejs和JavaWeb協(xié)助開發(fā)

    摘要:實(shí)現(xiàn)不同語言間進(jìn)行協(xié)助開發(fā),可以使用通信的方式來實(shí)現(xiàn),這次實(shí)現(xiàn)和的協(xié)助開發(fā),是項(xiàng)目主要服務(wù)端,由于要處理一些系統(tǒng)底層的事務(wù),所以要用提供一個輔助服務(wù),為主服務(wù)端處理相關(guān)事務(wù),以下是搭建流程和服務(wù)間通信原理。 實(shí)現(xiàn)不同語言間進(jìn)行協(xié)助開發(fā),可以使用通信的方式來實(shí)現(xiàn),這次實(shí)現(xiàn)Nodejs和JavaWeb的協(xié)助開發(fā),Nodejs是項(xiàng)目主要服務(wù)端,由于要處理一些系統(tǒng)底層的事務(wù),所以要用JavaW...

    HmyBmny 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<