《5K入门级项目实战:好来屋在线影院》之第 11 战 —— 用户端首页、BootStrap 分页(中)

OK,这一节我们开发 API 接口,把需要的数据返回给客户端。

我们先来解决:

1、indexMovie.html 里的热门电影接口数据

2、index.html 文件里的相关接口,如截图:

 

实际的流程是这样:

用户请求首页(即地址栏请求“/”)的时候,会进入到 IndexMovieController 这个类的 “/” 请求中,然后我们查询对应的数据,返回到 index.html (即 view 视图),thymeleaf 模板就可以获取到数据了。

 

修改 IndexMovieController 请求类,完整代码:

package com.movie.controller.consumer;

import com.movie.entity.MovieDynamicEntity;
import com.movie.entity.MovieInfoEntity;
import com.movie.manage.MovieDynamicManage;
import com.movie.manage.MovieInfoManage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * @author biandan
 * @signature 让天下没有难写的代码
 * @create 2019-12-01 下午 5:01
 */
@Controller
public class IndexMovieController {

    //注入电影信息的接口对象
    @Autowired
    private MovieInfoManage movieInfoManage;

    //注入电影动态信息的接口对象
    @Autowired
    private MovieDynamicManage movieDynamicManage;

    //请求首页
    @RequestMapping("/")
    public ModelAndView index(HttpServletRequest request) {
        //查询热门电影
        List<MovieInfoEntity> hotMovieList = movieInfoManage.getHotMovieList();
        //查询最新电影(右边信息栏)
        List<MovieInfoEntity> latestMovieList = movieInfoManage.latestMovieList();
        //查询最新电影动态信息(右边信息栏)
        List<MovieDynamicEntity> movieDynamicList = movieDynamicManage.movieDynamicList();

        ModelAndView view = new ModelAndView();
        view.addObject("title", "首页");
        view.addObject("mainPage", "consumer/indexMovie");
        view.addObject("mainPageKey", "#keyId");
        view.addObject("hotMovieList",hotMovieList);
        view.addObject("latestMovieList",latestMovieList);
        view.addObject("movieDynamicList",movieDynamicList);
        view.setViewName("index");//返回 index.html 页面
        return view;
    }
}

注意:我们的 view 对象在方法 addObject 里的 key,要对应前端的 key,一字不漏。否则无法对应到数据。

 

接下来,我们需要修改 MovieInfoManageMovieDynamicManage 两个接口,增加对应的方法:

MovieInfoManage 接口增加代码:

    //查询热门电影
    List<MovieInfoEntity> getHotMovieList();

    //查询最新电影
    List<MovieInfoEntity> latestMovieList();

MovieDynamicManage  接口增加代码:

    //查询最新电影动态信息
    List<MovieDynamicEntity> movieDynamicList();

对应的,它们的实现类也要实现上述的方法。

MovieInfoManageImpl 实现类增加代码,注意我们默认查询的记录数,定义在实现类上,可以根据实际需要修改数字大小:

    private static int HOT_SIZE = 20;//热门电影查询前 20 条记录

    private static int MSG_SIZE = 10;//列表信息查询 10 条记录


    //查询热门电影
    @Override
    public List<MovieInfoEntity> getHotMovieList(){
        List<MovieInfoEntity> list = new ArrayList<>();
        try{
            list = movieInfoService.getHotMovieList(HOT_SIZE);
        }catch (Exception e){
            e.printStackTrace();
        }
        return list;
    }

    //查询最新电影
    @Override
    public List<MovieInfoEntity> latestMovieList(){
        List<MovieInfoEntity> list = new ArrayList<>();
        try{
            list = movieInfoService.latestMovieList(MSG_SIZE);
        }catch (Exception e){
            e.printStackTrace();
        }
        return list;
    }

MovieDynamicManageImpl 实现类增加代码:

 private static int MSG_SIZE = 10;//列表信息查询 10 条记录

    //查询最新电影动态信息
    @Override
    public List<MovieDynamicEntity> movieDynamicList(){
        List<MovieDynamicEntity> list = new ArrayList<>();
        try{
            list = movieDynamicService.movieDynamicList(MSG_SIZE);
        }catch (Exception e){
            e.printStackTrace();
        }
        return list;
    }

