Javaweb 第15天 web练习和分页技术
第15天 web练习和分页技术
复习day14内容:
学习新技术的思路?
分析功能的思路?
使用queryRunner操作数据库的步骤?
ResultSetHandler接口常用实现类(三个重点)?
今日任务
- 用户的联系人增删改查
- 联系人的条件查询、
- 分页技术实现
案例—添加联系人
画图分析
添加联系人功能:
回顾联系人管理系统需求:
1)使用添加联系人功能,必须要用户登录(session中必须要有loginUser),如果,没有登陆,让用户返回登陆页面。
2)不同用户,可以有同样的联系人,同一个用户,联系人不能重复
3)联系人不重复的情况下,数据库添加一条联系人的记录
画图分析:
代码实现
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("添加联系人异常");
}
}
案例—查询当前用户的全部联系人实现
查询全部联系人(当前登录用户的全部联系人)
查询全部联系人功能什么时候被调用?
- 用户登录之后,查询全部联系人功能被调用
获取到所有联系人数据之后将数据转发到welcome.jsp,显示所有联系人的数据。
- 添加联系人完成之后,查询全部联系人功能被调用
添加联系人完成之后,要看到添加的数据。
需要重新获取全部联系人数据,转发welcome.jsp页显示
- 修改联系人完成之后,查询全部联系人功能被调用
修改联系人完成之后,看到修改后的数据。
- 删除联系人完成之后,查询全部联系人功能被调用
同上
画图分析
代码实现
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修改:
案例--修改联系人分析(分两次请求)
效果是什么?
- 点击修改连接(第一次请求),在页面(upadateContact.jsp)上看到原来的数据
- 点击修改联系人按钮提交数据(第二次请求)
- 在welcome.jsp页面看到修改后的数据,通过调用findAllContactServlet,servlet获取所有的联系人,看到修改后的结果
画图分析
修改联系人流程一:
修改联系人流程二:
代码实现
修改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("修改指定的联系人数据失败");
}
}
案例--删除联系人实现
注意:一般来说,公司在做删除功能时候,不是真实的物理删除(执行delete语句),只会设置标记,标记这条数据失效。
为什么不删除数据?
数据是公司最宝贵的财富,根据数据可以做大数据分析
例子:根据订单的下单时间,下单金额,订单的地址,订单商品的信息——这个人什么时候发工资,薪资水平,去哪里偷东西,偷哪些贵重物品
智能推荐:确定推荐的时间,你需要的品牌,你附近的商家
传智播客:名字,上海地址,老家地址,专业,学历,年龄,来源,有无工作经验,是否在校
老家地址:下一个分校应该在哪里
专业:分析出,当前培训的市场扩张程度
学历:给就业部老师,指定相应的就业方案
年龄:招生的部门,主要的招生的年龄段
来源:老学员介绍,广告,优酷视频看到的,通过百度查询——下一个推广的主要方向
是否在校:第一,是否要开辟高校市场。第二,就业指导老师,准备相应的就业方案
功能的效果:
画图分析
注意:相关money的功能(加 减 乘 除 ,显示),相关用户的功能,一定要把用户当作小白,把用户的体验,能做多好就做多好
代码实现
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("删除指定的联系人数据失败");
}
}
案例--根据条件查询联系人实现
页面分析:
条件查询sql语句实现:
select * from contact where key like '%用户输入的查询内容(value)%';
要查询的数据库字段:是页面下拉框选择的内容(key)
用户输入的查询条件:是input输入框中用户输入的内容(value)
画图分析
代码实现
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("条件查询联系人数据失败");
}
}
案例--大结果集分页实现
分页介绍
大结果集: 一次性,从,数据库中,获取,大量(上万的数量)的,数据。
分页: 将数据分批次展示给用户
大结果集分页的技术需求(它因为什么原因诞生的):
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();
}
}
代码执行效果:
页面修改(功能展示)
页面修改结果:
分析——使用数据库分页技术实现分页效果,需要那些数据?
- 用户需要看到的数据的页码(pageNum)
- 当前联系人总数(total)
- 一页多少行(长度size)
- 尾页(end)
- 当前分页查询的结果(联系人数据data:List<Contact>)
Page类(封装分页数据的对象)书写
将复杂的数据,我们封装一个对象中,这个对象,我们取名字叫Page
符合面向对象思想,封装。
画图分析
代码实现
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修改:
案例—分页与条件查询组合实现(了解:内容)
画图分析
需求:将条件查询的结果,进行分页显示
页面修改
1)要分页请求中,必须包含条件请求参数
2)条件查询的请求中,必须包含分页请求的参数
组合查询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对象
// 注意:要将查询key和value都要保存到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对象
// 注意:要将查询key和value都要保存到request对象
request.setAttribute("page", page);
request.setAttribute("key", key);
request.setAttribute("value", value);
request.getRequestDispatcher("/welcome.jsp").forward(request, response);
}
}
组合查询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;
// 根据总记录数和长度,计算尾页
// 不能直接做除法:
条数据,应该有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;
}
组合查询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 没有数据
//所以,我们需要根据key和value的值,判断,应该生成什么样的sql语句
//定义一个集合用来存储数据,这个集合中的数据,会根据判断,变化
List<Object> list = new ArrayList<Object>();
list.add(u_id);
if(key !=null && !key.equals("")){
//表示当前key是有数据
//应该拼接上key和value值
//思考:因为有判断存在,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 = ?";
//在用户登录之后,默认查询所有数据,key和value是没有值得,sql语句需要根据key和value进行变化
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("获取联系人分页数据失败");
}
}
修改登录servlet
作业:参考课堂笔记完成案例功能
- 完成添加功能(25点积分)
- 完成查询全部联系人的功能(25点积分)
- 完成修改联系人的功能(25点积分)
- 完成删除联系人的功能(25点积分)
- 完成条件查询联系人的功能(25点积分)
- 完成大结果集分页功能(25点积分)
QQ:395793718
电话:13651825024
Javaweb 第15天 web练习和分页技术的更多相关文章
- ] 解决myeclipse中新建javaweb工程,无法使用Web App Libraries问题
] 解决myeclipse中新建javaweb工程,无法使用Web App Libraries问题 标签: myeclipsejavawebWeb App Libraries 2013-10-16 1 ...
- 1、javaweb学习之配置文件web.xml
今天这里主要讲述javaweb中的配置文件web.xml中的内容及其作用,都是基础部分,对于初学者需要好好掌握理解. 简单配置: <servlet> <servlet-name ...
- JavaWeb基本概念及web服务器
1.基本概念 1.1.前言 web开发: web,网页的意思,www.baidu.com 静态web html,css 提供给所有人看的数据始终不会发生变化! 动态web 淘宝,几乎是所有的网站: 提 ...
- JDBC 学习笔记(一)—— 基础知识 + 分页技术
本文目录: 1.JDBC简介 2.使用JDBC的步骤——第一个JDBC程序 3.DriverManager ——加载数据库驱动 4.数据库URL ——标识数据库的 ...
- 关于Ajax无刷新分页技术的一些研究 c#
关于Ajax无刷新分页技术的一些研究 c# 小弟新手,求大神有更好的解决方案,指教下~ 以前做项目,用过GridView的刷新分页,也用过EasyUI的封装好的分页技术,最近在老项目的基础上加新功能, ...
- Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE
1. 前言 Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Serve ...
- 新手入门:史上最全Web端即时通讯技术原理详解
前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...
- Web端即时通讯技术原理详解
前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...
- 改进Spring中的分页技术
Spring中有一个PagedListHolder,能够实现分页. 但此类有几个缺点: 1. 使用此类的代码比較繁琐 2. 此类存放的数据源是全部的记录集,即对于记录数为1000条的数据,即使我们仅仅 ...
随机推荐
- headfirst设计模式(1)—策略模式
什么是策略模式 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化(摘自百度百科) 关键字:算法封装,相互替换,独立变化 算法封装 ...
- [翻译]Webpack解惑
本文译自Webpack - The Confusing Parts,原文需FQ. Webpack现在是React应用程序标配的模块打包器,我估计Angular2和其他框架的用户也在大规模使用.我第一次 ...
- C#调用百度地图API
1.打开链接http://developer.baidu.com/map/jshome.htm这里有很多DEMO,或者你直接百度搜索"百度地图API",第一个就是.进入后有很多方向 ...
- [大山中学dp常练-4 Rounds]
Round#1 2016.9.28 这次晚练十分sb 有点浪费时间 全是dp题 先说过程 3分钟草了第一题之后感觉好像有点水 然后翻了翻题目 看了看第一第四题两颗星 其他三颗星 然后一下子第二题题目太 ...
- python学习——DAY1
日期:20170113 一.个人体会: 零基础学python,是艰辛的,需要付出和坚持. 关于流程图.我最开始画的是从上到下,再从左到右,画了很多重复的内容,单线程的流程图,看起来很容易理解,但是自己 ...
- vs 插件
Visual Assist 代码提示 Indent Guides
- Freeplane中的自动边线颜色功能
今天我将电脑上的Freeplane从1.3.11升级到了1.5.18.发现新版本已经没有了1.3.11中的菜单选项Format → “Automatic edge color”.搜索了一下才发现,该功 ...
- Vultr新加坡机房速度怎么样?值得购买吗?最新评测!
2016年9月,Vultr vps开通了新加坡Singapore机房线路.与知名的竞争对手Digitalocean和Linode一样,新加坡机房对亚洲速度友好,是讨用户欢心的一个进步. 但是,vult ...
- C# Where
判断一个字符串中是否包含字符串数组里的字符,恶意字符限制提交,一般人,包括最初的我,会这样写 public bool ValidateStr(string[] parms) { bool result ...
- ios开发设置不同字体
最近项目开发中遇到需要设置指定字体的需求,研究了一下字体设置,最后附有我写的一个小demo,先来看一下效果: 开始上网搜了一下,普遍说到以下方法 for(NSString *fontfamilynam ...