【慕课网实战】Spark Streaming实时流处理项目实战笔记二十之铭文升级版
铭文一级:
Spring Boot整合Echarts动态获取HBase的数据
1) 动态的传递进去当天的时间
a) 在代码中写死
b) 让你查询昨天的、前天的咋办?
在页面中放一个时间插件(jQuery插件),默认只取当天的数据
2) 自动刷新展示图
每隔多久发送一个请求去刷新当前的数据供展示
统计慕课网当天实战课程从搜索引擎过来的点击量
数据已经在HBase中有的
自己通过Echarts整合Spring Boot方式自己来实现
铭文二级:
在Spring Boot项目pom.xml下引入<repositories>
<repositories> <repository> <id>cloudera</id> <url>https://repository.cloudera.com/artifactory/cloudera-repos</url> </repository> </repositories>
引入HBase的依赖:org.apache.hbase:hbase-client:1.2.0-cdh5.7.0
拷贝HBaseUtils进来过来改,添加方法:
/** * 根据表名和输入条件获取HBase的记录数 */ public Map<String, Long> query(String tableName, String condition) throws Exception { Map<String, Long> map = new HashMap<>(); HTable table = getTable(tableName); String cf = "info"; String qualifier = "click_count"; Scan scan = new Scan(); Filter filter = new PrefixFilter(Bytes.toBytes(condition)); scan.setFilter(filter); ResultScanner rs = table.getScanner(scan); for(Result result : rs) { String row = Bytes.toString(result.getRow()); long clickCount = Bytes.toLong(result.getValue(cf.getBytes(), qualifier.getBytes())); map.put(row, clickCount); } return map; }
重点:
先得到table,再根据查询条件condition过滤出rs,
然后遍历rs->直接获得row,根据cf、qualifier得到点击数clickCount
将row、clickCount添加put进map
过滤条件:
Scan scan = new Scan();
scan.setFilter(new PrefixFilter(Bytes.toBytes(condition)));
ResultScanner rs = getTable(tableName).getScanner(scan);
添加主函数进行测试:
public static void main(String[] args) throws Exception { Map<String, Long> map = HBaseUtils.getInstance().query("imooc_course_clickcount" , "20171022"); for(Map.Entry<String, Long> entry: map.entrySet()) { System.out.println(entry.getKey() + " : " + entry.getValue()); } }
重点:
Map.Entry<String, Long> entry: map.entrySet()
entry.getKey() + " : " + entry.getValue()
此处用到的是第三种:Map集合的四种遍历方式
返回的结果为:20171022_128 :1066 //只是获得课程id无法满足要求要求
为了匹配Echarts的name、value属性,所以需要组装一个domain:CourseClickCount
新建一个数据访问类:CourseClickCountDAO
新建query方法,返回值为List<CourseClickCount>
参考代码:
package com.imooc.dao; import com.imooc.domain.CourseClickCount; import com.imooc.utils.HBaseUtils; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * 实战课程访问数量数据访问层 */ @Component public class CourseClickCountDAO { /** * 根据天查询 */ public List<CourseClickCount> query(String day) throws Exception { List<CourseClickCount> list = new ArrayList<>(); // 去HBase表中根据day获取实战课程对应的访问量 Map<String, Long> map = HBaseUtils.getInstance().query("imooc_course_clickcount","20171022"); for(Map.Entry<String, Long> entry: map.entrySet()) { CourseClickCount model = new CourseClickCount(); model.setName(entry.getKey()); model.setValue(entry.getValue()); list.add(model); } return list; } public static void main(String[] args) throws Exception{ CourseClickCountDAO dao = new CourseClickCountDAO(); List<CourseClickCount> list = dao.query("20171022"); for(CourseClickCount model : list) { System.out.println(model.getName() + " : " + model.getValue()); } } }
但是,得到的还是课程Id,还没有具体的名称,所以还要加一层映射关系
建立Web层ImoocStatApp:
/** * web层 */ @RestController public class ImoocStatApp { private static Map<String, String> courses = new HashMap<>(); static { courses.put("112","Spark SQL慕课网日志分析"); courses.put("128","10小时入门大数据"); courses.put("145","深度学习之神经网络核心原理与算法"); courses.put("146","强大的Node.js在Web开发的应用"); courses.put("131","Vue+Django实战"); courses.put("130","Web前端性能优化"); } @Autowired CourseClickCountDAO courseClickCountDAO; // @RequestMapping(value = "/course_clickcount_dynamic", method = RequestMethod.GET) // public ModelAndView courseClickCount() throws Exception { // ModelAndView view = new ModelAndView("index"); // List<CourseClickCount> list = courseClickCountDAO.query("20171022"); // for(CourseClickCount model : list) { // model.setName(courses.get(model.getName().substring(9))); // } // JSONArray json = JSONArray.fromObject(list); // view.addObject("data_json", json); // return view; // } @RequestMapping(value = "/course_clickcount_dynamic", method = RequestMethod.POST) @ResponseBody public List<CourseClickCount> courseClickCount() throws Exception { List<CourseClickCount> list = courseClickCountDAO.query("20171022"); for(CourseClickCount model : list) { model.setName(courses.get(model.getName().substring(9))); } return list; } @RequestMapping(value = "/echarts", method = RequestMethod.GET) public ModelAndView echarts(){ return new ModelAndView("echarts"); } }
static{}内容应该配到数据库里面去,此处只是为了方便
另外需要添加注解
ImoocStatApp:@RestController
CourseClickCountDAO层:@Component
HelloBoot:@RestController
domain/CourseClickCount:@Component
自动装载:@Autowired
如果不是用ajax获取数据则:ModelAndView courseClickCount()
若是则升级成:List<CourseClickCount> courseClickCount()
注意:json格式需要添加依赖
net.sf.json-lib:json-lib:2.4:jdk1.5(classifier)
substring(9) //从第9位取到最后
动态页面设计,data删除后,栏目不见:
legend: {
orient: 'vertical',
left: 'left'
},
引入Echarts、JQuery(使用Ajax交互需要)的js文件:
<!-- 引入 ECharts 文件 -->
<script src="js/echarts.min.js"></script>
<!-- 引入 jQuery 文件 -->
<script src="js/jquery.js"></script>
修改series下的data,原先:
data:[ {value:3350, name:'Spark SQL项目实战'}, {value:3100, name:'Hadoop入门'}, {value:2340, name:'Spark Streaming项目实战'}, {value:1350, name:'大数据面试题'}, {value:15480, name:'Storm项目实战'} ],
修改后:
data: (function(){ //<![CDATA[ var datas = []; $.ajax({ type: "POST", url: "/imooc/course_clickcount_dynamic", dataType: 'json', async: false, success: function(result) { for(var i=0; i<result.length; i++) { datas.push({"value":result[i].value, "name":result[i].name}) } } }) return datas; //]]> })(),
没有加会报类型错误
//<![CDATA[
//]]>
打包到生产上面:
在本地的project文件夹目录下:mvn clean package -DskipTests
scp jar包 到linux上
启动包:java -jar jar包名