对应的,它们的 Service 类也要增加对应的方法:

MovieInfoService 增加代码:

    //查询热门电影
    @Transactional(readOnly = true)
    public List<MovieInfoEntity> getHotMovieList(int size){
        return movieInfoDao.getHotMovieList(size);
    }

    //查询最新电影
    @Transactional(readOnly = true)
    public List<MovieInfoEntity> latestMovieList(int size){
        return movieInfoDao.latestMovieList(size);
    }

MovieDynamicService 增加代码:

    //查询最新电影动态信息
    @Transactional(readOnly = true)
    public List<MovieDynamicEntity> movieDynamicList(Integer size){
        return movieDynamicDao.movieDynamicList(size);
    }

对应的,它们的 DAO 层也要增加代码:

MovieInfoDao 增加代码:

    //查询热门电影
    List<MovieInfoEntity> getHotMovieList(@Param("size") int size);

    //查询最新电影
    List<MovieInfoEntity> latestMovieList(@Param("size") int size);

MovieDynamicDao 增加代码:

    //查询最新电影动态信息
    List<MovieDynamicEntity> movieDynamicList(Integer size);

最后,它们的 mapper 文件也要增加对应的查询方法。

MovieInfoEntityMapper.xml 增加代码:

 <!-- 查询热门电影 -->
    <select id="getHotMovieList" parameterType="java.lang.Integer" resultMap="BaseResultMap">
        select *
        from movie_info
        where hot = 1
        order by id desc
        limit 0,#{size,jdbcType=INTEGER}
    </select>

    <!-- 查询最新电影 -->
    <select id="latestMovieList" parameterType="java.lang.Integer" resultMap="BaseResultMap">
        select *
        from movie_info
        order by id desc
        limit 0,#{size,jdbcType=INTEGER}
    </select>

MovieDynamicEntityMapper.xml 增加代码:

  <!-- 查询电影动态 -->
  <select id="movieDynamicList" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select d.*,i.movie_name
    from movie_dynamic as d
    LEFT JOIN movie_info as i
    ON d.movie_id = i.id
    order by d.id desc
    limit 0,#{size,jdbcType=INTEGER}
  </select>

OK,我们代码编写完成,启动服务测试效果:http://localhost:8080/

 

OK,我们已经搞定了首页的信息。

接下来,我们继续开发 API 接口:点击电影查看详情的接口,即 indexMovie.html 文件的 a 链接,以及 index.html 里的电影动态信息链接。

 

OK,我们新建一个类:ConsumerMovieController,用来处理点击电影详情的请求,放在 consumer 包下:

package com.movie.controller.consumer;

import com.movie.entity.MovieDynamicEntity;
import com.movie.entity.MovieInfoEntity;
import com.movie.manage.MovieDynamicManage;
import com.movie.manage.MovieInfoManage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;

/**
 * @author biandan
 * @signature 让天下没有难写的代码
 * @create 2019-12-01 下午 4:59
 */
@RestController
@RequestMapping(value = "/consumerMovie")
public class ConsumerMovieController {

    @Autowired
    private MovieInfoManage movieInfoManage;

    @Autowired
    private MovieDynamicManage movieDynamicManage;

    //根据id查询电影详细信息
    @RequestMapping("/{id}")
    public ModelAndView view(@PathVariable("id") Integer id){
        //根据电影 id 查询电影信息
        MovieInfoEntity movie = movieInfoManage.selectById(id);
        ///构造分页信息,根据当前电影 id 获取上一个电影、下一个电影的信息
        String pageCode = movieInfoManage.getPageCode(id);

        //查询最新电影(右边信息栏)
        List<MovieInfoEntity> latestMovieList = movieInfoManage.latestMovieList();
        //查询最新电影动态信息(右边信息栏)
        List<MovieDynamicEntity> movieDynamicList = movieDynamicManage.movieDynamicList();
        //查询该对应对应的动态信息(电影信息下面)
        List<MovieDynamicEntity> dynamicList = movieDynamicManage.dynamicList(id);

        ModelAndView view = new ModelAndView();
        view.addObject("pageCode", pageCode);
        view.addObject("title", movie.getMovieName());
        view.addObject("mainPage", "consumer/view");
        view.addObject("mainPageKey", "#mId");
        view.addObject("movie", movie);
        view.addObject("latestMovieList",latestMovieList);
        view.addObject("movieDynamicList",movieDynamicList);
        view.addObject("dynamicList",dynamicList);
        view.setViewName("index");
        return view;
    }
}

