文章目录
最终效果:
导航实现
1. 创建测试类,测试查询所有分类
//测试获取所有分类信息Category
public class TestCategoryService {
@Test
public void test01(){
//创建业务对象
CategoryService categoryService = new CategoryService();
//所有的分类
List<Category> categoryList=categoryService.findAll();
//显示
System.out.println(categoryList);
}
}
2. 查询所有分类的service
//分类业务
public class CategoryService {
private static CategoryDao categoryDao = GetDaoUtils.getMapper(CategoryDao.class);
public List<Category> findAll() {
//查询所有的分类数据
List<Category> list = categoryDao.findAll();
return list;
}
}
3. 创建对应的javabean对象
//分类信息Category
public class Category {
private int cid;//分类id
private String cname;//分类名称
//省略get/set方法
}
4. dao和对应映射
CategoryDao
public interface CategoryDao {
//获取所有的分类,按照升序排序
//select * from tab_category order by cid asc;
List<Category> findAll();
//通过id查找Category
//select * from tab_category c where c.cid =1;
Category findOneByCid(int cid);
}
<mapper namespace="com.xgf.dao.CategoryDao">
<!-- 查找所有分类,按升序输出 -->
<select id="findAll" resultType="com.xgf.bean.Category">
select cid,cname from tab_category order by cid asc;
</select>
<!-- 通过id查找category -->
<select id="findOneByCid" parameterType="int" resultType="com.xgf.bean.Category">
select cid,cname from tab_category c where c.cid =#{cid}
</select>
</mapper>
5. 测试运行
运行结果:
Preparing: select cid,cname from tab_category order by cid asc;
Parameters:
Total: 8
[Category{cid=1, cname=‘门票’}, Category{cid=2, cname=‘酒店’}, Category{cid=3, cname=‘香港车票’}, Category{cid=4, cname=‘处境游’}, Category{cid=5, cname=‘国内游’}, Category{cid=6, cname=‘港澳游’}, Category{cid=7, cname=‘抱团定制’}, Category{cid=8, cname=‘全球自由行’}]
6. CategoryServlet
@WebServlet("/categoryServlet")
public class CategoryServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//业务类
CategoryService categoryService = new CategoryService();
//获取所有的分类
List<Category> categoryList=categoryService.findAll();
//以json格式显示在页面上
Msg msg = new Msg();
msg.setCode(200); //响应码
msg.setData(categoryList); //数据
String json = new ObjectMapper().writeValueAsString(info); //转换为json数据格式
response.getWriter().println(json); //响应到浏览器
}
}
7. 导航jsp页面header.jsp
- 通过ajax发送get请求
- jquery的for循环
- html()函数修改界面
- js中字符串拼接,建议最外层用单引号,防止拼接字符串遇到双引号需要通过\转译
- js中的字符串拼接变量的方式
' + 变量名 + '
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<body>
<!-- 头部 start -->
<header id="header">
<div class="top_banner">
<img src="images/top_banner.jpg" alt="头部导航栏">
</div>
<div class="shortcut">
<!-- 登录状态 -->
<div class="login" style="margin-left: -100px">
<%-- 将session中的用户数据取出来 --%>
<%-- 判断用户对象是否为空 如果是提示请登录,否则显示用户信息--%>
<!-- 登录显示 -->
<c:if test="${user != null}">
<span>欢迎使用,${user.username}</span>
<a href="myfavorite.jsp" class="collection">我的收藏</a>
<a href="${pageContext.request.contextPath}/loginOutServlet">退出</a>
</c:if>
<!-- 未登录显示 -->
<c:if test="${user == null}">
<span>您还没有登录</span>
<a href="login.jsp">登录</a>
<a href="register.jsp">注册</a>
</c:if>
</div>
</div>
<div class="header_wrap">
<div class="topbar">
<div class="logo">
<a href="/"><img src="images/logo.jpg" alt=""></a>
</div>
<div class="search">
<input name="" type="text" placeholder="请输入路线名称" class="search_input" autocomplete="off">
<a href="javascript:;" class="search-button">搜索</a>
</div>
<div class="hottel">
<div class="hot_pic">
<img src="images/hot_tel.jpg" alt="">
</div>
<div class="hot_tel">
<p class="hot_time">客服热线(9:00-6:00)</p>
<p class="hot_num">400-000-0000</p>
</div>
</div>
</div>
</div>
</header>
<!-- 头部 end -->
<!-- 首页导航 -->
<script src="js/jquery-1.11.0.min.js" type="text/javascript"></script>
<script type="text/javascript">
//页面加载成功之后执行该函数
$(function () {
//ajax提交 这个data就是服务器返回的数据Msg
$.get("categoryServlet", function (data) {
if (data.code == 200) {
var list = data.data;//获取分类数据
//变量lis用于拼接导航的显示内容(分类)
var lis = "";
//拼接第一项首页
lis += '<li class="nav-active"><a href="index.jsp">首页</a></li>'
//循环所有的分类,加入到lis中
for (var i = 0; i < list.length; i++) {
//在js中,建议在最外行用单引号,避免生成转译的\ list[i].cname获取分类名
var li = '<li><a href="route_list.html">' + list[i].cname + '</a></li>'
//拼接
lis += li
}
//拼接最后一项 收藏排行榜
lis += ' <li><a href="favoriterank.html">收藏排行榜</a></li>'
//将其显示在页面的ul中
// $("#nav").html(lis)
$("#nav").html(lis)
}
}, "json");
})
</script>
<div class="navitem">
<ul class="nav" id="nav">
<%-- 这里填入脚本查询分类li --%>
</ul>
</div>
</body>
</html>
8. 显示效果
2. 导航优化,实现Redis缓存管理导航
用Redis优化的原因和好处:
分类的数据在每一次页面加载后都会重新请求数据库来加载,这种经常访问对数据库的压力比较大,而且类似分类的数据不会经常产生变化,所有可以使用redis来缓存这个数据。
Redis缓存流程
查询数据先从Redis查询,如果是第一次查询,从Redis缓存没查到,查数据库,然后将数据保存到Redis缓存中,以后每次查询都是直接从Redis缓存中取数据,减少数据库的压力。
2.1 创建属性文件jedis.properties
,用来配置连接Redis的基本信息(键值对)
maxTotal=100
maxIdle=15
url=localhost
port=6379
2.2 创建Jedis工具类,连接redis,读取propties文件键值对配置
public class JedisUtils {
//单例模式 静态代码块只执行一次,因为创建会很消耗性能
private static JedisPool pool;
//静态代码在项目中,如果被使用只会加载一次
static {
//读src下的文件用类加载器的方式
InputStream inputStream= JedisUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
//.properties文件专门的读取工具
Properties properties = new Properties();
try {
//将流中的数据读成map
properties.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
// 1:创建连接池的配置对象
JedisPoolConfig config = new JedisPoolConfig();
//设置最大链接数
config.setMaxTotal(Integer.parseInt(properties.getProperty("maxTotal")));
//设置空闲连接数 "3"
config.setMaxIdle(Integer.parseInt(properties.getProperty("maxIdle")));
//2:创建连接池
pool = new JedisPool(config, properties.getProperty("url"), Integer.parseInt(properties.getProperty("port")));
}
public static Jedis getJedis() {
// 3:从连接池中获取一个连接
Jedis jedis = pool.getResource();//获取一个连接
return jedis;
}
public static void close(Jedis jedis) {
if(jedis!=null){
jedis.close();
}
}
}
2.3 修改CategoryServlet
,通过Redis调用
//通过redis实现分类缓存
@WebServlet("/categoryServlet")
public class CategoryServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//访问redis 较快,但是第一次是没有数据的
//访问service,获取json,将json保存到redis
Jedis jedis = JedisUtils.getJedis();
String json = jedis.get("category_list");
if (json != null) {
System.out.println("redis cache");
response.getWriter().println(json);
} else {
System.out.println("mysql data");
//创建业务对象
CategoryService categoryService = new CategoryService();
//所有的分类
List<Category> categoryList=categoryService.findAll();
//显示
Msg msg = new Msg();
msg.setCode(200);
msg.setData(categoryList);
json = new ObjectMapper().writeValueAsString(msg);
//将数据保存到redis
jedis.set("category_list",json);
response.getWriter().println(json);
}
//关闭连接
JedisUtils.close(jedis);
}
}
2.4 开启Redis服务器
2.5 运行
运行结果:第一次查询
从 mysql data 中读取数据
Preparing: select cid,cname from tab_category order by cid asc;
Parameters:
Total: 8
刷新页面第二次/n次查询:(不查询MySQL数据库,不发送sql语句)
从 redis cache 中读取数据
通过Redis的可视化工具查看分类数据