《旅游网》综合案例
源码地址:https://github.com/xu-hao-tian/travel
1 前言
巩固web基础知识,提升综合运用能力。
二项目导入
点击绿色+按钮
选择travel项目的pom.xml文件,点击ok,完成项目导入。需要等待一小会,项目初始化完成。
3 启动项目
3.1 方式一:
3.2 方式二:配置maven快捷启动
4 技术选型
4.1 Web层
- Servlet:前端控制器
- html:视图
- Filter:过滤器
- BeanUtils:数据封装
-
4.2 Service层
Javamail:java发送邮件工具
- Redis:nosql内存数据库
-
4.3 Dao层
Mysql:数据库
- Druid:数据库连接池
- JdbcTemplate:jdbc的工具
5 创建数据库
— 创建数据库
CREATE DATABASE travel;
— 使用数据库
USE travel;
—创建表
复制提供好的sql
6 注册功能
6.1 页面效果
6.2 功能分析
6.3 代码实现
6.3.1 前台代码实现
6.3.2 表单校验
提升用户体验,并减轻服务器压力。<br />//校验用户名<br />//单词字符,长度8到20位**function **_checkUsername_() {<br /> //1.获取用户名值<br /> **var **username = **$**(**"#username"**).val();<br /> //2.定义正则<br /> **var **reg_username = /^\w{8,20}$/;<br /> <br /> //3.判断,给出提示信息<br /> **var **flag = reg_username.test(username);<br /> **if**(flag){<br /> //用户名合法<br /> **$**(**"#username"**).css(**"border"**,**""**);<br /> }**else**{<br /> //用户名非法,加一个红色边框<br /> **$**(**"#username"**).css(**"border"**,**"1px solid red"**);<br /> }<br /> <br /> **return **flag;<br /> }
//校验密码<br /> **function **_checkPassword_() {<br /> //1.获取密码值<br /> **var **password = **$**(**"#password"**).val();<br /> //2.定义正则<br /> **var **reg_password = /^\w{8,20}$/;
//3.判断,给出提示信息<br /> **var **flag = reg_password.test(password);<br /> **if**(flag){<br /> //密码合法<br /> **$**(**"#password"**).css(**"border"**,**""**);<br /> }**else**{<br /> //密码非法,加一个红色边框<br /> **$**(**"#password"**).css(**"border"**,**"1px solid red"**);<br /> }
**return **flag;<br /> }
//校验邮箱**function **_checkEmail_(){<br /> //1.获取邮箱<br /> **var **email = **$**(**"#email"**).val();<br /> //2.定义正则 itcast@163.com<br /> **var **reg_email = /^\w+@\w+\.\w+$/;
//3.判断
var flag = reg_email.test(email);
if(flag){
$(“#email”).css(“border”,“”);
}else{
$(“#email”).css(“border”,“1px solid red”);
}
return flag;
}
$(function () {
//当表单提交时,调用所有的校验方法
$(“#registerForm”).submit(function(){
**return **_checkUsername_() && _checkPassword_() && _checkEmail_();<br /> //如果这个方法没有返回值,或者返回为true,则表单提交,如果返回为false,则表单不提交<br /> });
//当某一个组件失去焦点是,调用对应的校验方法<br /> **$**(**"#username"**).blur(_checkUsername_);<br /> **$**(**"#password"**).blur(_checkPassword_);<br /> **$**(**"#email"**).blur(_checkEmail_);
});
6.3.3 异步(ajax)提交表单
在此使用异步提交表单是为了获取服务器响应的数据。因为我们前台使用的是html作为视图层,不能够直接从servlet相关的域对象获取值,只能通过ajax获取响应数据<br />![](https://cdn.nlark.com/yuque/0/2021/png/22277845/1627874035313-fb60126a-b16f-4662-a758-31034b78cbad.png#id=Uh5mX&originHeight=283&originWidth=789&originalType=binary&ratio=1&status=done&style=none)
6.3.4 后台代码实现
6.3.5 编写RegistUserServlet
@WebServlet(“/registUserServlet”)public class RegistUserServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//验证校验<br /> String check = request.getParameter(**"check"**);<br /> //从sesion中获取验证码<br /> HttpSession session = request.getSession();<br /> String checkcode_server = (String) session.getAttribute(**"CHECKCODE_SERVER"**);<br /> session.removeAttribute(**"CHECKCODE_SERVER"**);//为了保证验证码只能使用一次<br /> //比较<br /> **if**(checkcode_server == **null **|| !checkcode_server.equalsIgnoreCase(check)){<br /> //验证码错误<br /> ResultInfo info = **new **ResultInfo();<br /> //注册失败<br /> info.setFlag(**false**);<br /> info.setErrorMsg(**"验证码错误"**);<br /> //将info对象序列化为json<br /> ObjectMapper mapper = **new **ObjectMapper();<br /> String json = mapper.writeValueAsString(info);<br /> response.setContentType(**"application/json;charset=utf-8"**);<br /> response.getWriter().write(json);<br /> **return**;<br /> }
//1.获取数据<br /> Map<String, String[]> map = request.getParameterMap();
//2.封装对象<br /> User user = **new **User();<br /> **try **{<br /> BeanUtils._populate_(user,map);<br /> } **catch **(IllegalAccessException e) {<br /> e.printStackTrace();<br /> } **catch **(InvocationTargetException e) {<br /> e.printStackTrace();<br /> }
//3.调用service完成注册<br /> UserService service = **new **UserServiceImpl();<br /> **boolean **flag = service.regist(user);<br /> ResultInfo info = **new **ResultInfo();<br /> //4.响应结果<br /> **if**(flag){<br /> //注册成功<br /> info.setFlag(**true**);<br /> }**else**{<br /> //注册失败<br /> info.setFlag(**false**);<br /> info.setErrorMsg(**"注册失败!"**);<br /> }
//将info对象序列化为json<br /> ObjectMapper mapper = **new **ObjectMapper();<br /> String json = mapper.writeValueAsString(info);
//将json数据写回客户端<br /> //设置content-type<br /> response.setContentType(**"application/json;charset=utf-8"**);<br /> response.getWriter().write(json);
}
**protected void **doGet(HttpServletRequest request, HttpServletResponse response) **throws **ServletException, IOException {<br /> **this**.doPost(request, response);<br /> }<br />}
6.3.6 编写UserService以及UserServiceImpl
public class UserServiceImpl implements UserService {
**private **UserDao **userDao **= **new **UserDaoImpl();<br /> /**<br /> * 注册用户<br /> * **@param _user<br />__ _*** **@return<br /> ***/<br /> @Override<br /> **public boolean **regist(User user) {<br /> //1.根据用户名查询用户对象<br /> User u = **userDao**.findByUsername(user.getUsername());<br /> //判断u是否为null<br /> **if**(u != **null**){<br /> //用户名存在,注册失败<br /> **return false**;<br /> }<br /> //2.保存用户信息<br /> **userDao**.save(user);<br /> **return true**;<br /> }<br />}
6.3.7 编写UserDao以及UserDaoImpl
public class UserDaoImpl implements UserDao {
**private **JdbcTemplate **template **= **new **JdbcTemplate(JDBCUtils._getDataSource_());
@Override<br /> **public **User findByUsername(String username) {<br /> User user = **null**;<br /> **try **{<br /> //1.定义sql<br /> String sql = **"select **_*_** from tab_user where username = ?"**;<br /> //2.执行sql<br /> user = **template**.queryForObject(sql, **new **BeanPropertyRowMapper<User>(User.**class**), username);<br /> } **catch **(Exception e) {
}
**return **user;<br /> }
@Override<br /> **public void **save(User user) {<br /> //1.定义sql<br /> String sql = **"insert into tab_user(username,password,name,birthday,sex,telephone,email) values(?,?,?,?,?,?,?)"**;<br /> //2.执行sql
**template**.update(sql,user.getUsername(),<br /> user.getPassword(),<br /> user.getName(),<br /> user.getBirthday(),<br /> user.getSex(),<br /> user.getTelephone(),<br /> user.getEmail());<br /> }<br />}
6.3.8 邮件激活
为什么要进行邮件激活?为了保证用户填写的邮箱是正确的。将来可以推广一些宣传信息,到用户邮箱中。
6.3.9 发送邮件
- 申请邮箱
- 开启授权码
- 在MailUtils中设置自己的邮箱账号和密码(授权码)
邮件工具类:MailUtils,调用其中sendMail方法可以完成邮件发送
6.3.10 用户点击邮件激活
经过分析,发现,用户激活其实就是修改用户表中的status为‘Y’
分析:
发送邮件代码:
修改保存Dao代码,加上存储status和code 的代码逻辑
激活代码实现:
ActiveUserServlet
//1.获取激活码String code = request.getParameter(“code”);if(code != null){
//2.调用service完成激活
UserService service = new UserServiceImpl();
boolean flag = service.active(code);
//3.判断标记<br /> String msg = **null**;<br /> **if**(flag){<br /> //激活成功<br /> msg = **"激活成功,请<a href='login.html'>登录</a>"**;<br /> }**else**{<br /> //激活失败<br /> msg = **"激活失败,请联系管理员!"**;<br /> }<br /> response.setContentType(**"text/html;charset=utf-8"**);<br /> response.getWriter().write(msg);
UserService:active
@Overridepublic boolean active(String code) {
//1.根据激活码查询用户对象
User user = userDao.findByCode(code);
if(user != null){
//2.调用dao的修改激活状态的方法
userDao.updateStatus(user);
return true;
}else{
return false;
}
}
UserDao:findByCode updateStatus
/
根据激活码查询用户对象
@param code
__ * @return
*/@Overridepublic User findByCode(String code) {
User user = null;
try {
String sql = “select * from tab_user where code = ?”**;
user = **template**.queryForObject(sql,**new **BeanPropertyRowMapper<User>(User.**class**),code);<br /> } **catch **(DataAccessException e) {<br /> e.printStackTrace();<br /> }
**return **user;<br />}<br />/**<br /> * 修改指定用户激活状态<br /> * **@param _user<br />__ _***/@Override**public void **updateStatus(User user) {<br /> String sql = **" update tab_user set status = 'Y' where uid=?"**;<br /> **template**.update(sql,user.getUid());<br />}
7 登录
7.1 分析
7.2 代码实现
7.2.1 前台代码
7.2.2 后台代码
LoginServlet
//1.获取用户名和密码数据Map
BeanUtils.populate(user,map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//3.调用Service查询UserService service = new UserServiceImpl();
User u = service.login(user);
ResultInfo info = new ResultInfo();
//4.判断用户对象是否为nullif(u == null){
//用户名密码或错误
info.setFlag(false);
info.setErrorMsg(“用户名密码或错误”);
}//5.判断用户是否激活if(u != null && !“Y”.equals(u.getStatus())){
//用户尚未激活
info.setFlag(false);
info.setErrorMsg(“您尚未激活,请激活”);
}//6.判断登录成功if(u != null && “Y”.equals(u.getStatus())){
//登录成功
info.setFlag(true);
}
//响应数据ObjectMapper mapper = new ObjectMapper();
response.setContentType(“application/json;charset=utf-8”);
mapper.writeValue(response.getOutputStream(),info);
UserService
public User login(User user) {
return userDao.findByUsernameAndPassword(user.getUsername(),user.getPassword());
}
UserDao
public User findByUsernameAndPassword(String username, String password) {
User user = null;
try {
//1.定义sql
String sql = “select * from tab_user where username = ? and password = ?”;
//2.执行sql
user = template.queryForObject(sql, new BeanPropertyRowMapper
} catch (Exception e) {
}
**return **user;<br />}
7.2.3 index页面中用户姓名的提示信息功能
效果:
header.html代码
Servlet代码
//从session中获取登录用户Object user = request.getSession().getAttribute(“user”);//将user写回客户端
ObjectMapper mapper = new ObjectMapper();
response.setContentType(“application/json;charset=utf-8”);
mapper.writeValue(response.getOutputStream(),user);
8 退出
什么叫做登录了?session中有user对象。
实现步骤:
1. 访问servlet,将session销毁
1. 跳转到登录页面
代码实现:
Header.html
Servlet:
//1.销毁sessionrequest.getSession().invalidate();
//2.跳转登录页面response.sendRedirect(request.getContextPath()+“/login.html”);
9 优化Servlet
9.1 目的
减少Servlet的数量,现在是一个功能一个Servlet,将其优化为一个模块一个Servlet,相当于在数据库中一张表对应一个Servlet,在Servlet中提供不同的方法,完成用户的请求。
Idea控制台中文乱码解决:-Dfile.encoding=gb2312
9.2 BaseServlet编写:
**public class **BaseServlet **extends **HttpServlet {
@Override<br /> **protected void **service(HttpServletRequest req, HttpServletResponse resp) **throws **ServletException, IOException {<br /> //System.out.println("baseServlet的service方法被执行了...");
//完成方法分发<br /> //1.获取请求路径<br /> String uri = req.getRequestURI(); // /travel/user/add<br /> System.**_out_**.println(**"请求uri:"**+uri);// /travel/user/add<br /> //2.获取方法名称<br /> String methodName = uri.substring(uri.lastIndexOf(**'/'**) + 1);<br /> System.**_out_**.println(**"方法名称:"**+methodName);<br /> //3.获取方法对象Method<br /> //谁调用我?我代表谁<br /> System.**_out_**.println(**this**);//UserServlet的对象cn.itcast.travel.web.servlet.UserServlet@4903d97e<br /> **try **{<br /> //获取方法<br /> Method method = **this**.getClass().getMethod(methodName, HttpServletRequest.**class**, HttpServletResponse.**class**);<br /> //4.执行方法<br /> //暴力反射<br /> //method.setAccessible(true);<br /> method.invoke(**this**,req,resp);<br /> } **catch **(NoSuchMethodException e) {<br /> e.printStackTrace();<br /> } **catch **(IllegalAccessException e) {<br /> e.printStackTrace();<br /> } **catch **(InvocationTargetException e) {<br /> e.printStackTrace();<br /> }
}<br />}
9.3 UserServlet改写
将之前的Servlet实现的功能,抽取到UserServlet中的不同方法中实现,并且将UserService创建抽取到成员变量位置
@WebServlet(“/user/*”) // /user/add /user/findpublic class UserServlet extends BaseServlet {
//声明UserService业务对象<br /> **private **UserService **service **= **new **UserServiceImpl();
/**<br /> * 注册功能<br /> * **@param _request<br />__ _*** **@param _response<br />__ _*** **@throws **ServletException<br /> * **@throws **IOException<br /> */<br /> **public void **regist(HttpServletRequest request, HttpServletResponse response) **throws **ServletException, IOException {
//验证校验<br /> String check = request.getParameter(**"check"**);<br /> //从sesion中获取验证码<br /> HttpSession session = request.getSession();<br /> String checkcode_server = (String) session.getAttribute(**"CHECKCODE_SERVER"**);<br /> session.removeAttribute(**"CHECKCODE_SERVER"**);//为了保证验证码只能使用一次<br /> //比较<br /> **if**(checkcode_server == **null **|| !checkcode_server.equalsIgnoreCase(check)){<br /> //验证码错误<br /> ResultInfo info = **new **ResultInfo();<br /> //注册失败<br /> info.setFlag(**false**);<br /> info.setErrorMsg(**"验证码错误"**);<br /> //将info对象序列化为json<br /> ObjectMapper mapper = **new **ObjectMapper();<br /> String json = mapper.writeValueAsString(info);<br /> response.setContentType(**"application/json;charset=utf-8"**);<br /> response.getWriter().write(json);<br /> **return**;<br /> }
//1.获取数据<br /> Map<String, String[]> map = request.getParameterMap();
//2.封装对象<br /> User user = **new **User();<br /> **try **{<br /> BeanUtils._populate_(user,map);<br /> } **catch **(IllegalAccessException e) {<br /> e.printStackTrace();<br /> } **catch **(InvocationTargetException e) {<br /> e.printStackTrace();<br /> }
//3.调用service完成注册<br /> //UserService service = new UserServiceImpl();<br /> **boolean **flag = **service**.regist(user);<br /> ResultInfo info = **new **ResultInfo();<br /> //4.响应结果<br /> **if**(flag){<br /> //注册成功<br /> info.setFlag(**true**);<br /> }**else**{<br /> //注册失败<br /> info.setFlag(**false**);<br /> info.setErrorMsg(**"注册失败!"**);<br /> }
//将info对象序列化为json<br /> ObjectMapper mapper = **new **ObjectMapper();<br /> String json = mapper.writeValueAsString(info);
//将json数据写回客户端<br /> //设置content-type<br /> response.setContentType(**"application/json;charset=utf-8"**);<br /> response.getWriter().write(json);
}
/**<br /> * 登录功能<br /> * **@param _request<br />__ _*** **@param _response<br />__ _*** **@throws **ServletException<br /> * **@throws **IOException<br /> */<br /> **public void **login(HttpServletRequest request, HttpServletResponse response) **throws **ServletException, IOException {<br /> //1.获取用户名和密码数据<br /> Map<String, String[]> map = request.getParameterMap();<br /> //2.封装User对象<br /> User user = **new **User();<br /> **try **{<br /> BeanUtils._populate_(user,map);<br /> } **catch **(IllegalAccessException e) {<br /> e.printStackTrace();<br /> } **catch **(InvocationTargetException e) {<br /> e.printStackTrace();<br /> }
//3.调用Service查询<br /> // UserService service = new UserServiceImpl();<br /> User u = **service**.login(user);
ResultInfo info = **new **ResultInfo();
//4.判断用户对象是否为null<br /> **if**(u == **null**){<br /> //用户名密码或错误<br /> info.setFlag(**false**);<br /> info.setErrorMsg(**"用户名密码或错误"**);<br /> }<br /> //5.判断用户是否激活<br /> **if**(u != **null **&& !**"Y"**.equals(u.getStatus())){<br /> //用户尚未激活<br /> info.setFlag(**false**);<br /> info.setErrorMsg(**"您尚未激活,请激活"**);<br /> }<br /> //6.判断登录成功<br /> **if**(u != **null **&& **"Y"**.equals(u.getStatus())){<br /> request.getSession().setAttribute(**"user"**,u);//登录成功标记
//登录成功<br /> info.setFlag(**true**);<br /> }
//响应数据<br /> ObjectMapper mapper = **new **ObjectMapper();
response.setContentType(**"application/json;charset=utf-8"**);<br /> mapper.writeValue(response.getOutputStream(),info);<br /> }
/**<br /> * 查询单个对象<br /> * **@param _request<br />__ _*** **@param _response<br />__ _*** **@throws **ServletException<br /> * **@throws **IOException<br /> */<br /> **public void **findOne(HttpServletRequest request, HttpServletResponse response) **throws **ServletException, IOException {<br /> //从session中获取登录用户<br /> Object user = request.getSession().getAttribute(**"user"**);<br /> //将user写回客户端
ObjectMapper mapper = **new **ObjectMapper();<br /> response.setContentType(**"application/json;charset=utf-8"**);<br /> mapper.writeValue(response.getOutputStream(),user);<br /> }
/**<br /> * 退出功能<br /> * **@param _request<br />__ _*** **@param _response<br />__ _*** **@throws **ServletException<br /> * **@throws **IOException<br /> */<br /> **public void **exit(HttpServletRequest request, HttpServletResponse response) **throws **ServletException, IOException {<br /> //1.销毁session<br /> request.getSession().invalidate();
//2.跳转登录页面<br /> response.sendRedirect(request.getContextPath()+**"/login.html"**);<br /> }
/**<br /> * 激活功能<br /> * **@param _request<br />__ _*** **@param _response<br />__ _*** **@throws **ServletException<br /> * **@throws **IOException<br /> */<br /> **public void **active(HttpServletRequest request, HttpServletResponse response) **throws **ServletException, IOException {<br /> //1.获取激活码<br /> String code = request.getParameter(**"code"**);<br /> **if**(code != **null**){<br /> //2.调用service完成激活<br /> //UserService service = new UserServiceImpl();<br /> **boolean **flag = **service**.active(code);
//3.判断标记<br /> String msg = **null**;<br /> **if**(flag){<br /> //激活成功<br /> msg = **"激活成功,请<a href='login.html'>登录</a>"**;<br /> }**else**{<br /> //激活失败<br /> msg = **"激活失败,请联系管理员!"**;<br /> }<br /> response.setContentType(**"text/html;charset=utf-8"**);<br /> response.getWriter().write(msg);<br /> }<br /> }<br />}
9.4 页面路径改写
register.html
login.html
header.html
UserServiceImpl发送邮件
10 分类数据展示
10.1 效果:
![](https://cdn.nlark.com/yuque/0/2021/png/22277845/1627874044005-b315c937-bfb2-46a8-a25d-c531ef5c1d13.png#id=c6Ylb&originHeight=62&originWidth=1149&originalType=binary&ratio=1&status=done&style=none)
10.2 分析:
![](https://cdn.nlark.com/yuque/0/2021/png/22277845/1627874044520-45050930-80a4-4e77-975b-c8ce48bd6c85.png#id=o2cPJ&originHeight=381&originWidth=1219&originalType=binary&ratio=1&status=done&style=none)
10.3 代码实现:
10.3.1 后台代码
CategoryServlet
@WebServlet(“/category/*”)public class CategoryServlet extends BaseServlet {
**private **CategoryService **service **= **new **CategoryServiceImpl();
/**<br /> * 查询所有<br /> * **@param _request<br />__ _*** **@param _response<br />__ _*** **@throws **ServletException<br /> * **@throws **IOException<br /> */<br /> **public void **findAll(HttpServletRequest request, HttpServletResponse response) **throws **ServletException, IOException {<br /> //1.调用service查询所有<br /> List<Category> cs = **service**.findAll();<br /> //2.序列化json返回<br /> /* ObjectMapper mapper = new ObjectMapper();<br /> response.setContentType("application/json;charset=utf-8");<br /> mapper.writeValue(response.getOutputStream(),cs);*/<br /> writeValue(cs,response);
}
}
CategoryService
public class CategoryServiceImpl implements CategoryService {
**private **CategoryDao **categoryDao **= **new **CategoryDaoImpl();
@Override<br /> **public **List<Category> findAll() {<br /> **return categoryDao**.findAll();<br /> }<br />}
CategoryDao
public class CategoryDaoImpl implements CategoryDao {
**private **JdbcTemplate **template **= **new **JdbcTemplate(JDBCUtils._getDataSource_());
@Override<br /> **public **List<Category> findAll() {<br /> String sql = **"select **_*_** from tab_category "**;<br /> **return template**.query(sql,**new **BeanPropertyRowMapper<Category>(Category.**class**));<br /> }<br />}
在BaseServlet中封装了序列化json的方法
/
直接将传入的对象序列化为json,并且写回客户端
@param obj
__ */public void writeValue(Object obj,HttpServletResponse response) throws IOException {
ObjectMapper mapper = new ObjectMapper();
response.setContentType(“application/json;charset=utf-8”);
mapper.writeValue(response.getOutputStream(),obj);
}
/
将传入的对象序列化为json,返回
@param obj
__ * @return
*/public String writeValueAsString(Object obj) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(obj);
}
10.3.2 前台代码
hader.html加载后,发送ajax请求,请求category/findAll
//查询分类数据
$.get(“category/findAll”,{},function (data) {
//[{cid:1,cname:国内游},{},{}]
var lis = ‘
//遍历数组,拼接字符串(
for (var i = 0; i < data.length; i++) {
var li = ‘
lis += li;<br /> <br /> }<br /> //拼接收藏排行榜的li,<li><a href="favoriterank.html">收藏排行榜</a></li><br /> <br /> lis+= **'<li><a href="favoriterank.html">收藏排行榜</a></li>'**;
//将lis字符串,设置到ul的html内容中<br /> **$**(**"#category"**).html(lis);<br /> });
10.4 对分类数据进行缓存优化
分析发现,分类的数据在每一次页面加载后都会重新请求数据库来加载,对数据库的压力比较大,而且分类的数据不会经常产生变化,所有可以使用redis来缓存这个数据。
分析:
10.5 优化代码实现
期望数据中存储的顺序就是将来展示的顺序,使用redis的sortedset
@Overridepublic List
//1.从redis中查询
//1.1获取jedis客户端
Jedis jedis = JedisUtil.getJedis();
//1.2可使用sortedset排序查询
Set
List
//2.判断查询的集合是否为空
if (categorys == null || categorys.size() == 0) {
System.**_out_**.println(**"从数据库查询...."**);<br /> //3.如果为空,需要从数据库查询,在将数据存入redis<br /> //3.1 从数据库查询<br /> cs = **categoryDao**.findAll();<br /> //3.2 将集合数据存储到redis中的 category的key<br /> **for **(**int **i = 0; i < cs.size(); i++) {
jedis.zadd(**"category"**, cs.get(i).getCid(), cs.get(i).getCname());<br /> }<br /> } **else **{<br /> System.**_out_**.println(**"从redis中查询....."**);
//4.如果不为空,将set的数据存入list<br /> cs = **new **ArrayList<Category>();<br /> **for **(String name : categorys) {<br /> Category category = **new **Category();<br /> category.setCname(name);<br /> cs.add(category);
}<br /> }
**return **cs;<br />}
11 旅游线路的分页展示
点击了不同的分类后,将来看到的旅游线路不一样的。通过分析数据库表结构,发现,旅游线路表和分类表时一个多对一的关系
查询不同分类的旅游线路sql
Select * from tab_route where cid = ?;
11.1 类别id的传递
Redis中查询score(cid)
public class CategoryServiceImpl implements CategoryService {
**private **CategoryDao **categoryDao **= **new **CategoryDaoImpl();
@Override<br /> **public **List<Category> findAll() {<br /> //1.从redis中查询<br /> //1.1获取jedis客户端<br /> Jedis jedis = JedisUtil._getJedis_();<br /> //1.2可使用sortedset排序查询<br /> //Set<String> categorys = jedis.zrange("category", 0, -1);<br /> //1.3查询sortedset中的分数(cid)和值(cname)<br /> Set<Tuple> categorys = jedis.zrangeWithScores(**"category"**, 0, -1);
List<Category> cs = **null**;<br /> //2.判断查询的集合是否为空<br /> **if **(categorys == **null **|| categorys.size() == 0) {
System.**_out_**.println(**"从数据库查询...."**);<br /> //3.如果为空,需要从数据库查询,在将数据存入redis<br /> //3.1 从数据库查询<br /> cs = **categoryDao**.findAll();<br /> //3.2 将集合数据存储到redis中的 category的key<br /> **for **(**int **i = 0; i < cs.size(); i++) {
jedis.zadd(**"category"**, cs.get(i).getCid(), cs.get(i).getCname());<br /> }<br /> } **else **{<br /> System.**_out_**.println(**"从redis中查询....."**);
//4.如果不为空,将set的数据存入list<br /> cs = **new **ArrayList<Category>();<br /> **for **(Tuple tuple : categorys) {<br /> Category category = **new **Category();<br /> category.setCname(tuple.getElement());<br /> category.setCid((**int**)tuple.getScore());<br /> cs.add(category);
}<br /> }
**return **cs;<br /> }<br />}
页面传递cid
header.html传递cid
var li = ‘
获取cid
$(function () {
var search = location.search;
//alert(search);//?id=5
// 切割字符串,拿到第二个值
var cid = search.split(“=”)[1];
});
11.2 根据id查询不同类别的旅游线路数据
11.2.1 分析
11.2.2 编码
- 客户端代码编写
$(function () {
var search = location.search;
// 切割字符串,拿到第二个值
var cid = search.split(“=”)[1];
//当页码加载完成后,调用load方法,发送ajax请求加载数据<br /> _load_(cid);<br />});<br />**function **_load_(cid ,currentPage){<br /> //发送ajax请求,请求route/pageQuery,传递cid<br /> **$**.get(**"route/pageQuery"**,{**cid**:cid,**currentPage**:currentPage},**function **(pb) {<br /> //解析pagebean数据,展示到页面上
//1.分页工具条数据展示<br /> //1.1 展示总页码和总记录数<br /> **$**(**"#totalPage"**).html(pb.totalPage);<br /> **$**(**"#totalCount"**).html(pb.totalCount);
**var **lis = **""**;
**var **fristPage = **'<li onclick="javascipt:**_load_**('**+cid+**')"><a href="javascript:void(0)">首页</a></li>'**;
//计算上一页的页码<br /> **var **beforeNum = pb.**currentPage **- 1;<br /> **if**(beforeNum <= 0){<br /> beforeNum = 1;<br /> }
**var **beforePage = **'<li onclick="javascipt:**_load_**('**+cid+**','**+beforeNum+**')" class="threeword"><a href="javascript:void(0)">上一页</a></li>'**;
lis += fristPage;<br /> lis += beforePage;<br /> //1.2 展示分页页码<br /> /*<br /> 1.一共展示10个页码,能够达到前5后4的效果<br /> 2.如果前边不够5个,后边补齐10个<br /> 3.如果后边不足4个,前边补齐10个<br /> */
// 定义开始位置begin,结束位置 end<br /> **var **begin; // 开始位置<br /> **var **end ; // 结束位置
//1.要显示10个页码<br /> **if**(pb.totalPage < 10){<br /> //总页码不够10页
begin = 1;<br /> end = pb.totalPage;<br /> }**else**{<br /> //总页码超过10页
begin = pb.**currentPage **- 5 ;<br /> end = pb.**currentPage **+ 4 ;
//2.如果前边不够5个,后边补齐10个<br /> **if**(begin < 1){<br /> begin = 1;<br /> end = begin + 9;<br /> }
//3.如果后边不足4个,前边补齐10个<br /> **if**(end > pb.totalPage){<br /> end = pb.totalPage;<br /> begin = end - 9 ;<br /> }<br /> }
**for **(**var **i = begin; i <= end ; i++) {<br /> **var **li;<br /> //判断当前页码是否等于i<br /> **if**(pb.**currentPage **== i){
li = **'<li class="curPage" onclick="javascipt:**_load_**('**+cid+**','**+i+**')"><a href="javascript:void(0)">'**+i+**'</a></li>'**;
}**else**{<br /> //创建页码的li<br /> li = **'<li onclick="javascipt:**_load_**('**+cid+**','**+i+**')"><a href="javascript:void(0)">'**+i+**'</a></li>'**;<br /> }<br /> //拼接字符串<br /> lis += li;<br /> }
**var **lastPage = **'<li class="threeword"><a href="javascript:;">末页</a></li>'**;<br /> **var **nextPage = **'<li class="threeword"><a href="javascript:;">下一页</a></li>'**;
lis += nextPage;<br /> lis += lastPage;
//将lis内容设置到 ul<br /> **$**(**"#pageNum"**).html(lis);
//2.列表数据展示<br /> **var **route_lis = **""**;
**for **(**var **i = 0; i < pb.list.**length**; i++) {<br /> //获取{rid:1,rname:"xxx"}<br /> **var **route = pb.list[i];
**var **li = **'<li>\n' **+<br /> **' <div class="img"><img src="'**+route.rimage+**'" style="width: 299px;"></div>\n' **+<br /> **' <div class="text1">\n' **+<br /> **' <p>'**+route.rname+**'</p>\n' **+<br /> **' <br/>\n' **+<br /> **' <p>'**+route.routeIntroduce+**'</p>\n' **+<br /> **' </div>\n' **+<br /> **' <div class="price">\n' **+<br /> **' <p class="price_num">\n' **+<br /> **' <span>¥</span>\n' **+<br /> **' <span>'**+route.price+**'</span>\n' **+<br /> **' <span>起</span>\n' **+<br /> **' </p>\n' **+<br /> **' <p><a href="route_detail.html">查看详情</a></p>\n' **+<br /> **' </div>\n' **+<br /> **' </li>'**;<br /> route_lis += li;<br /> }<br /> **$**(**"#route"**).html(route_lis);
//定位到页面顶部<br /> **_window_**.scrollTo(0,0);<br /> });
}
- 服务器端代码编写
- 创建PageBean对象
public class PageBean
**private int totalCount**;//总记录数<br /> **private int totalPage**;//总页数<br /> **private int currentPage**;//当前页码<br /> **private int pageSize**;//每页显示的条数
**private **List<T> **list**;//每页显示的数据集合
**public int **getTotalCount() {<br /> **return totalCount**;<br /> }
**public void **setTotalCount(**int **totalCount) {<br /> **this**.**totalCount **= totalCount;<br /> }
**public int **getTotalPage() {<br /> **return totalPage**;<br /> }
**public void **setTotalPage(**int **totalPage) {<br /> **this**.**totalPage **= totalPage;<br /> }
**public int **getCurrentPage() {<br /> **return currentPage**;<br /> }
**public void **setCurrentPage(**int **currentPage) {<br /> **this**.**currentPage **= currentPage;<br /> }
**public int **getPageSize() {<br /> **return pageSize**;<br /> }
**public void **setPageSize(**int **pageSize) {<br /> **this**.**pageSize **= pageSize;<br /> }
**public **List<T> getList() {<br /> **return list**;<br /> }
**public void **setList(List<T> list) {<br /> **this**.**list **= list;<br /> }<br />}
- RouteServlet
@WebServlet(“/route/*”)public class RouteServlet extends BaseServlet {
**private **RouteService **routeService **= **new **RouteServiceImpl();
/**<br /> * 分页查询<br /> * **@param _request<br />__ _*** **@param _response<br />__ _*** **@throws **ServletException<br /> * **@throws **IOException<br /> */<br /> **public void **pageQuery(HttpServletRequest request, HttpServletResponse response) **throws **ServletException, IOException {<br /> //1.接受参数<br /> String currentPageStr = request.getParameter(**"currentPage"**);<br /> String pageSizeStr = request.getParameter(**"pageSize"**);<br /> String cidStr = request.getParameter(**"cid"**);
**int **cid = 0;//类别id<br /> //2.处理参数<br /> **if**(cidStr != **null **&& cidStr.length() > 0){<br /> cid = Integer._parseInt_(cidStr);<br /> }<br /> **int **currentPage = 0;//当前页码,如果不传递,则默认为第一页<br /> **if**(currentPageStr != **null **&& currentPageStr.length() > 0){<br /> currentPage = Integer._parseInt_(currentPageStr);<br /> }**else**{<br /> currentPage = 1;<br /> }
**int **pageSize = 0;//每页显示条数,如果不传递,默认每页显示5条记录<br /> **if**(pageSizeStr != **null **&& pageSizeStr.length() > 0){<br /> pageSize = Integer._parseInt_(pageSizeStr);<br /> }**else**{<br /> pageSize = 5;<br /> }
//3. 调用service查询PageBean对象<br /> PageBean<Route> pb = **routeService**.pageQuery(cid, currentPage, pageSize);
//4. 将pageBean对象序列化为json,返回<br /> writeValue(pb,response);
}
}
- RouteService
public class RouteServiceImpl implements RouteService {
private RouteDao routeDao = new RouteDaoImpl();
@Override
public PageBean
//封装PageBean
PageBean
//设置当前页码
pb.setCurrentPage(currentPage);
//设置每页显示条数
pb.setPageSize(pageSize);
//设置总记录数
int totalCount = routeDao.findTotalCount(cid);
pb.setTotalCount(totalCount);
//设置当前页显示的数据集合
int start = (currentPage - 1) pageSize;//开始的记录数
List
pb.setList(list);
//设置总页数 = 总记录数/每页显示条数<br /> **int **totalPage = totalCount % pageSize == 0 ? totalCount / pageSize :(totalCount / pageSize) + 1 ;<br /> pb.setTotalPage(totalPage);
**return **pb;<br /> }<br />}
- RouteDao
public class RouteDaoImpl implements RouteDao {
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
@Override<br /> **public int **findTotalCount(**int **cid) {<br /> String sql = **"select **_count_**(**_*_**) from tab_route where cid = ?"**;<br /> **return template**.queryForObject(sql,Integer.**class**,cid);<br /> }
@Override<br /> **public **List<Route> findByPage(**int **cid, **int **start, **int **pageSize) {<br /> String sql = **"select **_*_** from tab_route where cid = ? limit ? , ?"**;
**return template**.query(sql,**new **BeanPropertyRowMapper<Route>(Route.**class**),cid,start,pageSize);<br /> }<br />}
12 旅游线路名称查询
12.1 查询参数的传递
在header.html中
$(“#search-button”).click(function () {
//线路名称
var rname = $(“#search_input”).val();
**var **cid = _getParameter_(**"cid"**);<br /> // 跳转路径 http://localhost/travel/route_list.html?cid=5,拼接上rname=xxx<br /> **_location_**.href=**"http://localhost/travel/route_list.html?cid="**+cid+**"&rname="**+rname;<br />});<br />在route_list.html<br />**var **cid = _getParameter_(**"cid"**);<br /> //获取rname的参数值<br /> **var **rname = _getParameter_(**"rname"**);<br /> //判断rname如果不为null或者""<br /> **if**(rname){<br /> //url解码<br /> rname = **_window_**._decodeURIComponent_(rname);<br /> }
12.2 修改后台代码
Servlet<br />@WebServlet(**"/route/*"**)**public class **RouteServlet **extends **BaseServlet {
**private **RouteService **routeService **= **new **RouteServiceImpl();
/**<br /> * 分页查询<br /> * **@param _request<br />__ _*** **@param _response<br />__ _*** **@throws **ServletException<br /> * **@throws **IOException<br /> */<br /> **public void **pageQuery(HttpServletRequest request, HttpServletResponse response) **throws **ServletException, IOException {<br /> //1.接受参数<br /> String currentPageStr = request.getParameter(**"currentPage"**);<br /> String pageSizeStr = request.getParameter(**"pageSize"**);<br /> String cidStr = request.getParameter(**"cid"**);
//接受rname 线路名称<br /> String rname = request.getParameter(**"rname"**);<br /> rname = **new **String(rname.getBytes(**"iso-8859-1"**),**"utf-8"**);
**int **cid = 0;//类别id<br /> //2.处理参数<br /> **if**(cidStr != **null **&& cidStr.length() > 0){<br /> cid = Integer._parseInt_(cidStr);<br /> }<br /> **int **currentPage = 0;//当前页码,如果不传递,则默认为第一页<br /> **if**(currentPageStr != **null **&& currentPageStr.length() > 0){<br /> currentPage = Integer._parseInt_(currentPageStr);<br /> }**else**{<br /> currentPage = 1;<br /> }
**int **pageSize = 0;//每页显示条数,如果不传递,默认每页显示5条记录<br /> **if**(pageSizeStr != **null **&& pageSizeStr.length() > 0){<br /> pageSize = Integer._parseInt_(pageSizeStr);<br /> }**else**{<br /> pageSize = 5;<br /> }
//3. 调用service查询PageBean对象<br /> PageBean<Route> pb = **routeService**.pageQuery(cid, currentPage, pageSize,rname);
//4. 将pageBean对象序列化为json,返回<br /> writeValue(pb,response);
}
}
Service
public PageBean
//封装PageBean
PageBean
//设置当前页码
pb.setCurrentPage(currentPage);
//设置每页显示条数
pb.setPageSize(pageSize);
//设置总记录数
int totalCount = routeDao.findTotalCount(cid,rname);
pb.setTotalCount(totalCount);
//设置当前页显示的数据集合
int start = (currentPage - 1) pageSize;//开始的记录数
List
pb.setList(list);
//设置总页数 = 总记录数/每页显示条数<br /> **int **totalPage = totalCount % pageSize == 0 ? totalCount / pageSize :(totalCount / pageSize) + 1 ;<br /> pb.setTotalPage(totalPage);
**return **pb;<br />}
Dao
@Overridepublic int findTotalCount(int cid,String rname) {
//String sql = “select count() from tabroute where cid = ?”;
//1.定义sql模板
String sql = “select _count(__) from tab_route where 1=1 “;
StringBuilder sb = new StringBuilder(sql);
List params = **new **ArrayList();//条件们<br /> //2.判断参数是否有值<br /> **if**(cid != 0){<br /> sb.append( **" and cid = ? "**);
params.add(cid);//添加?对应的值<br /> }
**if**(rname != **null **&& rname.length() > 0){<br /> sb.append(**" and rname like ? "**);
params.add(**"%"**+rname+**"%"**);<br /> }
sql = sb.toString();
**return template**.queryForObject(sql,Integer.**class**,params.toArray());<br />}<br />@Override**public **List<Route> findByPage(**int **cid, **int **start, **int **pageSize,String rname) {<br /> //String sql = "select * from tab_route where cid = ? and rname like ? limit ? , ?";<br /> String sql = **" select **_*_** from tab_route where 1 = 1 "**;<br /> //1.定义sql模板<br /> StringBuilder sb = **new **StringBuilder(sql);
List params = **new **ArrayList();//条件们<br /> //2.判断参数是否有值<br /> **if**(cid != 0){<br /> sb.append( **" and cid = ? "**);
params.add(cid);//添加?对应的值<br /> }
**if**(rname != **null **&& rname.length() > 0){<br /> sb.append(**" and rname like ? "**);
params.add(**"%"**+rname+**"%"**);<br /> }<br /> sb.append(**" limit ? , ? "**);//分页条件
sql = sb.toString();
params.add(start);<br /> params.add(pageSize);
**return template**.query(sql,**new **BeanPropertyRowMapper<Route>(Route.**class**),params.toArray());<br />}
12.3 修改前台代码
$(function () {
/ var search = location.search;
//alert(search);//?id=5
// 切割字符串,拿到第二个值
var cid = search.split(“=”)[1];/
//获取cid的参数值
var cid = getParameter(“cid”);
//获取rname的参数值
var rname = getParameter(“rname”);
//判断rname如果不为null或者””
if(rname){
//url解码
rname = window.decodeURIComponent(rname);
}
//当页码加载完成后,调用load方法,发送ajax请求加载数据<br /> _load_(cid,**null**,rname);<br />});<br />**function **_load_(cid ,currentPage,rname){<br /> //发送ajax请求,请求route/pageQuery,传递cid<br /> **$**.get(**"route/pageQuery"**,{**cid**:cid,**currentPage**:currentPage,**rname**:rname},**function **(pb) {<br /> //解析pagebean数据,展示到页面上
//1.分页工具条数据展示<br /> //1.1 展示总页码和总记录数<br /> **$**(**"#totalPage"**).html(pb.totalPage);<br /> **$**(**"#totalCount"**).html(pb.totalCount);
/*<br /> <li><a href="">首页</a></li><br /> <li class="threeword"><a href="#">上一页</a></li><br /> <li class="curPage"><a href="#">1</a></li><br /> <li><a href="#">2</a></li><br /> <li><a href="#">3</a></li><br /> <li><a href="#">4</a></li><br /> <li><a href="#">5</a></li><br /> <li><a href="#">6</a></li><br /> <li><a href="#">7</a></li><br /> <li><a href="#">8</a></li><br /> <li><a href="#">9</a></li><br /> <li><a href="#">10</a></li><br /> <li class="threeword"><a href="javascript:;">下一页</a></li><br /> <li class="threeword"><a href="javascript:;">末页</a></li>
*/<br /> **var **lis = **""**;
**var **fristPage = **'<li onclick="javascipt:**_load_**('**+cid+**',1,\''**+rname+**'\')"><a href="javascript:void(0)">首页</a></li>'**;
//计算上一页的页码<br /> **var **beforeNum = pb.**currentPage **- 1;<br /> **if**(beforeNum <= 0){<br /> beforeNum = 1;<br /> }
**var **beforePage = **'<li onclick="javascipt:**_load_**('**+cid+**','**+beforeNum+**',\''**+rname+**'\')" class="threeword"><a href="javascript:void(0)">上一页</a></li>'**;
lis += fristPage;<br /> lis += beforePage;<br /> //1.2 展示分页页码<br /> /*<br /> 1.一共展示10个页码,能够达到前5后4的效果<br /> 2.如果前边不够5个,后边补齐10个<br /> 3.如果后边不足4个,前边补齐10个<br /> */
// 定义开始位置begin,结束位置 end<br /> **var **begin; // 开始位置<br /> **var **end ; // 结束位置
//1.要显示10个页码<br /> **if**(pb.totalPage < 10){<br /> //总页码不够10页
begin = 1;<br /> end = pb.totalPage;<br /> }**else**{<br /> //总页码超过10页
begin = pb.**currentPage **- 5 ;<br /> end = pb.**currentPage **+ 4 ;
//2.如果前边不够5个,后边补齐10个<br /> **if**(begin < 1){<br /> begin = 1;<br /> end = begin + 9;<br /> }
//3.如果后边不足4个,前边补齐10个<br /> **if**(end > pb.totalPage){<br /> end = pb.totalPage;<br /> begin = end - 9 ;<br /> }<br /> }
**for **(**var **i = begin; i <= end ; i++) {<br /> **var **li;<br /> //判断当前页码是否等于i<br /> **if**(pb.**currentPage **== i){
li = **'<li class="curPage" onclick="javascipt:**_load_**('**+cid+**','**+i+**',\''**+rname+**'\')"><a href="javascript:void(0)">'**+i+**'</a></li>'**;
}**else**{<br /> //创建页码的li<br /> li = **'<li onclick="javascipt:**_load_**('**+cid+**','**+i+**',\''**+rname+**'\')"><a href="javascript:void(0)">'**+i+**'</a></li>'**;<br /> }<br /> //拼接字符串<br /> lis += li;<br /> }
/* for (var i = 1; i <= pb.totalPage ; i++) {<br /> var li;<br /> //判断当前页码是否等于i<br /> if(pb.currentPage == i){
li = '<li class="curPage" onclick="javascipt:load('+cid+','+i+')"><a href="javascript:void(0)">'+i+'</a></li>';
}else{<br /> //创建页码的li<br /> li = '<li onclick="javascipt:load('+cid+','+i+')"><a href="javascript:void(0)">'+i+'</a></li>';<br /> }<br /> //拼接字符串<br /> lis += li;<br /> }*/<br /> **var **lastPage = **'<li class="threeword"><a href="javascript:;">末页</a></li>'**;<br /> **var **nextPage = **'<li class="threeword"><a href="javascript:;">下一页</a></li>'**;
lis += nextPage;<br /> lis += lastPage;
//将lis内容设置到 ul<br /> **$**(**"#pageNum"**).html(lis);
/*<br /> <li><br /> <div class="img"><img src="images/04-search_03.jpg" alt=""></div><br /> <div class="text1"><br /> <p>【减100元 含除夕/春节出发】广州增城三英温泉度假酒店/自由行套票</p><br /> <br/><br /> <p>1-2月出发,网付立享¥1099/2人起!爆款位置有限,抢完即止!</p><br /> </div><br /> <div class="price"><br /> <p class="price_num"><br /> <span>¥</span><br /> <span>299</span><br /> <span>起</span><br /> </p><br /> <p><a href="route_detail.html">查看详情</a></p><br /> </div><br /> </li>
*/
//2.列表数据展示<br /> **var **route_lis = **""**;
**for **(**var **i = 0; i < pb.list.**length**; i++) {<br /> //获取{rid:1,rname:"xxx"}<br /> **var **route = pb.list[i];
**var **li = **'<li>\n' **+<br /> **' <div class="img"><img src="'**+route.rimage+**'" style="width: 299px;"></div>\n' **+<br /> **' <div class="text1">\n' **+<br /> **' <p>'**+route.**rname**+**'</p>\n' **+<br /> **' <br/>\n' **+<br /> **' <p>'**+route.routeIntroduce+**'</p>\n' **+<br /> **' </div>\n' **+<br /> **' <div class="price">\n' **+<br /> **' <p class="price_num">\n' **+<br /> **' <span>¥</span>\n' **+<br /> **' <span>'**+route.price+**'</span>\n' **+<br /> **' <span>起</span>\n' **+<br /> **' </p>\n' **+<br /> **' <p><a href="route_detail.html">查看详情</a></p>\n' **+<br /> **' </div>\n' **+<br /> **' </li>'**;<br /> route_lis += li;<br /> }<br /> **$**(**"#route"**).html(route_lis);
//定位到页面顶部<br /> **_window_**.scrollTo(0,0);<br /> });
}
13 旅游线路的详情展示
13.1 分析
13.2 代码实现
13.2.1 后台代码
Servlet
/
根据id查询一个旅游线路的详细信息
@param request
__ * @param response
__ * @throws ServletException
* @throws IOException
*/public void findOne(HttpServletRequest request, HttpServletResponse response) throws **ServletException, IOException {
//1.接收id<br /> String rid = request.getParameter(**"rid"**);<br /> //2.调用service查询route对象<br /> Route route = **routeService**.findOne(rid);<br /> //3.转为json写回客户端<br /> writeValue(route,response);<br />}
Service
@Overridepublic Route findOne(String rid) {
//1.根据id去route表中查询route对象
Route route = routeDao.findOne(Integer.parseInt(rid));
//2.根据route的id 查询图片集合信息<br /> List<RouteImg> routeImgList = **routeImgDao**.findByRid(route.getRid());<br /> //2.2将集合设置到route对象<br /> route.setRouteImgList(routeImgList);<br /> //3.根据route的sid(商家id)查询商家对象<br /> Seller seller = **sellerDao**.findById(route.getSid());<br /> route.setSeller(seller);
**return **route;<br />}
SellerDao
public class SellerDaoImpl implements SellerDao {
**private **JdbcTemplate **template **= **new **JdbcTemplate(JDBCUtils._getDataSource_());
@Override<br /> **public **Seller findById(**int **id) {
String sql = **"select **_*_** from tab_seller where sid = ? "**;<br /> **return template**.queryForObject(sql,**new **BeanPropertyRowMapper<Seller>(Seller.**class**),id);<br /> }<br />}<br />routeDao<br />@Override**public **Route findOne(**int **rid) {<br /> String sql = **"select **_*_** from tab_route where rid = ?"**;<br /> **return template**.queryForObject(sql,**new **BeanPropertyRowMapper<Route>(Route.**class**),rid);<br />}<br />RouteImgDao
public class RouteImgDaoImpl implements RouteImgDao {
**private **JdbcTemplate **template **= **new **JdbcTemplate(JDBCUtils._getDataSource_());
@Override<br /> **public **List<RouteImg> findByRid(**int **rid) {<br /> String sql = **"select **_*_** from tab_route_img where rid = ? "**;<br /> **return template**.query(sql,**new **BeanPropertyRowMapper<RouteImg>(RouteImg.**class**),rid);<br /> }<br />}
13.2.2 前台代码
Route_detail.html中加载后
- 获取rid
- 发送ajax请求,获取route对象
- 解析对象的数据
//1.获取ridvar rid = getParameter(“rid”);
//2.发送请求请求 route/findOne
$.get(“route/findOne”,{rid:rid},function (route) {
//3.解析数据填充html
$(“#rname”).html(route.rname);
$(“#routeIntroduce”).html(route.routeIntroduce);
$(“#price”).html(“¥”+route.price);
$(“#sname”).html(route.seller.sname);
$(“#consphone”).html(route.seller.consphone);
$(“#address”).html(route.seller.address);
//图片展示
**var **ddstr = **'<a class="up_img up_img_disable"></a>'**;
//遍历routeImgList<br /> **for **(**var **i = 0; i < route.routeImgList.**length**; i++) {<br /> **var **astr ;<br /> **if**(i >= 4){<br /> astr = **'<a title="" class="little_img" data-bigpic="'**+route.routeImgList[i].bigPic+**'" style="display:none;">\n' **+<br /> **' <img src="'**+route.routeImgList[i].smallPic+**'">\n' **+<br /> **' </a>'**;<br /> }**else**{<br /> astr = **'<a title="" class="little_img" data-bigpic="'**+route.routeImgList[i].bigPic+**'">\n' **+<br /> **' <img src="'**+route.routeImgList[i].smallPic+**'">\n' **+<br /> **' </a>'**;<br /> }
ddstr += astr;<br /> }<br /> ddstr+=**'<a class="down_img down_img_disable" style="margin-bottom: 0;"></a>'**;
**$**(**"#dd"**).html(ddstr);
//图片展示和切换代码调用<br /> _goImg_();<br /> });
14 旅游线路收藏功能
14.1 分析
14.1.1 判断当前登录用户是否收藏过该线路
当页面加载完成后,发送ajax请求,获取用户是否收藏的标记
根据标记,展示不同的按钮样式
14.2 编写代码
14.2.1 后台代码
RouteServlet:
public void isFavorite(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 获取线路id
String rid = request.getParameter(“rid”);
//2. 获取当前登录的用户 user<br /> User user = (User) request.getSession().getAttribute(**"user"**);<br /> **int **uid;//用户id<br /> **if**(user == **null**){<br /> //用户尚未登录<br /> uid = 0;<br /> }**else**{<br /> //用户已经登录<br /> uid = user.getUid();<br /> }
//3. 调用FavoriteService查询是否收藏<br /> **boolean **flag = **favoriteService**.isFavorite(rid, uid);
//4. 写回客户端<br /> writeValue(flag,response);<br />}
FavoriteService
@Overridepublic boolean isFavorite(String rid, int uid) {
Favorite favorite = **favoriteDao**.findByRidAndUid(Integer._parseInt_(rid), uid);
**return **favorite != **null**;//如果对象有值,则为true,反之,则为false}
FavoriteDao
@Overridepublic Favorite findByRidAndUid(int rid, int uid) {
Favorite favorite = null;
try {
String sql = “ select * from tab_favorite where rid = ? and uid = ?”;
favorite = template.queryForObject(sql, new BeanPropertyRowMapper
} catch (DataAccessException e) {
e.printStackTrace();
}
return favorite;
}
14.2.2 前台代码
route_detail.html
$(function () {
// 发送请求,判断用户是否收藏过该线路
var rid = getParameter(“rid”);
$.get(“route/isFavorite”,{rid:rid},function (flag) {
if(flag){
// 用户已经收藏过
//
//设置收藏按钮的样式
$(“#favorite”).addClass(“already”);
$(“#favorite”).prop(“disabled”,disabled);
}**else**{<br /> // 用户没有收藏<br /> }<br /> });
14.3 收藏次数的动态展示
前台:
//设置收藏次数$(“#favoriteCount”).html(“已收藏”+route.count+“次”);
后台:
RouteService
//4. 查询收藏次数int count = favoriteDao.findCountByRid(route.getRid());
route.setCount(count);
FavoriteDao
@Overridepublic int findCountByRid(int rid) {
String sql = “SELECT COUNT(*) FROM tab_favorite WHERE rid = ?”;
**return template**.queryForObject(sql,Integer.**class**,rid);<br />}
14.4 点击按钮收藏线路
14.4.1 分析:
![](https://cdn.nlark.com/yuque/0/2021/png/22277845/1627874049321-2199eecf-04e3-44b8-9d60-8fad17271e08.png#id=YhAND&originHeight=465&originWidth=1180&originalType=binary&ratio=1&status=done&style=none)
14.4.2 编码
前台代码
$(function () {
// 发送请求,判断用户是否收藏过该线路
var rid = getParameter(“rid”);
$.get(“route/isFavorite”,{rid:rid},function (flag) {
if(flag){
// 用户已经收藏过
//
//设置收藏按钮的样式
$(“#favorite”).addClass(“already”);
$(“#favorite”).attr(“disabled”,“disabled”);
//删除按钮的点击事件<br /> **$**(**"#favorite"**).removeAttr(**"onclick"**); }**else**{<br /> // 用户没有收藏<br /> }<br /> });
});
//点击收藏按钮触发的方法function addFavorite(){
var rid = getParameter(“rid”);
//1. 判断用户是否登录
$.get(“user/findOne”,{},function (user) {
if(user){
//用户登录了
//添加功能
$.get(“route/addFavorite”,{rid:rid},function () {
//代码刷新页面<br /> **_location_**.reload();<br /> });
}**else**{<br /> //用户没有登录<br /> _alert_(**"您尚未登录,请登录"**);<br /> **_location_**.href=**"http://localhost/travel/login.html"**;<br /> }<br /> })<br />}
后台代码
RouteServlet
public void addFavorite(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 获取线路rid
String rid = request.getParameter(“rid”);
//2. 获取当前登录的用户
User user = (User) request.getSession().getAttribute(“user”);
int uid;//用户id
if(user == null){
//用户尚未登录
return ;
}else{
//用户已经登录
uid = user.getUid();
}
//3. 调用service添加<br /> **favoriteService**.add(rid,uid);
}
FavoriteService
@Overridepublic void add(String rid, int uid) {
favoriteDao.add(Integer.parseInt(rid),uid);
}
FavoriteDao
@Overridepublic void add(int rid, int uid) {
String sql = “insert into tab_favorite values(?,?,?)”;
**template**.update(sql,rid,**new **Date(),uid);<br />}