说明:

1、mainPage mainPageKey 这里指定的值,对应 view.html 和 id=mId  需要我们创建。

2、pageCode 是我们的分页信息,可以查看 BootStrap 文档:https://www.runoob.com/bootstrap/bootstrap-pagination.html

这里我们使用最简单的分页

<ul class="pager">
    <li><a href="#">Previous</a></li>
    <li><a href="#">Next</a></li>
</ul>

3、我们还要新增一个接口,用于查询该电影对应的动态信息。

//查询该对应对应的动态信息(电影信息下面)
        List<MovieDynamicEntity> dynamicList = movieDynamicManage.dynamicList(id);

OK,接下来,我们先在前端的 consumer 目录下创建 view.html

<meta charset="UTF-8"/>
<div id="mId">
	<div class="data_list">
		<div class="data_list_movieName">
		<img src="/static/images/movie_icon.png"></img>
		电影详细信息</div>
		<div>
			<div class="movie_movieName"><h3><strong th:text="${movie.movieName}"></strong></h3></div>
		</div>
		<div class="movie_createTime">
			发布时间:<font th:text="${#dates.format(movie.createTime,'yyyy-MM-dd')}"></font>
		</div>
		<div class="movie_content" th:utext="${movie.movieContent}"></div>
		<div class="movie_lastAndNextPage">
			<ul class="pager" th:utext="${pageCode}"></ul>
		</div>
	</div>
	
	<div class="data_list">
		<div class="data_list_movieName">
		<img src="/static/images/list_icon.png"/>
		电影动态信息列表</div>
		<div>
			<table class="table">
		      <thead>
		        <tr>
					<th>序号</th>
					<th>动态信息</th>
					<th>发布日期</th>
		        </tr>
		      </thead>
		      <tbody>
	        	<tr th:each="dynamicInfo,sequence:${dynamicList}">
		          <th scope="row" th:text="${sequence.index+1}"></th>
					<td>
						<a th:href="${dynamicInfo.movieUrl}" th:text="${dynamicInfo.dynamic}"
						   th:title="${dynamicInfo.dynamic}" target="_blank"></a>
					</td>
		          <td th:text="${#dates.format(dynamicInfo.createTime,'yyyy-MM-dd')}" ></td>
		        </tr>
	       </tbody>
	    </table>
		</div>
	</div>
	
</div>
	

说明:

这个属性要对应后台返回的属性值,否则无法找到数据。以及下面的分页信息。

我们来处理一下分页的:

MovieInfoManage 增加方法;

    //根据当前电影 id 获取上一个电影、下一个电影的信息
    String getPageCode(Integer id);

MovieInfoManageImpl 实现类增加方法:

    //根据当前电影 id 获取上一个电影、下一个电影的信息
    @Override
    public String getPageCode(Integer id){
        String pageCode = null;
        try{
            //查询上一个电影信息
            MovieInfoEntity lastInfoEnity = movieInfoService.getLastEntity(id);

            //查询下一个电影信息
            MovieInfoEntity nextInfoEnity = movieInfoService.getNextEntity(id);

            //构建分页
            pageCode = PageCodeUtil.getPageCode(lastInfoEnity,nextInfoEnity);

        }catch (Exception e){
            e.printStackTrace();
        }
        return pageCode;
    }

这里我们需要一个我们自己的工具类 PageCodeUtil,创建在 util 包下,代码如下,具体逻辑自行理解:

package com.movie.util;

import com.movie.entity.MovieInfoEntity;

/**
 * 构造分页对象
 * @author biandan
 * @signature 让天下没有难写的代码
 * @create 2019-12-03 下午 11:01
 */
public class PageCodeUtil {

