python爬虫豆瓣读书top250+数据清洗+数据库+Java后端开发+Echarts数据可视化(五)

接下来继续完成各作者出版图书数量、图书价格数量总计、各评分书籍数量的相关代码及结果展示。具体不详细讲了,可参考(四)https://blog.csdn.net/qq_45804925/article/details/113117424

1 各作者出版图书数量

在这里插入图片描述

1.1 在cn.geo.doubanbook.entity包下创建Author.java类

package cn.geo.doubanbook.entity;

import java.io.Serializable;
/**
 * 各作者出版图书数量
 * @author SGG
 *
 */
public class Author implements Serializable{

	private static final long serialVersionUID = 1365043351381386615L;
	
	private String author;
	private Integer num;
	
	public Author() {	}
	
	public Author(String author, Integer num) {
		super();
		this.author = author;
		this.num = num;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((author == null) ? 0 : author.hashCode());
		result = prime * result + ((num == null) ? 0 : num.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Author other = (Author) obj;
		if (author == null) {
			if (other.author != null)
				return false;
		} else if (!author.equals(other.author))
			return false;
		if (num == null) {
			if (other.num != null)
				return false;
		} else if (!num.equals(other.num))
			return false;
		return true;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public Integer getNum() {
		return num;
	}
	public void setNum(Integer num) {
		this.num = num;
	}
	@Override
	public String toString() {
		return "Author [author=" + author + ", num=" + num + "]";
	}		
}

1.2 在cn.geo.doubanbook.dao包下创建AuthorDAO.java类

package cn.geo.doubanbook.dao;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import cn.geo.doubanbook.entity.Author;
import cn.geo.doubanbook.util.DBUtils;

/**
 * 各作者出版图书数量的持久层类
 * @author SGG
 *
 */
public class AuthorDAO {
	
	/**
	 * 查询各作者出版图书数量
	 * @return
	 * @throws SQLException
	 */
	public List<Author> listAuthor() throws SQLException {
		List<Author> list = new ArrayList<Author>(248);
		
		// 从数据库连接池获取连接
		Connection conn = DBUtils.getConn();
		// 声明SQL的执行器
		Statement st = conn.createStatement();
		// 执行SQL语句
		String sql = "select * from book_author_num";
		ResultSet rs = st.executeQuery(sql);
		// 对结果集进行操作
		while(rs.next()) {
			// 获取该行数据中的指定字段
			String author = rs.getString("author");
			int num = rs.getInt("num");
			// 创建Author对象,封装一行数据
			Author an= new Author(author, num);
			// 将Author对象 保存到集合中
			list.add(an);
		}
		// 关闭连接释放资源
		st.close();
		conn.close();
		
		return list;	
	}
}

1.3 持久层测试用例开发

package cn.geo.doubanbook.dao;

import java.sql.SQLException;
import java.util.List;

import org.junit.Test;

import cn.geo.doubanbook.dao.AuthorDAO;
import cn.geo.doubanbook.entity.Author;

public class AuthorDAOTest {
	
	AuthorDAO dao = new AuthorDAO();

	@Test
	public void listAuthor() throws SQLException{
		List<Author> list = dao.listAuthor();
		list.forEach(item->System.out.println(item));
	}
}

1.4 在cn.geo.doubanbook.entity包下创建AuthorVO.java类

package cn.geo.doubanbook.entity;

import java.io.Serializable;
import java.util.List;

public class AuthorVO implements Serializable{

	private static final long serialVersionUID = 4109889845897505740L;
	
	private List<String> xData;
	private List<Integer> yData;

	public AuthorVO() {	}
	/**
	 * @param xData
	 * @param yData
	 */
	public AuthorVO(List<String> xData, List<Integer> yData) {
		super();
		this.xData = xData;
		this.yData = yData;
	}
	@Override
	public String toString() {
		return "AuthorVO [xData=" + xData + ", yData=" + yData + "]";
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((xData == null) ? 0 : xData.hashCode());
		result = prime * result + ((yData == null) ? 0 : yData.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		AuthorVO other = (AuthorVO) obj;
		if (xData == null) {
			if (other.xData != null)
				return false;
		} else if (!xData.equals(other.xData))
			return false;
		if (yData == null) {
			if (other.yData != null)
				return false;
		} else if (!yData.equals(other.yData))
			return false;
		return true;
	}
	public List<String> getxData() {
		return xData;
	}
	public void setxData(List<String> xData) {
		this.xData = xData;
	}
	public List<Integer> getyData() {
		return yData;
	}
	public void setyData(List<Integer> yData) {
		this.yData = yData;
	}
}

1.5 在cn.geo.doubanbook.service包下创建AuthorService.java类

package cn.geo.doubanbook.service;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import cn.geo.doubanbook.dao.AuthorDAO;
import cn.geo.doubanbook.entity.Author;
import cn.geo.doubanbook.entity.AuthorVO;

public class AuthorService {

	private AuthorDAO dao = new AuthorDAO();
	
	public AuthorVO findAuthor() {
		// 调用持久层方法,查询所需数据
		List<Author> list = null;
		try {
			list = dao.listAuthor();
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
		// 创建xData,保存x轴数据
		List<String> xData = new ArrayList<String>(list.size());
		// 创建yData,保存y轴数据
		List<Integer> yData = new ArrayList<Integer>(list.size());
		// 遍历持久层查询到的数据
		for(Author an: list) {
			xData.add(an.getAuthor());
			yData.add(an.getNum());
		}
		// 创建AuthorVO对象,封装xData和yData
		AuthorVO vo = new AuthorVO(xData, yData);
		return vo;
	}
}

1.6 业务层测试用例开发

package cn.geo.doubanbook.service;

import org.junit.Test;

import cn.geo.doubanbook.entity.AuthorVO;

public class AuthorServiceTest {

	AuthorService service = new AuthorService();
	
	@Test
	public void findAuthor() {
		AuthorVO vo = service.findAuthor();
		System.out.println(vo);
	}
}

1.7 Web层开发

package cn.geo.doubanbook.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;

import cn.geo.doubanbook.entity.AuthorVO;
import cn.geo.doubanbook.service.AuthorService;

public class AuthorServlet extends HttpServlet {

	private static final long serialVersionUID = -7118566587768546293L;
	private AuthorService service = new AuthorService();
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 调动业务层方法,获取AuthorVO
		AuthorVO vo = service.findAuthor();
		// 判断AuthorVO是否不为null
		if(vo != null) {
		    // 将vo对象转变成JSON字符串-基于JSON插件实现
			String jsonStr = JSON.toJSONString(vo);
			// 通知浏览器,本次返回的数据是JSON格式
			resp.setContentType("application/json;charset=utf-8");
			// 将JSON字符串添加到response对象中
			resp.getWriter().write(jsonStr);
		} else {
			// 返回空的json字符串
			// 通知浏览器,本次返回的数据是JSON格式
			resp.setContentType("application/json;charset=utf-8");
			// 将JSON字符串添加到response对象中
			resp.getWriter().write("{}");
		}
	}
}

1.8 在webapp/WEB-INF/web.xml文件中对Servlet进行配置

<servlet>
		<servlet-name>AuthorServlet</servlet-name>
		<servlet-class>cn.geo.doubanbook.web.AuthorServlet</servlet-class>	
</servlet>
<servlet-mapping>
		<servlet-name>AuthorServlet</servlet-name>
		<url-pattern>/author</url-pattern>
</servlet-mapping>

1.9 前端页面开发

在webapp根目录下,创建authorNum.html文件。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>各作者出版图书数量</title>
<script src="js/echarts.min.js"></script>
<script src="js/jquery-1.11.0.min.js"></script>
</head>
<body>
	
	<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
    <div id="author" style="width: 1300px;height:500px;"></div>
    <script type="text/javascript">
    
 		// 声明服务器数据的url
    	var url = "http://localhost:8080/doubanbook/author";
    	// 发送Ajax请求,从服务器获取数据
		$.get(url, function(result) {
			// x轴数据: 作者
			var xData = result.xData;
			// y轴数据: 数量
			var yData = result.yData;
		
			// 基于准备好的dom,初始化echarts实例
	        var myChart = echarts.init(document.getElementById('author'));
			
	     	// 指定图表的配置项和数据
	        var option = {
	        	// 图表标题
	            title: {
	                text: '各作者出版图书数量'
	            },
	            // 提示框
	            tooltip : {
            		trigger: 'axis',
            		axisPointer: {
                		type: 'cross',
                		label: {
                    		backgroundColor: '#6a7985'
                		}
            		}
            	},
	            // 图例
	            legend: {
	                data:['出版量']
	            },
	            //工具栏组件
	            toolbox: {   
	                show: true,
	                feature:{  //需要的功能
	                    saveAsImage: {
	                        show: true	//保存为图片
	                    }, 
	                    dataView: {
	                        show: true	//数据视图         
	                    },
	                    dataZoom: {
	                        show: true	//区域缩放与区域缩放还原            
	                    },
	                    magicType: {
	                        type: ['line', 'bar']	//动态类型转换       
	                    }
	                }
	            },
	            // x轴
	            xAxis: {
	            	data : xData
	            },
	            // y轴
	            yAxis: {},
	            // 系列列表
	            series: [{
	                name: '出版量',
	                type: 'line',
	                data: yData
	            }]
	        };
	     	// 使用刚指定的配置项和数据显示图表
	        myChart.setOption(option);
		});
	</script>	
</body>
</html>

2 图书价格数量总计

在这里插入图片描述

2.1 在cn.geo.doubanbook.entity包下创建Price.java类

package cn.geo.doubanbook.entity;

import java.io.Serializable;

public class Price implements Serializable{

	private static final long serialVersionUID = -4261027434571682623L;
	
	private Float price;	
	private Integer num;
	
	public Price() {
		
	}
	public Price(Float price, Integer num) {
		super();
		this.price = price;
		this.num = num;
	}
	public Float getPrice() {
		return price;
	}
	public void setPrice(Float price) {
		this.price = price;
	}
	public Integer getNum() {
		return num;
	}
	public void setNum(Integer num) {
		this.num = num;
	}
	
	
	@Override
	public String toString() {
		return "Price [price=" + price + ", num=" + num + "]";
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((num == null) ? 0 : num.hashCode());
		result = prime * result + ((price == null) ? 0 : price.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Price other = (Price) obj;
		if (num == null) {
			if (other.num != null)
				return false;
		} else if (!num.equals(other.num))
			return false;
		if (price == null) {
			if (other.price != null)
				return false;
		} else if (!price.equals(other.price))
			return false;
		return true;
	}
}

2.2 在cn.geo.doubanbook.dao包下创建PriceDAO.java类

package cn.geo.doubanbook.dao;

import java.sql.*;
import java.util.*;

import cn.geo.doubanbook.entity.Price;
import cn.geo.doubanbook.util.DBUtils;

public class PriceDAO {
	/**
	 * 查询各个国家出版的图书数量
	 * @return
	 * @throws SQLException
	 */
	public List<cn.geo.doubanbook.entity.Price> listPrice() throws SQLException {
		List<Price> list = new ArrayList<Price>(248);
		
		// 从数据库连接池获取连接
		Connection conn = DBUtils.getConn();
		// 声明SQL的执行器
		Statement st = conn.createStatement();
		// 执行SQL语句
		String sql = "select * from book_price_num";
		ResultSet rs = st.executeQuery(sql);
		// 对结果集进行操作
		while(rs.next()) {
			// 获取该行数据中的指定字段
			Float price = rs.getFloat("price");
			int num = rs.getInt("num");
			// 创建Country对象,封装一行数据
			Price cn= new Price(price, num);
			// 将Country对象 保存到集合中
			list.add(cn);
		}
		// 关闭连接释放资源
		st.close();
		conn.close();
		
		return list;	
	}
}

2.3 持久层测试用例开发

package cn.geo.doubanbook.dao;

import java.sql.SQLException;
import java.util.List;

import org.junit.Test;

import cn.geo.doubanbook.dao.PriceDAO;
import cn.geo.doubanbook.entity.Price;

public class PriceDAOTest {
	PriceDAO dao = new PriceDAO();
	/**
	 * 测试PriceDAO中的listPrice方法中的方法
	 * @throws SQLException
	 */
	@Test
	public void listCountry() throws SQLException{
		List<Price> list = dao.listPrice();
		list.forEach(item->System.out.println(item));
	}
}

2.4 在cn.geo.doubanbook.entity包下创建PriceVO.java类

package cn.geo.doubanbook.entity;

import java.io.Serializable;
import java.util.List;

public class PriceVO implements Serializable{

	private static final long serialVersionUID = -7989992505206565221L;
	
	private List<Float> xData;	
	private List<Integer>yData;
	
	public PriceVO() {}
	public PriceVO(List<Float> xData, List<Integer> yData) {
		super();
		this.xData = xData;
		this.yData = yData;
	}
	public List<Float> getxData() {
		return xData;
	}
	public void setxData(List<Float> xData) {
		this.xData = xData;
	}
	public List<Integer> getyData() {
		return yData;
	}
	public void setyData(List<Integer> yData) {
		this.yData = yData;
	}
	
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((xData == null) ? 0 : xData.hashCode());
		result = prime * result + ((yData == null) ? 0 : yData.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		PriceVO other = (PriceVO) obj;
		if (xData == null) {
			if (other.xData != null)
				return false;
		} else if (!xData.equals(other.xData))
			return false;
		if (yData == null) {
			if (other.yData != null)
				return false;
		} else if (!yData.equals(other.yData))
			return false;
		return true;
	}
	@Override
	public String toString() {
		return "PriceVO [xData=" + xData + ", yData=" + yData + "]";
	}
}

2.5 在cn.geo.doubanbook.service包下创建PriceService.java类

package cn.geo.doubanbook.service;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import cn.geo.doubanbook.dao.PriceDAO;
import cn.geo.doubanbook.entity.Price;
import cn.geo.doubanbook.entity.PriceVO;

public class PriceService{
	
	private PriceDAO dao = new PriceDAO();

	public PriceVO findPrice() {
		// 调用持久层方法,查询所需数据
		List<Price> list = null;
		try {
			list = dao.listPrice();
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
		// 创建xData,保存x轴数据
		List<Float> xData = new ArrayList<Float>(list.size());
		// 创建yData,保存y轴数据
		List<Integer> yData = new ArrayList<Integer>(list.size());
		// 遍历持久层查询到的数据
		for (Price pn : list) {
			xData.add(pn.getPrice());
			yData.add(pn.getNum());
		}
		// 创建PriceVO对象,封装xData和yData
		PriceVO vo = new PriceVO(xData, yData);
		return vo;
	}
}

2.6 业务层测试用例开发

package cn.geo.doubanbook.service;

import org.junit.Test;


import cn.geo.doubanbook.entity.PriceVO;
import cn.geo.doubanbook.service.PriceService;

public class PriceServiceTest {
	
	PriceService service = new PriceService();
	
	@Test
	public void findPrice() {
		PriceVO vo = service.findPrice();
		System.out.println(vo);
	}		
}

2.7 Web层开发

package cn.geo.doubanbook.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;

import cn.geo.doubanbook.entity.PriceVO;
import cn.geo.doubanbook.service.PriceService;

public class PriceServlet extends HttpServlet{
	private static final long serialVersionUID = -4869015457920074899L;
	private PriceService service = new PriceService();
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 调动业务层方法,获取PriceVO
		PriceVO vo = service.findPrice();
		// 判断PriceVO是否不为null
		if(vo != null) {
			// 将vo对象转变成JSON字符串-基于JSON插件实现
			String jsonStr = JSON.toJSONString(vo);
			// 通知浏览器,本次返回的数据是JSON格式
		    resp.setContentType("application/json;charset=utf-8");
		    // 将JSON字符串添加到response对象中
		    resp.getWriter().write(jsonStr);
		} else {
			// 返回空的json字符串
		    // 通知浏览器,本次返回的数据是JSON格式
		    resp.setContentType("application/json;charset=utf-8");
		    // 将JSON字符串添加到response对象中
		    resp.getWriter().write("{}");
		}
	}
}

2.8 在webapp/WEB-INF/web.xml文件中对Servlet进行配置

<servlet>
		<servlet-name>PriceServlet</servlet-name>
		<servlet-class>cn.geo.doubanbook.web.PriceServlet</servlet-class>	
</servlet>
<servlet-mapping>
		<servlet-name>PriceServlet</servlet-name>
		<url-pattern>/price</url-pattern>
</servlet-mapping>

2.9 前端页面开发

在webapp根目录下,创建priceNum.html文件。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图书价格总计直观图</title>
<script src="js/echarts.min.js"></script>
<script src="js/jquery-1.11.0.min.js"></script>
</head>
<body>
	<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
	<div id="price" style="width: 1350px; height: 400px;"></div>
	<script type="text/javascript">
		// 声明服务器数据的url
		var url = "http://localhost:8080/doubanbook/price";
		// 发送Ajax请求,从服务器获取数据
		$.get(url, function(result) {
			// x轴数据: 价格
			var xData = result.xData;
			// y轴数据: 数量
			var yData = result.yData;

			// 基于准备好的dom,初始化echarts实例
			var myChart = echarts.init(document.getElementById('price'));

			// 指定图表的配置项和数据
			var option = {
				// 图表标题
				title : {
					left : 'center',
					top : '3%',
					text : '图书价格总计--折线图+柱状图',
					subtext : '豆瓣top250'

				},
				// 提示框
				tooltip : {
					show : true,
					trigger : 'item'
				},
				// 图例
				legend : {
					data : [ '价格数量' ],
					top : '10%'
				},
				//工具栏组件
				toolbox : {
					show : true,
					top : '10%',
					feature : { //需要的功能
						saveAsImage : {
							show : true
						//保存为图片
						},
						dataView : {
							show : true
						//数据视图         
						},
						dataZoom : {
							show : true
						//区域缩放与区域缩放还原            
						},
						magicType : {
							type : [ 'line', 'bar' ]
						//动态类型转换       
						}
					}
				},
				// x轴
				xAxis : {
					data : xData,
					type : 'category',
					axisTick : {
						alignWithLabel : true,//竖线对准文字
						interval : 0,
					//坐标轴刻度标签的显示间隔(在类目轴中有效),默认会采用标签不重叠的方式显示标签(也就是默认会将部分文字显示不全)
					//可以设置为0强制显示所有标签,如果设置为1,表示隔一个标签显示一个标签,如果为3,表示隔3个标签显示一个标签,以此类推
					},
					axisLabel : {
						interval : 0,//显示全部信息
						textStyle : {
							color : "#a9a9a9", //更改坐标轴文字颜色
							fontSize : 8
						//更改坐标轴文字大小
						},
						rotate : 40,

					}
				},
				// y轴
				yAxis : [ {
					type : 'value'
				} ],
				grid : {
					top : '20%',//距离dom容器顶部
					right : '10%',//...右侧
					bottom : '10%',//底部
					left : '10%'//左侧
				},

				// 系列列表
				series : [ {
					name : '价格数量',
					type : 'line',
					data : yData

				}, {
					name : '价格数量',
					type : 'bar',
					data : yData,
					markPoint : {
						data : [ {
							type : 'max',
							name : '最大值'
						}, {
							type : 'min',
							name : '最小值'
						} ]
					},
					markLine : {
						data : [ {
							type : 'average',
							name : '平均值'
						} ]
					},
					color : new echarts.graphic.LinearGradient(1, 0, 0, 1, [ {
						offset : 0,
						color : '#FF0000'
					}, {
						offset : 0.5,
						color : '#3A8EE6'
					}, {
						offset : 0.8,
						color : '#ddd'
					} ])
				} ]
			};
			// 使用刚指定的配置项和数据显示图表
			myChart.setOption(option);
		});
	</script>
</body>
</html>

3 各评分书籍数量

在这里插入图片描述

3.1 在cn.geo.doubanbook.entity包下创建Score.java类

package cn.geo.doubanbook.entity;

import java.io.Serializable;

/**
 * 各评分区间的书籍数量及名称
 * @author SGG
 *
 */
public class Score implements Serializable{

	private static final long serialVersionUID = 5098801739816776287L;
	
	private Float score; 
	private Integer num;
	
	public Score() { }
	/**
	 * @param score
	 * @param title
	 * @param num
	 */
	public Score(Float score, Integer num) {
		super();
		this.score = score;
		this.num = num;
	}
	@Override
	public String toString() {
		return "Score [score=" + score +  ", num=" + num + "]";
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((num == null) ? 0 : num.hashCode());
		result = prime * result + ((score == null) ? 0 : score.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Score other = (Score) obj;
		if (num == null) {
			if (other.num != null)
				return false;
		} else if (!num.equals(other.num))
			return false;
		if (score == null) {
			if (other.score != null)
				return false;
		} else if (!score.equals(other.score))
			return false;
		return true;
	}
	public Float getScore() {
		return score;
	}
	public void setScore(Float score) {
		this.score = score;
	}
	public Integer getNum() {
		return num;
	}
	public void setNum(Integer num) {
		this.num = num;
	}
}

3.2 在cn.geo.doubanbook.dao包下创建ScoreDAO.java类

package cn.geo.doubanbook.dao;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import cn.geo.doubanbook.entity.Score;
import cn.geo.doubanbook.util.DBUtils;

/**
 * 各评分区间的书籍数量及名称的持久层类
 * @author SGG
 *
 */
public class ScoreDAO {

	/**
	 * 查询各评分区间的书籍数量及名称
	 * @return
	 * @throws SQLException
	 */
	public List<Score> listScore() throws SQLException {
		List<Score> list = new ArrayList<Score>(248);
		
		// 从数据库连接池获取连接
		Connection conn = DBUtils.getConn();
		// 声明SQL的执行器
		Statement st = conn.createStatement();
		// 执行SQL语句
		String sql = "select * from book_score_num";
		ResultSet rs = st.executeQuery(sql);
		// 对结果集进行操作
		while(rs.next()) {
			// 获取该行数据中的指定字段
			float score = rs.getFloat("score");
			int num = rs.getInt("num");
			// 创建Author对象,封装一行数据
			Score stn = new Score(score, num);
			// 将Author对象 保存到集合中
			list.add(stn);
		}
		// 关闭连接释放资源
		st.close();
		conn.close();
		
		return list;	
	}
}

3.3 持久层测试用例开发

package cn.geo.doubanbook.dao;

import java.sql.SQLException;
import java.util.List;

import org.junit.Test;

import cn.geo.doubanbook.dao.ScoreDAO;
import cn.geo.doubanbook.entity.Score;

public class ScoreDAOTest {

	ScoreDAO dao = new ScoreDAO();
	/**
	 * 测试PublisherDAO中的listPublisher方法中的方法
	 * @throws SQLException
	 */
	@Test
	public void listScore() throws SQLException{
		List<Score> list = dao.listScore();
		list.forEach(item->System.out.println(item));
	}
}

3.4 在cn.geo.doubanbook.entity包下创建ScoreVO.java类

package cn.geo.doubanbook.entity;

import java.io.Serializable;
import java.util.List;

public class ScoreVO implements Serializable {

	private static final long serialVersionUID = -5359939797117324176L;
	
	private List<Float> xData;	
	private List<Integer> yData;

	public ScoreVO() {}
	/**
	 * @param xData
	 * @param yData
	 */
	public ScoreVO(List<Float> xData, List<Integer> yData) {
		super();
		this.xData = xData;
		this.yData = yData;
	}
	@Override
	public String toString() {
		return "ScoreVO [xData=" + xData + ", yData=" + yData + "]";
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((xData == null) ? 0 : xData.hashCode());
		result = prime * result + ((yData == null) ? 0 : yData.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ScoreVO other = (ScoreVO) obj;
		if (xData == null) {
			if (other.xData != null)
				return false;
		} else if (!xData.equals(other.xData))
			return false;
		if (yData == null) {
			if (other.yData != null)
				return false;
		} else if (!yData.equals(other.yData))
			return false;
		return true;
	}
	public List<Float> getxData() {
		return xData;
	}
	public void setxData(List<Float> xData) {
		this.xData = xData;
	}
	public List<Integer> getyData() {
		return yData;
	}
	public void setyData(List<Integer> yData) {
		this.yData = yData;
	}
}

3.5 在cn.geo.doubanbook.service包下创建ScoreService.java类

在这里插入代码片package cn.geo.doubanbook.service;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import cn.geo.doubanbook.dao.ScoreDAO;
import cn.geo.doubanbook.entity.Publisher;
import cn.geo.doubanbook.entity.PublisherVO;
import cn.geo.doubanbook.entity.Score;
import cn.geo.doubanbook.entity.ScoreVO;

public class ScoreService {

	private ScoreDAO dao = new ScoreDAO();
	public ScoreVO findScore() {
		// 调用持久层方法,查询所需数据
		List<Score> list = null;
		try {
			list = dao.listScore();
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
		// 创建xData,保存x轴数据
		List<Float> xData = new ArrayList<Float>(list.size());
		// 创建yData,保存y轴数据
		List<Integer> yData = new ArrayList<Integer>(list.size());
		// 遍历持久层查询到的数据
		for(Score pn: list) {
			xData.add(pn.getScore());
			yData.add(pn.getNum());
		}
		// 创建ScoreVO对象,封装xData和yData
		ScoreVO vo = new ScoreVO(xData, yData);
		return vo;
	}
}

3.6 业务层测试用例开发

package cn.geo.doubanbook.service;

import org.junit.Test;

import cn.geo.doubanbook.entity.ScoreVO;

public class ScoreServiceTest {

	ScoreService service = new ScoreService();
	
	@Test
	public void findScore() {
		ScoreVO vo = service.findScore();
		System.out.println(vo);
	}
}

3.7 Web层开发

package cn.geo.doubanbook.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;

import cn.geo.doubanbook.entity.ScoreVO;
import cn.geo.doubanbook.service.ScoreService;

public class ScoreServlet extends HttpServlet {

	private static final long serialVersionUID = -5676546964955638137L;

	private ScoreService service = new ScoreService();

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 调动业务层方法,获取ScoreVO
		ScoreVO vo = service.findScore();
		// 判断ScoreVO是否不为null
		if (vo != null) {
			// 将vo对象转变成JSON字符串-基于JSON插件实现
			String jsonStr = JSON.toJSONString(vo);
			// 通知浏览器,本次返回的数据是JSON格式
			resp.setContentType("application/json;charset=utf-8");
			// 将JSON字符串添加到response对象中
			resp.getWriter().write(jsonStr);
		} else {
			// 返回空的json字符串
			// 通知浏览器,本次返回的数据是JSON格式
			resp.setContentType("application/json;charset=utf-8");
			// 将JSON字符串添加到response对象中
			resp.getWriter().write("{}");
		}
	}
}

3.8 在webapp/WEB-INF/web.xml文件中对Servlet进行配置

<servlet>
		<servlet-name>ScoreServlet</servlet-name>
		<servlet-class>cn.geo.doubanbook.web.ScoreServlet</servlet-class>	
</servlet>
<servlet-mapping>
		<servlet-name>ScoreServlet</servlet-name>
		<url-pattern>/score</url-pattern>
</servlet-mapping>

3.9 前端页面开发

在webapp根目录下,创建scoreNum.html文件。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>各评分的书籍数量</title>
<script src="js/echarts.min.js"></script>
<script src="js/jquery-1.11.0.min.js"></script>
</head>
<body>
	<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
    <div id="score" style="width: 1350px;height:400px;"></div>
    <script type="text/javascript">
    
 		// 声明服务器数据的url
    	var url = "http://localhost:8080/doubanbook/score";
    	// 发送Ajax请求,从服务器获取数据
		$.get(url, function(result) {
			// x轴数据: 评分
			var xData = result.xData;
			// y轴数据: 数量
			var yData = result.yData;
		
			// 基于准备好的dom,初始化echarts实例
	        var myChart = echarts.init(document.getElementById('score'));
			
	     	// 指定图表的配置项和数据
	        var option = {
	        	// 图表标题
	            title: {
	                text: '各评分的书籍数量'
	            },
	            // 提示框
	            tooltip: {
	                show: true,
	            	// trigger: 'item'
	            	trigger: 'axis',
            		axisPointer: {
                		type: 'cross',
                		label: {
                    		backgroundColor: '#6a7985'
                		}
            		}
	            },
	            // 图例
	            legend: {
	                data: ['出版量']
	            },
	          	//工具栏组件
	            toolbox:{   
	                show:true,
	                feature:{  //需要的功能
	                    saveAsImage:{
	                        show: true	//保存为图片
	                    }, 
	                    dataView:{
	                        show: true	//数据视图         
	                    },
	                    dataZoom:{
	                        show: true	//区域缩放与区域缩放还原            
	                    },
	                    magicType:{
	                        type: ['line', 'bar']	//动态类型转换       
	                    }
	                }
	            },
	            // x轴
	            xAxis: {
	            	data: xData,
	            	type: 'category',
	            	    axisTick:{
	            	        alignWithLabel: true,//竖线对准文字
	            	        interval: 0,   
	            	        //坐标轴刻度标签的显示间隔(在类目轴中有效),默认会采用标签不重叠的方式显示标签(也就是默认会将部分文字显示不全)
	            		    //可以设置为0强制显示所有标签,如果设置为1,表示隔一个标签显示一个标签,如果为3,表示隔3个标签显示一个标签,以此类推
	            	    },
	            	    axisLabel:{ 
	            	        interval: 0	//显示全部信息
	            	} 
	            },
	            // y轴
	            yAxis:[{
   					type:'value'
  				}],
	            // 系列列表
	            series: [{
	                name: '出版量',
	                type: 'bar',
	                data: yData,
	                // 最大值、最小值标注
					markPoint : {
						data : [ {
							type : 'max',
							name : '最大值'
						}, {
							type : 'min',
							name : '最小值'
						} ]
					},
					// 平均值标注
					markLine : {
						data : [ {
							type : 'average',
							name : '平均值',
							color : '#FE8463'
						} ]
					},
	                color: new echarts.graphic.LinearGradient(1, 0, 0, 1, [{
	                	offset: 0,
	                	color: '#FE8463'
	            	}, {
	            		offset: 0.5,
	                	color: '#FE8463'
	            	}, {
	            		offset: 0.8,
	                	color: '#278FB0'
	            	}])            
	            }]
	        };
	     	// 使用刚指定的配置项和数据显示图表
	        myChart.setOption(option);
		});
    </script>
</body>
</html>
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 豆瓣电影是众所周知的一个知名电影评分网站,其中的TOP250电影榜单更是备受关注。爬取这个榜单的数据可以帮助我们更好地了解电影市场和评价,数据可视化方面可以更好地呈现这些数据。 首先,我们可以使用Python程序编写爬虫,抓取豆瓣电影TOP250数据。我们可以通过分析网页源代码,选取需要的信息,例如电影名称、上映时间、豆瓣评分、评分人数、电影类型、导演、演员等信息。然后,将所有信息保存在CSV文件中。我们可以使用BeautifulSoup模块或Scrapy框架来实现爬虫程序的编写。 接下来,我们可以使用Python数据可视化工具来对这些数据进行可视化处理。例如,我们可以使用matplotlib或Seaborn绘制电影评分的统计图表和线型图,了解每部电影评分的分布情况、评分人数的多寡、豆瓣评分的走向等。另外,我们也可以绘制散点图或热图,从电影类型、上映时间等角度分析不同类型电影的评分情况。我们还可以利用词云图工具呈现电影的标签云图,更直观地展示豆瓣用户对电影的评价。 总的来说,我们可以使用Python爬虫数据可视化工具来爬取豆瓣电影TOP250榜单的数据,并且将数据以图表、统计、云图等形式进行可视化分析,从而更好地了解电影市场和评价。 ### 回答2: 豆瓣电影Top250是电影爱好者们都很熟悉的一个电影排行榜。为了更好地了解这个排行榜的情况,我们可以利用Python爬取豆瓣电影Top250上的电影信息,并将数据制作成可视化图表,以更直观地呈现数据。 首先,我们需要使用Python爬虫技术获取豆瓣电影Top250中每部电影的信息。一般来说,爬取网页数据需要用到一些第三方爬虫库,比如Requests和BeautifulSoup。使用Requests库可以向豆瓣服务器发送请求,获取Top250的网页HTML文件。接着,我们可以使用BeautifulSoup库解析HTML文件,从中获取每一部电影的名称、评分、演员、导演、简介等信息。爬取完毕后,将获取到的数据存储在MySQL或者MongoDB数据库中,方便后续对数据的处理和分析。 接下来,我们需要将获取到的数据进行数据可视化。我们可以使用Python中的Matplotlib或者Seaborn等数据可视化库来制作可视化图表。比如,我们可以生成柱状图、饼图、折线图等多种图表类型,展现Top250中电影各类别的数量分布、电影评分的分布情况、导演、演员等数据的贡献度等信息。 总之,通过Python爬取豆瓣电影Top250数据,并利用数据可视化技术制作图表,我们可以更好地了解电影市场的情况,从中找到一些有用的数据洞察点,对后续的电影市场分析等工作提供有力支持。 ### 回答3: 随着互联网的普及和数据挖掘的发展,数据可视化已经成为当今最流行的技术之一。而Python语言的出现,极大地促进了数据可视化技术的发展,并且能够使数据可视化更加高效、便捷。 Python爬取豆瓣电影Top250数据可以使用爬虫框架Scrapy,通过对网页的解析和内容抓取,将所需数据存入数据集中。数据集中存储了每个电影的名称、导演、主演、类型、上映时间、评价人数、评分等信息,这些数据可以通过Python数据可视化工具如Matplotlib、Pandas等进行可视化处理。 通过数据可视化可以得到丰富的数据分析和呈现,如: 1.不同类型电影的数量 通过Python可视化工具可以得到不同类型电影的数量,并且可以使用饼图、柱状图等图表进行图像展示,帮助人们更好地了解豆瓣Top250电影中各类型的分布情况。 2.电影排名及评价情况 通过Python爬虫框架获取的豆瓣Top250电影可以进行排名展示及评价等数据的分析。可视化工具可以帮助我们通过散点图、折线图等形式直观地了解电影排名及评价情况。 3.电影时长对评分的影响 通过Python可视化工具可视化处理电影时长对评分的影响。可以得出电影时长对于电影评分存在明显影响的结论,以饼图的形式将主观评价高的电影与电影时长进行对比。 Python爬取豆瓣电影Top250,通过数据可视化工具可以使我们直观地了解到豆瓣Top250电影的分类情况、排名和评价等数据信息,同时,也可以了解到电影时长等因素对电影评价的影响,这对我们对电影的分析与推荐可以起到积极的作用,有助于我们更好地了解电影行业的情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值