Javaweb 第15天 web练习和分页技术

第15天 web练习和分页技术

复习day14内容:

 

学习新技术的思路?

 

 

 

分析功能的思路?

 

 

 

使用queryRunner操作数据库的步骤?

 

 

ResultSetHandler接口常用实现类(三个重点)?

 

 

 

 

 

今日任务

  1. 用户的联系人增删改查
  2. 联系人的条件查询、
  3. 分页技术实现

 

  1. 案例—添加联系人

    1. 图分析

     

    添加联系人功能:

     

    回顾联系人管理系统需求:

    1)使用添加联系人功能,必须要用户登录(session中必须要有loginUser),如果,没有登陆,让用户返回登陆页面。

    2)不同用户,可以有同样的联系人,同一个用户,联系人不能重复

    3)联系人不重复的情况下,数据库添加一条联系人的记录

     

     

    画图分析:

     

     

     

    1. 代码实现

    Jsp:

     

    Servlet代码:

     

    package cn.itcast.web;

     

    import java.io.IOException;

    import java.lang.reflect.InvocationTargetException;

     

    import javax.servlet.ServletException;

    import javax.servlet.http.HttpServlet;

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

     

    import org.apache.commons.beanutils.BeanUtils;

     

    import cn.itcast.domain.Contact;

    import cn.itcast.domain.User;

    import cn.itcast.service.ContactService;

    import cn.itcast.service.impl.ContactServiceImpl;

     

    public class AddContactServlet extends HttpServlet {

     

        public void doGet(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

     

            request.setCharacterEncoding("utf-8");

            //第一步:校验登录

            User loginUser = (User)request.getSession().getAttribute("loginUser");

            if(loginUser == null){

                

                response.sendRedirect(request.getContextPath()+"/login.jsp");

                return;

            }

            //第二步:封装数据

            Contact con = new Contact();

            try {

                BeanUtils.populate(con, request.getParameterMap());

            } catch (Exception e) {

                //抓取异常的时候,根据需求去抓,不同的异常,不同处理

                e.printStackTrace();

            }

            //单独封装了u_id数据,这个数据是,表示当前联系人是哪个用户的

            con.setU_id(loginUser.getId());

            //第三步:调用service,添加联系人

            ContactService contactService = new ContactServiceImpl();

            int info = contactService.addContact(con);

            //第四步:根据返回值,处理

            if(info == 1){

                //添加成功,请求一个Servlet,获取所有当前用户的联系人数据

                //response.sendRedirect(request.getContextPath()+"/welcome.jsp");

                response.sendRedirect(request.getContextPath()+"/findAllContact");

                return;

            }else if(info == -1){

                //联系人重复

                request.setAttribute("msg", "联系人重复");

                request.getRequestDispatcher("/addContect.jsp").forward(request, response);

                return;

            }else{

                //服务器忙,请稍候再

                request.setAttribute("msg", "服务器忙,请稍候再试");

                request.getRequestDispatcher("/addContect.jsp").forward(request, response);

                return;

            }

        }

     

        public void doPost(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

            doGet(request, response);

        }

     

    }

     

     

     

    Service代码:

    接口:

     

    /**

         * 添加联系人方法

         * @param con

         * @return

         */

        int addContact(Contact con);

     

    实现类:

    private ContactDao contactDao = new ContactDaoImpl();

        

        @Override

        public int addContact(Contact con) {

            //查询数据库,联系人是否重复

            int info = contactDao.findContactByNameAndUid(con.getName(),con.getU_id());

            if(info == 1){

                //不重复,可以添加

                contactDao.addContact(con);

                return 1;

            }else{

                return -1;

            }

        }

     

     

     

    Dao代码:

    接口:

    /**

         * 根据用户id和联系人名称查询数据的方法

         * @param name

         * @param u_id

         * @return

         */

        int findContactByNameAndUid(String name, int u_id);

     

        /**

         * 添加联系人的方法

         * @param con

         */

        void addContact(Contact con);

    实现类:

    private QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

        @Override

        public int findContactByNameAndUid(String name, int u_id) {

            String sql = "select * from contact where name = ? and u_id = ?";

            try {

                Contact contact = qr.query(sql, new BeanHandler<Contact>(Contact.class), name,u_id);

                if(contact == null){

                    return 1;

                }else{

                    return -1;

                }

            } catch (SQLException e) {

                //e.printStackTrace();打印堆栈信息,包括了错误信息。后期需要写入日志,数据一定要保留起来

                e.printStackTrace();

                throw new RuntimeException("查询联系人异常");

            }

            

        }

     

        @Override

        public void addContact(Contact con) {

            String sql = "insert into contact values(null,?,?,?,?,?)";

            try {

                qr.update(sql,con.getU_id() ,con.getName(),con.getSex(),con.getAddress(),con.getTel());

            } catch (SQLException e) {

                e.printStackTrace();

                throw new RuntimeException("添加联系人异常");

            }

     

        }

     

     

  2. 案例—查询当前用户的全部联系人实现

    查询全部联系人(当前登录用户的全部联系人)

     

    查询全部联系人功能什么时候被调用?

     

    1. 用户登录之后,查询全部联系人功能被调用

      获取到所有联系人数据之后将数据转发到welcome.jsp,显示所有联系人的数据。

       

    2. 添加联系人完成之后,查询全部联系人功能被调用

      添加联系人完成之后,要看到添加的数据。

      需要重新获取全部联系人数据,转发welcome.jsp页显示

     

    1. 修改联系人完成之后,查询全部联系人功能被调用

      修改联系人完成之后,看到修改后的数据。

     

    1. 删除联系人完成之后,查询全部联系人功能被调用

      同上

    1. 图分析

    1. 代码实现

     

    loginServlet:

     

     

    findAllContactServlet:

     

    package cn.itcast.web;

     

    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.Contact;

    import cn.itcast.domain.User;

    import cn.itcast.service.ContactService;

    import cn.itcast.service.impl.ContactServiceImpl;

     

    public class FindAllContactServlet extends HttpServlet {

     

        public void doGet(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

     

            //校验登录

            User loginUser = (User)request.getSession().getAttribute("loginUser");

            if(loginUser == null){

                response.sendRedirect(request.getContextPath()+"/login.jsp");

                return;

            }

            //获取数据(u_id

            int u_id = loginUser.getId();

            //调用service方法

            ContactService contactService = new ContactServiceImpl();

            List<Contact> data = contactService.findAll(u_id);

            

            //将数据存入request,转发到welcome.jsp页面

            request.setAttribute("data", data);

            request.getRequestDispatcher("/welcome.jsp").forward(request, response);

        }

     

        public void doPost(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

            doGet(request, response);

        }

     

    }

     

     

    Service:

     

    接口:

    /**

         * 查询指定用户的所有联系人

         * @param u_id

         * @return

         */

        List<Contact> findAll(int u_id);

    实现类:

    public List<Contact> findAll(int u_id) {

            return contactDao.findAll(u_id);

        }

    Dao:

    接口:

    /**

         * 获取指定用户联系人的方法

         * @param u_id

         * @return

         */

        List<Contact> findAll(int u_id);

     

    实现类:

     

    public List<Contact> findAll(int u_id) {

            String sql = "select * from contact where u_id = ?";

            try {

                return qr.query(sql, new BeanListHandler<Contact>(Contact.class), u_id);

            } catch (SQLException e) {

                e.printStackTrace();

                throw new RuntimeException("获取指定的用户所有联系人失败");

            }

        }

    添加联系人servlet修改:

     

     

     

     

  3. 案例--修改联系人分析(分两次请求

    效果是什么?

     

    1. 点击修改连接(第一次请求),在页面(upadateContact.jsp)上看到原来的数据
    2. 点击修改联系人按钮提交数据(第二次请求)
    3. 在welcome.jsp页面看到修改后的数据,通过调用findAllContactServlet,servlet获取所有的联系人,看到修改后的结果

     

     

     

     

    1. 图分析

    修改联系人流程一:

     

    修改联系人流程二:

     

    1. 代码实现

    修改welcome.jsp页面:

     

     

    显示了当前联系人数据的id:

     

     

    修改updateContact.jsp页面:

     

    FindContactByIdServlet:

     

    package cn.itcast.web;

     

    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.Contact;

    import cn.itcast.domain.User;

    import cn.itcast.service.ContactService;

    import cn.itcast.service.impl.ContactServiceImpl;

     

    public class FindByIDServlet extends HttpServlet {

     

        public void doGet(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

     

            //校验登录

            User loginUser = (User)request.getSession().getAttribute("loginUser");

            if(loginUser == null){

                response.sendRedirect(request.getContextPath()+"/login.jsp");

                return;

            }

            //获取参数联系人id

            String parameter = request.getParameter("id");

            int id = Integer.parseInt(parameter);

            //调用service方法获取数据

            ContactService contactService = new ContactServiceImpl();

            Contact con = contactService.findById(id);

            //将数据转发到updateContact.jsp页面

            request.setAttribute("con", con);

            request.getRequestDispatcher("/updateContact.jsp").forward(request, response);

            

        }

     

        public void doPost(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

            doGet(request, response);

        }

     

    }

     

     

    Service:

    接口:

    /**

         * 根据id查询数据

         * @param id

         * @return

         */

        Contact findById(int id);

     

    实现类:

    public Contact findById(int id) {

            return contactDao.findById(id);

        }

     

    Dao:

    接口:

     

    /**

         * 根据id查询数据

         * @param id

         * @return

         */

        Contact findById(int id);

    实现类:

    public Contact findById(int id) {

            String sql = "select * from contact where id = ?";

            try {

                return qr.query(sql, new BeanHandler<Contact>(Contact.class), id);

            } catch (SQLException e) {

                e.printStackTrace();

                throw new RuntimeException("获取指定的联系人数据失败");

            }

        }

     

    修改操作UpdateContactServlet:

     

    package cn.itcast.web;

     

    import java.io.IOException;

    import java.lang.reflect.InvocationTargetException;

     

    import javax.servlet.ServletException;

    import javax.servlet.http.HttpServlet;

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

     

    import org.apache.commons.beanutils.BeanUtils;

     

    import cn.itcast.domain.Contact;

    import cn.itcast.domain.User;

    import cn.itcast.service.ContactService;

    import cn.itcast.service.impl.ContactServiceImpl;

     

    public class UpdateContactServlet extends HttpServlet {

     

        public void doGet(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

     

            request.setCharacterEncoding("utf-8");

            //校验登录

            User loginUser = (User)request.getSession().getAttribute("loginUser");

            if(loginUser == null){

                

                response.sendRedirect(request.getContextPath()+"/login.jsp");

                return;

            }

            //封装数据

            Contact con = new Contact();

            try {

                BeanUtils.populate(con, request.getParameterMap());

            } catch (Exception e) {

                e.printStackTrace();

            }

            //调用service

            ContactService contactService = new ContactServiceImpl();

            contactService.updateContact(con);

            //调用findAllContact查看效果

            response.sendRedirect(request.getContextPath()+"/findAllContact");

            

        }

     

        public void doPost(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

            doGet(request, response);

        }

     

    }

     

     

     

    Service:

    接口:

     

    /**

         * 修改联系人

         * @param con

         */

        void updateContact(Contact con);

     

    实现类:

    public void updateContact(Contact con) {

            contactDao.updateContact(con);

        }

     

    Dao:

    接口:

    /**

         * 修噶联系人

         * @param con

         */

        void updateContact(Contact con);

    实现类:

    public void updateContact(Contact con) {

            String sql = "update contact set name = ? , sex = ? , tel = ? , address = ? where id = ?";

            try {

                qr.update(sql, con.getName(),con.getSex(),con.getTel(),con.getAddress(),con.getId());

            } catch (SQLException e) {

                e.printStackTrace();

                throw new RuntimeException("修改指定的联系人数据失败");

            }

        }

     

     

     

  4. 例--删除联系人实现

    注意:一般来说,公司在做删除功能时候,不是真实的物理删除(执行delete语句),只会设置标记,标记这条数据失效。

     

    为什么不删除数据?

    数据是公司最宝贵的财富,根据数据可以做大数据分析

    例子:根据订单的下单时间,下单金额,订单的地址,订单商品的信息——这个人什么时候发工资,薪资水平,去哪里偷东西,偷哪些贵重物品

     

    智能推荐:确定推荐的时间,你需要的品牌,你附近的商家

     

    传智播客:名字,上海地址,老家地址,专业,学历,年龄,来源,有无工作经验,是否在校

     

    老家地址:下一个分校应该在哪里

    专业:分析出,当前培训的市场扩张程度

    学历:给就业部老师,指定相应的就业方案

    年龄:招生的部门,主要的招生的年龄段

    来源:老学员介绍,广告,优酷视频看到的,通过百度查询——下一个推广的主要方向

    是否在校:第一,是否要开辟高校市场。第二,就业指导老师,准备相应的就业方案

     

     

    功能的效果:

     

    1. 画图分析

     

     

    注意:相关money的功能(加 减 乘 除 ,显示),相关用户的功能,一定要把用户当作小白,把用户的体验,能做多好就做多好

     

    1. 代码实现

    Welcome.jsp修改:

     

    Servlet代码:

     

    package cn.itcast.web;

     

    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.User;

    import cn.itcast.service.ContactService;

    import cn.itcast.service.impl.ContactServiceImpl;

     

    public class DeleteServlet extends HttpServlet {

     

        public void doGet(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

     

            //校验登录

            User loginUser = (User)request.getSession().getAttribute("loginUser");

            if(loginUser == null){

                

                response.sendRedirect(request.getContextPath()+"/login.jsp");

                return;

            }

            //获取数据 id

            int id = Integer.parseInt(request.getParameter("id"));

            //调用service方法删除数据

            ContactService contactService = new ContactServiceImpl();

            contactService.delete(id);

            

            //调用findAllContact查看删除效果

            response.sendRedirect(request.getContextPath()+"/findAllContact");

        }

     

        public void doPost(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

            doGet(request, response);

        }

     

    }

     

     

     

    Service代码:

    接口:

    /**

         * 删除操作

         * @param id

         */

        void delete(int id);

    实现类:

     

    public void delete(int id) {

            contactDao.delete(id);

        }

    Dao代码:

     

    接口:

    /**删除操作

         * @param id

         */

        void delete(int id);

    实现类:

     

    public void delete(int id) {

            String sql = "delete from contact where id = ?";

            try {

                qr.update(sql, id);

            } catch (SQLException e) {

                e.printStackTrace();

                throw new RuntimeException("删除指定的联系人数据失败");

            }

            

        }

  5. 案例--根据条件查询联系人实现

    页面分析:

     

     

    条件查询sql语句实现:

     

    select * from contact where key like '%用户输入的查询内容(value)%';

     

    要查询的数据库字段:是页面下拉框选择的内容(key)

    用户输入的查询条件:是input输入框中用户输入的内容(value)

    1. 画图分析

     

     

    1. 代码实现

     

    Servlet:

     

    package cn.itcast.web;

     

    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.Contact;

    import cn.itcast.domain.User;

    import cn.itcast.service.ContactService;

    import cn.itcast.service.impl.ContactServiceImpl;

     

    public class FindByKeyServlet extends HttpServlet {

     

        public void doGet(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

     

            request.setCharacterEncoding("utf-8");

            //校验登录

            User loginUser = (User)request.getSession().getAttribute("loginUser");

            if(loginUser == null){

                response.sendRedirect(request.getContextPath()+"/login.jsp");

                return;

            }

            //获取数据(key :查询字段name tel address || value :用户输入的模糊查询的条件 || u_id 当前用户

            String key = request.getParameter("key");

            String value = request.getParameter("value");

            int u_id = loginUser.getId();

            //调用service方法获取数据

            ContactService contactService = new ContactServiceImpl();

            List<Contact> data = contactService.findByKey(key ,value, u_id);

            //将数据转发到welcome.jsp页面

            request.setAttribute("data", data);

            request.getRequestDispatcher("/welcome.jsp").forward(request, response);

        }

     

        public void doPost(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

            doGet(request, response);

        }

     

    }

     

     

     

    Service:

     

    接口:

    /**

         * 条件查询方法

         * @param key 查询字段

         * @param value :用户输入的查询内容

         * @param u_id 当前用户id

         * @return

         */

        List<Contact> findByKey(String key, String value, int u_id);

     

    实现类:

     

    public List<Contact> findByKey(String key, String value, int u_id) {

            

            return contactDao.findByKey(key,value,u_id);

        }

    Dao:

    接口:

     

    /**

         * 条件查询的方法

         * @param key

         * @param value

         * @param u_id

         * @return

         */

        List<Contact> findByKey(String key, String value, int u_id);

     

    实现类:

    public List<Contact> findByKey(String key, String value, int u_id) {

            String sql = "select * from contact where "+ key +" like ? and u_id = ?";

            try {

                return qr.query(sql, new BeanListHandler<Contact>(Contact.class), "%"+value+"%",u_id);

            } catch (SQLException e) {

                e.printStackTrace();

                throw new RuntimeException("条件查询联系人数据失败");

            }

        }

  6. 案例--大结果集分页实现

    1. 分页介绍

    大结果集: 一次性,从,数据库中,获取,大量(上万的数量)的,数据。

    分页: 将数据分批次展示给用户

     

     

    大结果集分页的技术需求(它因为什么原因诞生的):

     

    1)物理计算机的瓶颈(内存瓶颈),如果给一个只有1千万数据内存的机器,给了2千万数据。数据溢出。

     

    一个水桶,只能装1L水,现在我给他灌2L的水,肯定有1L的水溢出,浪费了。

    2)封装数据到对象,过程十分慢长(这个漫长是数据量太大),这样的用户体验非常差

    假设:有一个超级机器,内存无限的,1个数据要1秒钟,1千万数据,一千万秒。

     

     

    补充:用户等待一个功能响应,一般只会等多久?

    跟据不同的信息内容,不同。

    查看商品,用户不喜欢等待,而且有代替方案,一般5到15秒。

    支付,等30秒左右

    抢票,不要动我的手机,我正在抢票,等待时间3分钟。

     

     

     

    分页技术的实现:数据库实现,内存实现(redis数据库)

     

     

    数据库实现:通过关键字,限制一次性从数据库中获取数据的起始位置和长度。

     

    起始位置:数据从哪一行开始获取。

    长度:一次性获取数据的量。

     

    MySql关键字:limit

     

    Select * from contact where key =? limit ?,?

     

    第一个问号:起始位置

    第二个问号:长度

     

     

    代码测试:

    //测试数据库分页

    //测试数据库分页

        @Test

        public void test1(){

            

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            //第一个?:起始位置第二个?:长度

            String sql = "select * from contact limit ?,?";

            try {

                List<Contact> list = qr.query(sql, new BeanListHandler<Contact>(Contact.class), 10,10);

                System.out.println(list);

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

    效果截图:

     

     

     

    内存分页实现:

     

    先将数据从数据库中获取出来,将数据存入缓存(list集合)中,将数据分批次展示给用户。

     

    缓存:内存中开辟的空间,专门用来存储数据的

     

    代码测试:

     

    //测试内存分页

            @Test

            public void test2(){

                

                QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

                //第一个?:起始位置第二个?:长度

                String sql = "select * from contact";

                try {

                    List<Contact> list = qr.query(sql, new BeanListHandler<Contact>(Contact.class));

                    //list集合中的数据分批次展示给用户

                    List<Contact> subList = list.subList(3, 6);

                    System.out.println(subList);

                } catch (SQLException e) {

                    e.printStackTrace();

                }

            }

     

    代码执行效果:

     

    1. 页面修改(功能展示)

     

    页面修改结果:

     

     

    分析——使用数据库分页技术实现分页效果,需要那些数据?

     

    1. 用户需要看到的数据的页码(pageNum)
    2. 当前联系人总数(total)
    3. 一页多少行(长度size)
    4. 尾页(end)
    5. 当前分页查询的结果(联系人数据data:List<Contact>)

     

    1. Page类(封装分页数据的对象)书写

     

    将复杂的数据,我们封装一个对象中,这个对象,我们取名字叫Page

    符合面向对象思想,封装。

     

     

    1. 画图分析

     

     

    1. 代码实现

     

     

    Servlet:

    package cn.itcast.web;

     

    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.Page;

    import cn.itcast.domain.User;

    import cn.itcast.service.ContactService;

    import cn.itcast.service.impl.ContactServiceImpl;

     

    public class QueryPageServlet extends HttpServlet {

     

        public void doGet(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

     

            //校验登录

            User loginUser = (User)request.getSession().getAttribute("loginUser");

            if(loginUser == null){

                response.sendRedirect(request.getContextPath()+"/login.jsp");

                return;

            }

            //获取数据

            int pageNum = Integer.parseInt(request.getParameter("pageNum"));

            int u_id = loginUser.getId();

            //调用service方法获取数据

            ContactService contactService = new ContactServiceImpl();

            Page page = contactService.queryPage(u_id,pageNum);

            //将数据转发到welcome.jsp页面

            request.setAttribute("page", page);

            request.getRequestDispatcher("/welcome.jsp").forward(request, response);

        }

     

        public void doPost(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

            doGet(request, response);

        }

     

    }

     

     

    Service:

    接口:

    /**

         * 分页查询的方法

         * @param u_id

         * @param pageNum

         * @return

         */

        Page queryPage(int u_id, int pageNum);

    实现类:

     

    public Page queryPage(int u_id, int pageNum) {

            //获取总记录数据

            int total = contactDao.count(u_id);

            

            //定义长度

            int size = 10;

            //计算尾页

            //total size end %

            //100 10 10 0

            //101 10 11 1

            int end = total % size == 0 ? (total / size) :(total / size)+1;

            //计算起始位置

            int startIndex = (pageNum - 1) * size;

            //获取联系人数据

            List<Contact> data = contactDao.queryPage(u_id ,startIndex,size);

            //封装数据到page对象

            Page page = new Page();

            page.setData(data);

            page.setEnd(end);

            page.setPageNum(pageNum);

            page.setSize(size);

            page.setTotal(total);

            //返回page

            return page;

        }

    Dao:

    接口:

     

    /**

         * 获取总记录数

         * @param u_id

         * @return

         */

        int count(int u_id);

     

        /**

         * 获取联系人数据

         * @param u_id

         * @param startIndex

         * @param size

         * @return

         */

        List<Contact> queryPage(int u_id, int startIndex, int size);

     

    实现类:

     

    public int count(int u_id) {

            String sql = "select count(*) from contact where u_id = ? ";

            //ScalarHandler:封装count avg max min 。。。。函数执行结果

            try {

                //Long:一般数据的总数,使用int 类型存不下的

                Long long1 = qr.query(sql, new ScalarHandler<Long>(), u_id);

                return long1.intValue();

            } catch (SQLException e) {

                e.printStackTrace();

                throw new RuntimeException("分页总数获取失败");

            }

        }

     

        @Override

        public List<Contact> queryPage(int u_id, int startIndex, int size) {

            String sql = "select * from contact where u_id = ? limit ?,?";

            try {

                return qr.query(sql, new BeanListHandler<Contact>(Contact.class), u_id,startIndex,size);

            } catch (SQLException e) {

                e.printStackTrace();

                throw new RuntimeException("分页联系人数据获取失败");

            }

        }

    loginServlet:

     

     

    Welcome.jsp修改:

     

  7. 案例—分页与条件查询组合实现(了解:内容)

    画图分析

    需求:将条件查询的结果,进行分页显示

     

    1. 页面修改

    1)要分页请求中,必须包含条件请求参数

    2)条件查询的请求中,必须包含分页请求的参数

    1. 组合查询servlet

    package cn.itcast.web;

     

    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.Page;

    import cn.itcast.domain.User;

    import cn.itcast.service.ContactService;

    import cn.itcast.service.impl.ContactServiceImpl;

     

    public class QueryPageServlet2 extends HttpServlet {

     

        public void doGet(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

     

            // 校验登陆

            User loginUser = (User) request.getSession().getAttribute("loginUser");

            if (loginUser == null) {

                response.sendRedirect(request.getContextPath() + "/login.jsp");

                return;

            }

            // 获取数据

            String key = request.getParameter("key");

            String value = request.getParameter("value");

            // 处理中文乱码

            if(value == null){

                value = "";

            }

            value = new String(value.getBytes("iso-8859-1"), "utf-8");

            int pageNum = Integer.parseInt(request.getParameter("pageNum"));

            int u_id = loginUser.getId();

            // 调用service方法

            ContactService contactService = new ContactServiceImpl();

            Page page = contactService.queryPage2(key, value, pageNum, u_id);

            // 展示数据

            // 除了要将分页(page)数据保存到request对象

            // 注意:要将查询keyvalue都要保存到request对象

            request.setAttribute("page", page);

            request.setAttribute("key", key);

            request.setAttribute("value", value);

            request.getRequestDispatcher("/welcome.jsp").forward(request, response);

     

        }

     

        public void doPost(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

            // 处理中文乱码

            request.setCharacterEncoding("utf-8");

            // 校验登陆

            User loginUser = (User) request.getSession().getAttribute("loginUser");

            if (loginUser == null) {

                response.sendRedirect(request.getContextPath() + "/login.jsp");

                return;

            }

            // 获取数据

            String key = request.getParameter("key");

            String value = request.getParameter("value");

            int pageNum = Integer.parseInt(request.getParameter("pageNum"));

            int u_id = loginUser.getId();

            // 调用service方法

            ContactService contactService = new ContactServiceImpl();

            Page page = contactService.queryPage2(key, value, pageNum, u_id);

            // 展示数据

            // 除了要将分页(page)数据保存到request对象

            // 注意:要将查询keyvalue都要保存到request对象

            request.setAttribute("page", page);

            request.setAttribute("key", key);

            request.setAttribute("value", value);

            request.getRequestDispatcher("/welcome.jsp").forward(request, response);

        }

     

    }

     

     

    1. 组合查询service

    接口:

    /**

         * 条件查询和分页方法

         * @param key

         * @param value

         * @param pageNum

         * @param u_id

         * @return

         */

        Page queryPage2(String key, String value, int pageNum, int u_id);

    实现类:

        public Page queryPage2(String key, String value, int pageNum, int u_id) {

            // 获取总记录数

            int total = contactDao.count2(u_id,key,value);

            // 定义长度

            int size = 3;

            // 根据总记录数和长度,计算尾页

            // 不能直接做除法:

            // 如果有101条数据,应该有11页,但是除法运算,结果:10

            int end = total % size == 0 ? (total / size) : (total / size) + 1;

            // 计算数据库查询的起始位置

            // 第一页:pageNum=1 1-1=0 0*size = 0

            // 第二页:pageNum=2 2-1=1 1*size = 10

            // 第三页:pageNum=3 3-1=2 2*size = 20

            int startIndex = (pageNum - 1) * size;

            // 获取联系人数据

            List<Contact> data = contactDao.queryPage2(u_id,key,value, startIndex, size);

            // 创建对象封装数据(page

            Page p = new Page();

            p.setData(data);

            p.setEnd(end);

            p.setPageNum(pageNum);

            p.setSize(size);

            p.setTotal(total);

            // 返回page

            return p;

        }

    1. 组合查询dao

    接口:

     

    /**

         * 条件查询和分页——获取总记录数据

         * @param u_id

         * @param key

         * @param value

         * @return

         */

        int count2(int u_id, String key, String value);

     

        /**

         * 条件查询和分页——获取联系人数据

         * @param u_id

         * @param key

         * @param value

         * @param startIndex

         * @param size

         * @return

         */

        List<Contact> queryPage2(int u_id, String key, String value,

                int startIndex, int size);

     

    实现类:

     

    @Override

        public int count2(int u_id, String key, String value) {

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            String sql = "select count(*) from contact where u_id = ?";

            //思考:用户登录之后,默认查询当前用户全部联系人,key value 没有数据

            //所以,我们需要根据keyvalue的值,判断,应该生成什么样的sql语句

            //定义一个集合用来存储数据,这个集合中的数据,会根据判断,变化

            List<Object> list = new ArrayList<Object>();

            list.add(u_id);

            if(key !=null && !key.equals("")){

                //表示当前key是有数据

                //应该拼接上keyvalue

                //思考:因为有判断存在,sql语句的参数,有时候是一个问号,有时是两个问号

                sql = sql + " and "+key+" like ?";

                list.add("%"+value+"%");

            }

            

            try {

                Long long1 = qr.query(sql, new ScalarHandler<Long>(),list.toArray());

                return long1.intValue();

            } catch (SQLException e) {

                e.printStackTrace();

                throw new RuntimeException("获取联系人总数失败");

            }

        }

     

        @Override

        public List<Contact> queryPage2(int u_id, String key, String value,

                int startIndex, int size) {

            QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());

            String sql = "select * from contact where u_id = ?";

            //在用户登录之后,默认查询所有数据,keyvalue是没有值得,sql语句需要根据keyvalue进行变化

            List<Object> list = new ArrayList<Object>();

            list.add(u_id);

            if(key !=null && !key.equals("")){

                sql = sql + " and "+key+" like ?";

                list.add("%"+value+"%");

            }

            sql = sql + " limit ?,?";

            list.add(startIndex);

            list.add(size);

            try {

                return qr.query(sql, new BeanListHandler<Contact>(Contact.class), list.toArray());

            } catch (SQLException e) {

                e.printStackTrace();

                throw new RuntimeException("获取联系人分页数据失败");

            }

        }

     

    1. 修改登录servlet

     

    作业:参考课堂笔记完成案例功能

    1. 完成添加功能(25点积分)
    2. 完成查询全部联系人的功能(25点积分)
    3. 完成修改联系人的功能(25点积分)
    4. 完成删除联系人的功能(25点积分)
    5. 完成条件查询联系人的功能(25点积分)
    6. 完成大结果集分页功能(25点积分)

     

    QQ:395793718

    电话:13651825024

posted @ 2017-01-10 21:35  beyondcj  阅读(2513)  评论(0编辑  收藏  举报