    /**
     * 构造分页对象方法
     * @param lastEntity 上一个电影信息实体
     * @param nextEntity 下一个电影信息实体
     * @return
     */
    public static String getPageCode(MovieInfoEntity lastEntity, MovieInfoEntity nextEntity) {
        StringBuilder builder = new StringBuilder();
        if (lastEntity == null || lastEntity.getId() == null) {
            builder.append("<p>上一部:没有了</p>");
        } else {
            builder.append("<p>上一部:<a href='/consumerMovie/" + lastEntity.getId() + "'>" + lastEntity.getMovieName() + "</a></p>");
        }
        if (nextEntity == null || nextEntity.getId() == null) {
            builder.append("<p>下一部:没有了</p>");
        } else {
            builder.append("<p>下一部:<a href='/consumerMovie/" + nextEntity.getId() + "'>" + nextEntity.getMovieName() + "</a></p>");
        }
        return builder.toString();
    }
}

MovieInfoService 类增加2个方法:

    //根据 id 查询上一个电影信息
    @Transactional(readOnly = true)
    public MovieInfoEntity getLastEntity(Integer id){
        return movieInfoDao.getLastEntity(id);
    }

    //根据 id 查询下一个电影信息
    @Transactional(readOnly = true)
    public MovieInfoEntity getNextEntity(Integer id){
        return movieInfoDao.getNextEntity(id);
    }

MovieInfoDao 增加2个方法:

    //根据 id 查询上一个电影信息
    MovieInfoEntity getLastEntity(Integer id);

    //根据 id 查询下一个电影信息
    MovieInfoEntity getNextEntity(Integer id);

MovieInfoEntityMapper.xml 增加两个查询方法:

    <!-- 根据 id 查询上一个电影信息,注意左尖括号的使用 -->
    <select id="getLastEntity" parameterType="java.lang.Integer" resultMap="BaseResultMap">
        select id, movie_name, movie_title, hot, image_name, movie_content,create_time
        from movie_info
        <where>
            <![CDATA[ id < #{id,jdbcType=INTEGER} ]]>
        </where>
        order by id desc
        limit 0,1
    </select>

    <!-- 根据 id 查询下一个电影信息 -->
    <select id="getNextEntity" parameterType="java.lang.Integer" resultMap="BaseResultMap">
        select id, movie_name, movie_title, hot, image_name, movie_content,create_time
        from movie_info
        where id > #{id,jdbcType=INTEGER}
        order by id asc
        limit 0,1
    </select>

说明:

1、mapper 文件里不允许使用 < 尖括号,会被误以为是html 的符号,需要使用  <![CDATA[  ]]>  包装起来

2、查询上一个、下一个电影的 id 逻辑,一个是把 id 倒序排,然后取最大的;另一个是 id 顺序排,取最小的值。

 

接下来讲解查询某个电影动态信息的 API 接口:

 MovieDynamicManage 增加方法:

    //查询该对应对应的动态信息(电影信息下面)
    List<MovieDynamicEntity> dynamicList(Integer id);

MovieDynamicManageImpl 实现类:

    //查询该对应对应的动态信息(电影信息下面)
    @Override
    public List<MovieDynamicEntity> dynamicList(Integer id){
        List<MovieDynamicEntity> list = new ArrayList<>();
        try{
            list = movieDynamicService.dynamicList(id);
        }catch (Exception e){
            e.printStackTrace();
        }
        return list;
    }

MovieDynamicService 增加方法:

    //查询该对应对应的动态信息(电影信息下面)
    @Transactional(readOnly = true)
    public List<MovieDynamicEntity> dynamicList(Integer id){
        return movieDynamicDao.dynamicList(id);
    }

MovieDynamicDao 增加方法:

    //查询该对应对应的动态信息(电影信息下面)
    List<MovieDynamicEntity> dynamicList(Integer id);

MovieDynamicEntityMapper.xml 增加方法:

  <!-- 查询该对应对应的动态信息(电影信息下面) -->
  <select id="dynamicList" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select d.*,i.movie_name
    from movie_dynamic as d
    LEFT JOIN movie_info as i
    ON d.movie_id = i.id
    where d.movie_id = #{id,jdbcType=INTEGER}
  </select>

OK,我们启动服务,测试:http://localhost:8080/

 

效果出来了:

 

为了直观的看到效果,我们可以去数据库 movie_dynamic 修改一些动态信息,对应具体的电影的,如下图;

效果如下图:

 

OK,我们的测试成功。如果电脑链接网络,还可以看视频,快和你的朋友分享喜悦吧!perfect!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值