当博客开发到这里了,很多功能都是相通的,后端管理基本上就是增删改查、前端显示基本上就是返回model。
根据页面的功能需求,返回所有分类和该分类下的所有博客文章列表(列表展示和首页相同,所有不需要在新建VO)。
1.持久层接口
引用oneStar的内容:
这里需要两个接口,一个查询分类和该分类下博客数目(getAllTypeAndBlog)、一个是查询博客文章列表(getByTypeId),查询分类和该分类下博客数目是和分类相关的,就放在分类的Dao里面,查询博客文章列表是和博客相关的,就放在博客的Dao里面。
- 在TypeDao接口中添加:
/*============前台业务==========================*/
//查询所有分类(包括该分类下的博客数)
List<Type> getAllTypeAndBlog();
- 在BlogDao接口中添加:
/*=========博客分类查询==============*/
//根据typeId查询博客列表,显示在分类页面
List<LatestBlog> getByTypeId(Long typeId);
2.mapper
博客和分类是多对一的关系,所以需要mybatis的多表查询(collection),在博客后台管理有简要说明过。
TypeDao.xml
添加如下sql:
<!--查询所有分类(包括该分类下的博客数),要往Type里面存东西(做映射),不然统计不了 list的博客数量-->
<select id="getAllTypeAndBlog" resultMap="type">
select t.id tid,t.name,b.id bid,b.title,b.type_id
from t_type t,t_blog b
where t.id=b.type_id;
</select>
<resultMap id="type" type="Type">
<id property="id" column="tid"/>
<result property="name" column="name"/>
<collection property="blogs" ofType="Blog">
<id property="id" column="bid"/>
<result property="title" column="title"/>
<result property="typeId" column="type_id"/>
</collection>
</resultMap>
- BlogDao
<!--==========================分类查询博客(根据博客id)===================-->
<!--根据typeId查询博客列表,显示在分类页面(复用之前查(博客列表的map) LatestBlog)-->
<select id="getByTypeId" resultMap="LatestBlog">
select b.id,b.title,b.description,b.update_time,b.first_picture,b.views,b.comment_count,
t.name,
u.avatar,u.username
from t_blog b,t_type t,t_user u
where b.type_id=t.id and u.id=b.user_id and b.type_id=#{typeId};
</select>
3. 业务层
-
TypeService
添加如下代码://查询所有分类(包括该分类下的博客数) List<Type> getAllTypeAndBlog();
TypeServiceImpl
添加:@Override public List<Type> getAllTypeAndBlog() { return typeDao.getAllTypeAndBlog(); }
-
BlogService
添加如下代码:/*=========博客分类查询==============*/ //根据typeId查询博客列表,显示在分类页面 List<LatestBlog> getByTypeId(Long typeId);
BlogServiceImpl
添加:@Override public List<LatestBlog> getByTypeId(Long typeId) { return blogDao.getByTypeId(typeId); }
4. 控制器
实现分页的局部刷新,和首页同理。
前端改动:
分页部分:
<div class="two wide column" align="center">
<a class="item" style="cursor: pointer" onclick="page(this)" th:attr="data-page=1" th:unless="${pageInfo.isFirstPage}">首页</a>
</div>
<div class="two wide column" align="center">
<!--<a class="item" th:href="@{/admin/blogs(pageNum=${pageInfo.hasPreviousPage}?${pageInfo.prePage}:1)}" th:unless="${pageInfo.isFirstPage}">上一页</a>-->
<a class="item" style="cursor: pointer" onclick="page(this)" th:attr="data-page=${pageInfo.hasPreviousPage}?${pageInfo.prePage}:1" th:unless="${pageInfo.isFirstPage}">上一页</a>
</div>
<div class="eight wide column" align="center">
<p><span th:text="${pageInfo.pageNum}"></span> / <span
th:text="${pageInfo.pages}"></span></p>
</div>
<div class="two wide column " align="center">
<!--<a class="item" th:href="@{/admin/blogs(pageNum=${pageInfo.hasNextPage}?${pageInfo.nextPage}:${pageInfo.pages})}" th:unless="${pageInfo.isLastPage}">下一页</a>-->
<a class="item" style="cursor: pointer" onclick="page(this)" th:attr="data-page=${pageInfo.hasNextPage}?${pageInfo.nextPage}:${pageInfo.pages}" th:unless="${pageInfo.isLastPage}">下一页</a>
</div>
<div class="two wide column " align="center">
<a class="item" style="cursor: pointer" onclick="page(this)" th:attr="data-page=${pageInfo.pages}" th:unless="${pageInfo.isLastPage}">尾页</a>
</div>
JS部分:
function page(obj) {
$("[name='page']").val($(obj).data("page"));
loaddata();
$(window).scrollTo($('#type-container'),500);
}
function loaddata() {
$("#type-container").load(/*[[@{/typeRefresh}]]*/
"/typeRefresh",{
id : $("[name='typeId']").val(),
pageNum : $("[name='page']").val()
},function (responseTxt, statusTxt, xhr) {
$(window).scrollTo($('#type-container'),500);
});
}
在controller
包下创建TypeShowController
类
@Controller
public class TypeShowController {
@Autowired
private TypeService typeService;
@Autowired
private BlogService blogService;
@GetMapping("/types/{id}")
public String types(Model model, @PathVariable("id")Long id,@RequestParam(defaultValue = "1",value = "pageNum") Integer pageNum){
List<Type> types = typeService.getAllTypeAndBlog();
//id=-1表示从首页导航栏进入分类页面
if(id == -1){
id = types.get(0).getId();
}
//根据选的 id 来查 对应博客
String orderBy="b.update_time desc";
PageHelper.startPage(pageNum,2,orderBy);
List<LatestBlog> blogs = blogService.getByTypeId(id);
PageInfo<LatestBlog> pageInfo = new PageInfo<>(blogs);
model.addAttribute("pageInfo",pageInfo);
model.addAttribute("activeTypeId",id);//激活对应分类 选项框
model.addAttribute("types",types);
return "types";
}
@PostMapping("/typeRefresh")
public String typeRefresh(Model model,@RequestParam("id")Long id,@RequestParam(defaultValue = "1",value = "pageNum") Integer pageNum){
List<Type> types = typeService.getAllTypeAndBlog();
//id=-1表示从首页导航栏进入分类页面
if(id == -1){
id = types.get(0).getId();
}
/*主要用到下面的*/
//根据选的 id 来查 对应博客
String orderBy="b.update_time desc";
PageHelper.startPage(pageNum,2,orderBy);
List<LatestBlog> blogs = blogService.getByTypeId(id);
System.out.println(blogs);
PageInfo<LatestBlog> pageInfo = new PageInfo<>(blogs);
model.addAttribute("pageInfo",pageInfo);
model.addAttribute("activeTypeId",id);//激活对应分类 选项框
return "types :: typesList";
}
}
到这里时,基本功能实现都大差不大,前面难的都已经完成了,后面的功能就不再详细说明。
浏览页面的效果图: