本文共 11777 字,大约阅读时间需要 39 分钟。
分页成果展示:
1.数据库准备好数据:我网站中的数据时通过python爬虫,直接保存到数据库中的。图片直接保存的豆瓣的url。
2.整合mybatis依赖和mybatis分页插件:
根据此教程完成初步操作:(不要选择kotlin即可)
然后添加分页插件依赖:官网
//mybatis分页插件 compile group: 'com.github.pagehelper', name:'pagehelper-spring-boot-starter',version: '1.2.10'
有三种分页方式:。我选择的是后台分页。
因为使用mybatis分页插件直接得到的是json数据,所以我直接使用接口来访问和传递数据。如果不想用接口的话,也可以使用模版等方式,不过我就不说了。
使用接口后,前端可以直接通过ajax来通过rest风格接口获取数据。
示例:
{"total":6,"list":[{"id":26752088,"name":"我不是药神","score":9.0,"url":"https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2519070834.jpg"},{"id":26425063,"name":"无双","score":8.2,"url":"https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2535096871.jpg"},{"id":26647117,"name":"暴裂无声","score":8.2,"url":"https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2517333671.jpg"},{"id":27110296,"name":"无名之辈","score":8.3,"url":"https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2539661066.jpg"},{"id":25716096,"name":"狗十三","score":8.5,"url":"https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2540474819.jpg"},{"id":30206517,"name":"切尔诺贝利之春","score":8.0,"url":"https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2520682504.jpg"}],"pageNum":1,"pageSize":10,"size":6,"startRow":1,"endRow":6,"pages":1,"prePage":0,"nextPage":0,"isFirstPage":true,"isLastPage":true,"hasPreviousPage":false,"hasNextPage":false,"navigatePages":8,"navigatepageNums":[1],"navigateFirstPage":1,"navigateLastPage":1}
我直接给出我的流程:
1.编写controller层(根据之前设计好的接口来)
@RestControllerpublic class CategoryController { @Autowired private CategoryService categoryService; @GetMapping("/page") public PageInfopage(@RequestParam(value = "start",defaultValue = "1") String start, @RequestParam(value = "size",defaultValue = "6") String size, @RequestParam(value = "genres",required=false) String genres , @RequestParam(value = "sort",defaultValue = "0") String sort, @RequestParam(value = "beginyear",required=false) String beginyear, @RequestParam(value = "endyear",required=false) String endyear, @RequestParam(value = "place",required=false) String place ){ Map myMap= new HashMap<>(7); myMap.put("start",start); myMap.put("size",size); myMap.put("genres",genres); myMap.put("sort",sort); myMap.put("beginyear",beginyear); myMap.put("endyear",endyear); myMap.put("place",place); return categoryService.homePage(myMap); }}
2.编写service层:
在执行sql前添加插件,完成分页功能:参考
我们知道,在中,分页的sql是使用limit来做,如果我们自己写sql,那分页肯定是没有任何问题的。但是一旦model多了起来,复杂了起来,我们很自然的想到使用mybatis的逆向工程来生成相应的po和mapper,但是同时也会带来弊端,比如这里的分页问题就不好解决了。 所以还是选择使用分页插件。
在查询的sql语句执行之前,添加一行代码PageHelper.startPage(x,y);
第一个参数表示第几页,第二个参数表示每页显示的记录数。这样在执行sql后就会将记录按照语句中设置的那样进行分页。如果需要获取总记录数的话,需要PageInfo类的对象,这个对象可以获取总记录数,下面看下测试的代码。
public interface CategoryService { PageInfo homePage(Mapmap);}@Servicepublic class CategoryServiceImpl implements CategoryService { @Resource private MovieShowBeanMapper movieShowBeanMapper; @Resource private CategoryMapper categoryMapper; @Override public PageInfo homePage(Map myMap) { //设置分页参数 PageHelper.startPage(Integer.valueOf(myMap.get("start")),Integer.valueOf(myMap.get("size"))); List list=movieShowBeanMapper.findShowMovie(myMap.get("genres"), myMap.get("sort"), myMap.get("beginyear"), myMap.get("endyear"), myMap.get("place")); //使用对象包装返回结果 return new PageInfo(list); }}
3.编写dao层(或者说是mapper)
因为需要根据选择来判断是否添加限定条件,所以必须是动态sql。
因为注解方式很简单,所以我直接使用注解的方式完成操作。
参考阅读:
@SelectProvider(type = MovieShowSqlProvider.class, method = "selectShow"):使用MovieShowSqlProvider.class这个类中的方法selectShow返回的sql字符串 作为查询的语句。
@Results注解:结果映射的列表, 包含了一个特别结果列如何被映射到属性或字段的详情。属性:value, id。value 属性是 Result 注解的数组。这个id的属性是结果映射的名称可以省略。
@Result注解:column为数据库字段名,porperty为实体类属性名,jdbcType为数据库字段数据类型,id为是否为主键。
public interface MovieShowBeanMapper { @SelectProvider(type = MovieShowSqlProvider.class, method = "selectShow") @Results(value = { @Result( id=true, property = "id",column = "id"), @Result(property = "name",column = "name"), @Result(property = "score",column = "score") }) ListfindShowMovie( @Param("genres") String genres , @Param("sort") String sort, @Param("beginyear") String beginyear, @Param("endyear") String endyear, @Param("place") String place );}
4.编写mapper中用到的动态sql:MovieShowSqlProvider类
参考:
然后在这个类中进行sql语句的拼接
tempSql=new SQL().SELECT("movie_id").FROM("class_contact"); 因为是分页查询,使用的是子查询的方式public class MovieShowSqlProvider { /*完整的sql语句 SELECT m.id,m.name,m.time from movie m WHERE id in ( SELECT movie_id from place WHERE name ="中国大陆" and movie_id in (SELECT movie_id from class_contact WHERE class_id=11) ) and YEAR(m.time)>1995 and YEAR(m.time)<=2018 ORDER BY(YEAR(m.time)) desc*/ public String selectShow(Mapmap){ SQL tempSql=null; String order="order by m.comment_num"; //1.是否有分类 if(map.get("genres") != null){ tempSql=new SQL().SELECT("movie_id").FROM("class_contact"); if(map.get("place") != null){ SQL tempSql2=new SQL().SELECT("movie_id").FROM("place") .WHERE("name=#{place}"); tempSql.WHERE("movie_id in("+tempSql2+")") .WHERE("class_id=#{genres}"); } else{ tempSql.WHERE("class_id=#{genres}"); } } else{ if(map.get("place") != null){ tempSql=new SQL().SELECT("movie_id").FROM("place") .WHERE("name=#{place}"); } } //判断排序方式 SQL finalTempSql = tempSql; return new SQL(){ { SELECT("m.id,m.name,m.score,m.url"); FROM("movie m"); if(finalTempSql !=null) WHERE("m.id in("+finalTempSql+")"); if(map.get("beginyear") != null) WHERE("YEAR(m.time)>=#{beginyear}"); if(map.get("endyear") != null) WHERE("YEAR(m.time)<=#{endyear}"); //排序 if(map.get("sort").equals("1")){ ORDER_BY("m.time desc"); } else if(map.get("sort").equals("2")){ ORDER_BY("m.score desc"); } else{ ORDER_BY("m.comment_num desc"); } } }.toString(); }}
好啦,单元测试自己写喽。还有注意写异常处理。(我暂时还不会写)
相关阅读:
1.
2.
3.
4.
5.
逆向工程可用可不用,对我工程来说是没必要的。
直接通过点按钮击触发参数,通过参数发送get请求,参数放在里面。
不过因为不太清楚get请求,我直接使用的拼接url来发送get请求。
然后前端通过js进行数据处理,我听说前端也有数据处理插件,不过没有查询资料。感兴趣的可以查一查。
//请求jsonfunction sendurl() { //先构造基础部分 baseUrl="/page?size="+size+"&start="+start+"&sort="+sort; if(genres!=""){ baseUrl+="&genres="+genres; } if(place!=""){ baseUrl+="&place="+place; } if(beginyear!=""){ baseUrl+="&beginyear="+beginyear; } if(endyear!=""){ baseUrl+="&endyear="+endyear; } $.ajax({ //访问地址 url: baseUrl, //访问方式,一般有GET或POST两种 type: 'GET', //返回的数据格式,这个是可选参数,jquery回默认判断返回参数的类型 dataType: 'json' /*//发送的数据 data: { param1: 'value1', param2: 'value2' },*/ }) //成功后的处理函数,res为服务器返回的数据 .done(function(data) { //删除当前页面显示: $(".want_remove").remove(); toastr.success('获取数据成功:ヾ(o◕∀◕)ノヾ'); //因为设置了type,返回的就是json对象 //构造电影模块 //背景变量 var myback=["bg-danger","bg-primary","bg-success","bg-info","bg-secondary"] var lineNum=size/2; $.each(data.list,function(idx,item) { myscore=Math.round(item.score/2); var myn=idx%5; var star=""; for(i=0;i\n" + " \n" + " \n" + "\n" + " " ); } else{ $("#second_row").append( "\n" + "\n" + ""+item.name+"
\n" + ""+star+item.score+"
\n" + "\n" + "" ); } }) // $(".want_remove").fadeIn("slow"); //构造分页栏 //显示基本信息 $("#myresult").text("共"+data.total+"部;"+data.pages+"页"); //删除之前的标签 $(".can_remove").remove(); //设置标签页 /*for(i=0;i\n" + " \n" + "\n" + "\n" + "\n" + ""+item.name+"
\n" + ""+star+item.score+"
\n" + "" + item + "" ); } else{ $("#list_next").before( " " + item+ " " ); } }) //如果前一页不存在 if(!data.hasPreviousPage) $("#list_pre").addClass("disabled"); else{ $("#list_pre").removeClass("disabled"); } //如果后一页不存在 if(!data.hasNextPage) $("#list_next").addClass("disabled"); else{ $("#list_next").removeClass("disabled"); } //分别是数组 console.log("success"); }) //失败后的处理函数 .fail(function() { toastr.error('Error:肯定不是服务器炸了ヾノ≧∀≦)o死开!'); console.log("error"); }) //结束后的处理函数,不管成功失败都执行 /*.always(function(res) { console.log("complete"); });*/ //get不能判断是否失败 /*$.get(baseUrl,function(result){ alert(result); });*/}
最终完成喽。
转载地址:http://nfihn.baihongyu.com/