前台系统二:需求分析与数据建模:创建数据工具类、分页工具类;Dao数据对象访问类;(分页模块的Model的Dao部分)

目录

一:概述:

二:首先需要开发的是,两个工具类:XmlDataSource类和PageModel类:

1.XmlDataSource类:将整个xml文件读取到内存中

2.JavaBean:Painting类:承载数据

3.PageModel类:用于分页的类:

三:在底层工具类做好了以后:编写数据访问对象类:PaintingDao类:

由此,Model中的,Dao部分就开发完成了;


一:概述:

本部分主要是MVC架构的Model(模型)层中的Dao部分:然后,本篇博客的具体内容是分页功能的Dao部分;

主要包括:

     (1)XmlDataSource类工具类,将整个xml文件读取到内存中;

     (2)Painting类entity实体类,承载油画数据的javaBean;

     (3)PageModel类工具类,数据分页类;这个PageModel其实也需要是一个标准的javaBea,这样才能被前台的注入jsp的el表达式等识别获取;

     (4)PaintingDao类数据访问对象类,提供完整的数据访问业务;一个汇总的类;


二:首先需要开发的是,两个工具类:XmlDataSource类和PageModel类:

1.XmlDataSource类:将整个xml文件读取到内存中

因为本项目没有使用数据库,数据都存放在了XML中,所以需要Dom4j来提供对xml文件读写的支持;

Dom4j内容如果忘记了,可以参考使用Dom4j读取XML文档使用Dom4j写(追加)XML文档XPath路径表达式查询XML这几篇博客;

需要读写xml文件,为了提升效率,引入Dom4j的jar包:

这个类的目的就是,读取xml文件的内容,将xml内容读进内存中,其背后是使用JavaBean类对象存储xml中的一条一条的数据,然后使用一个List存储xml所有的数据;

在utils包下创建XmlDataSource类;

package com.imooc.mgallery.utils;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import com.imooc.mgallery.entity.Painting;

/**
 * 数据源类,将xml文件解析为Java对象
 * 
 * @author dell
 *
 */
public class XmlDataSource {
	// 为了保证在同一时间,内存中只有一份xml的Document对象,即为了保证加载的xml对象全局唯一
	// 通过static静态关键字保证数据的全局唯一性;(自然也可以通过单例模式)
	private static List<Painting> data = new ArrayList<Painting>();  // 在XmlDataSource类加载的时候,就会创建data对象,这个对象隶属于XmlDataSource类,可以保证是全局唯一;
	private static String dataFile;  // xml文件的地址;
	static {
		// 程序运行编译后,src目录下得java文件会被编译为class文件,这些class文件会被放在classes目录下,而同样处于src目录下的painting.xml文件也会放在classes目录下;
		// XmlDataSource.class.getResoure()得到classes目录的根路径,然后在classes目录的根路径下找到painting.xml,然后getPath()获得painting.xml文件的完整的物理磁盘的地址;	
		dataFile = XmlDataSource.class.getResource("/painting.xml").getPath();
		//System.out.println(dataFile);
		// 如painting.xml文件的地址是:c:\new style\painting.xml;可以发现,new和style之间有一个空格,这个空格是个特殊字符;
		// datFile得到painting.xml文件地址的时候,会进行base64转换,实际dataFile的值会是:c:\new%20style\painting.xml,即空格被转化成了%20;
		// 但是如果在后续中,利用JavaIO对painting.xml文件按照“c:\new%20style\painting.xml”读取时,会提示路径找不到,因为%20不会被JavaIO解析;需要手动的将%20转换为空格;
		// URLDecoder的作用就是:将base64转回普通的字符串;
		URLDecoder decoder = new URLDecoder();
		try {
			dataFile = decoder.decode(dataFile, "UTF-8");  // 这个需要捕获“不支持的编码格式”异常
			//System.out.println(dataFile);
			SAXReader reader = new SAXReader();
			Document document = reader.read(dataFile);  // 需要捕获“DocumentException”异常
			List<Node> nodes = document.selectNodes("/root/painting");
			for(Node node:nodes) {
				Element element = (Element)node;
				// 提取数据,如何将数据转换成Java对象?通过什么载体来保存油画的数据?所以,需要开发对应的JavaBean承载油画数据;
				String id = element.attributeValue("id");
				String pname = element.elementText("pname");
				//
				Painting painting = new Painting();
				painting.setId(Integer.parseInt(id));
				painting.setPname(pname);
				// 剩余几个采用紧凑的写法
				painting.setCategory(Integer.parseInt(element.elementText("category")));
				painting.setPrice(Integer.parseInt(element.elementText("price")));
				painting.setPreview(element.elementText("preview"));
				painting.setDescription(element.elementText("description"));
				// 将对象存储到data集合中;
				data.add(painting);  // 这样以后,当XmlDataSource这个类被加载以后,data集合中就保存了完整的油画信息;
				
			}
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 为了保证外部可以访问data集合,需要给data增加一个出口;;;
	 * 这儿添加一个方法,getRawData():即获取最原始的信息;
	 * @return
	 */
	public static List<Painting> getRawData(){
		return data;
	}
//	public static void main(String[] args) { // 这个main方法主要目的,是测试一下
//		//new XmlDataSource();   // 创建这个对象之前,需要加载XmlDataSource这个类,一旦加载这个类,那么和这个类的static块就会初始dataFile对象;
//		List<Painting> list = XmlDataSource.getRawData();
//		System.out.println(list);
//	}
}

XmlDataSource类需要注意:

(1)使用了private static List<Painting> data = new ArrayList<Painting>();来存储xml的文件内容;私有的,静态的;然后提供了一个public static List<Painting> getRawData(),公有静态方法来提供访问data的入口;设置成静态的,也可以保证内存中,只有一份xml的内容;

(2)XmlDataSource.class.getResource("/painting.xml").getPath();:这种获取类编译后的classes目录的地址,获取某个文件的地址;注意这种用法啦;

(3)使用URLDecoder将base64编码的字符串转成普通的字符串;

(4)读取xml是固定流程,没什么好说的啦;本业务内容简单,所以此处的xPath的很简单;;;

(5)用一个JavaBean类的对象来存储xml中的一条一条的数据,这种做法是约定俗成采取的策略,司空见惯,也没什么好说的;

……………………………………………………

注解: 

 

……………………………………………………


2.JavaBean:Painting类:承载数据

在entity目录下创建JavaBean:Painting类:这个类就是个普通的javaBean没什么好说的,只需要注意(1)别忘了无参构造;(2)属性的含义最好注释一下;

package com.imooc.mgallery.entity;

/**
 * 保存油画数据的JavaBean
 * @author dell
 *
 */
public class Painting {
	private Integer id; // 油画编号
	private String pname;  // 名称
	private Integer category;  // 分类 1-现实主义,2-抽象主义;
	private Integer price;  // 通常在油画中,油画的价格都是整数,所以这儿价格采用Integer而不是Float;
	private String preview;  // 油画图片地址
	private String description;  // 描述
	public Painting() {}	
	public Painting(Integer id, String pname, Integer category, Integer price, String preview, String description) {
		super();
		this.id = id;
		this.pname = pname;
		this.category = category;
		this.price = price;
		this.preview = preview;
		this.description = description;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getPname() {
		return pname;
	}
	public void setPname(String pname) {
		this.pname = pname;
	}
	public Integer getCategory() {
		return category;
	}
	public void setCategory(Integer category) {
		this.category = category;
	}
	public Integer getPrice() {
		return price;
	}
	public void setPrice(Integer price) {
		this.price = price;
	}
	public String getPreview() {
		return preview;
	}
	public void setPreview(String preview) {
		this.preview = preview;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
}

3.PageModel类:用于分页的类:

PageModel工具类的主要作用是:为分页服务的基础类;这个类的有参构造很给力!!!传入的参数是:全部数据的List,当前页码,每页的记录数;;;;就能得到:不仅仅是当前页需要显示的记录的内容,还要有有关分页的所有相关信息(比如是否有上页,是否有下页,当前页码等等);而这些信息在页面显示的时候是很关键的。

在某种程度上,PageModel类可以看成是存储分页各种信息的javaBean;其实这个PageModel就是一个标准的javaBea,这样才能被前台的注入jsp的el表达式等识别获取;(因为后面Controller部分调用Service部分后,向请求中添加的参数就是PageModel类型的对象,所以PageModel必须是一个JavaBean

在utils包下,创建PageModel类

package com.imooc.mgallery.utils;

import java.util.ArrayList;
import java.util.List;

/**
 * 分页类
 * @author dell
 *
 */
public class PageModel {
	private int page; // 页号:当前是第几页;
	private int totalPages; //总页数:一共有多少页,这个需要
	private int rows;  // 每页记录数:每页有几条数据;
	private int totalRows;  // 总记录数:原始的数据易容有多少条;totalRows/rows:就可以得到总页数了;;;
	private int pageStartRow;  // 当前页从第n行开始:当前页是从原始数据的第几行开始的;
	private int pageEndRow;   // 当前页到第n行结束:当前页的最后一条数据是原始数据的第几行;
	private boolean hasNextPage;  // 是否有下一页;
	private boolean hasPreviousPage; //是否有上一页;
	private List pageData;  // 当前页的数据
	
	public PageModel() {}
	/**
	 * @param data:原始完整的数据;
	 * @param page:要查询第几页数据;
	 * @param rows:每一页有几条;
	 */
	public PageModel(List data,int page,int rows) {
		this.page = page;
		this.rows = rows;
		totalRows = data.size();
		// 总页数,向上取整;Math.ceil():作用是向上取整;Math.ceil()返回的数据类型是double,所以下面转成了int;
		// 注:Math.floor():向下取整,返回的数据类型也是double类型;
		// Java中如8/3 = 2;而不是2.66666;;;;(rows * 1f)的作用是把除数转成浮点数,这样(totalRows/(rows * 1f))得到的就是浮点数了;
		totalPages = new Double(Math.ceil(totalRows/(rows * 1f))).intValue();
		
		pageStartRow = (page-1)*rows;   // 0
		pageEndRow = page*rows;  // 6
		
		// totalRows:20  | totalPage:4  | rows:6
		// pageEndRow = 4*6=24>20  执行subList会抛出下标越界异常;所以做个判断处理
		if(pageEndRow > totalRows) {
			pageEndRow = totalRows;
		}
		pageData = data.subList(pageStartRow, pageEndRow); // subList()截取,可以取到pageStartRow,取不到pageEndRow,即是左闭右开的;
		
		if(page > 1) {   // 如果当前页号大于1,存在上一页;
			hasPreviousPage = true;
		}else {
			hasPreviousPage = false;
		}
		if(page < totalPages) {  // 如果当前页号小于总页数,存在下一页;
			hasNextPage = true;
		}else {
			hasNextPage = false;
		}
		
	}
	public int getPage() {
		return page;
	}
	public void setPage(int page) {
		this.page = page;
	}
	public int getTotalPages() {
		return totalPages;
	}
	public void setTotalPages(int totalPages) {
		this.totalPages = totalPages;
	}
	public int getRows() {
		return rows;
	}
	public void setRows(int rows) {
		this.rows = rows;
	}
	public int getTotalRows() {
		return totalRows;
	}
	public void setTotalRows(int totalRows) {
		this.totalRows = totalRows;
	}
	public int getPageStartRow() {
		return pageStartRow;
	}
	public void setPageStartRow(int pageStartRow) {
		this.pageStartRow = pageStartRow;
	}
	public int getPageEndRow() {
		return pageEndRow;
	}
	public void setPageEndRow(int pageEndRow) {
		this.pageEndRow = pageEndRow;
	}
	public boolean isHasNextPage() {
		return hasNextPage;
	}
	public void setHasNextPage(boolean hasNextPage) {
		this.hasNextPage = hasNextPage;
	}
	public boolean isHasPreviousPage() {
		return hasPreviousPage;
	}
	public void setHasPreviousPage(boolean hasPreviousPage) {
		this.hasPreviousPage = hasPreviousPage;
	}
	public List getPageData() {
		return pageData;
	}
	public void setPageData(List pageData) {
		this.pageData = pageData;
	}
	
//	public static void main(String[] args) {
//		List sample = new ArrayList();
//		for(int i=1;i<=100;i++) {
//			sample.add(i);
//		}
//		PageModel pageModel = new PageModel(sample,6,8);
//		System.out.println("当前页数据:"+pageModel.getPageData());
//		System.out.println("总页数"+pageModel.getTotalPages());
//		System.out.println("起始行号:"+pageModel.getPageStartRow());
//		System.out.println("结束行号"+pageModel.getPageEndRow());
//		
//	}

}

PageModel类需要注意:

(1)这个类是,专门服务于分页的工具类;

(2)List.subList(index x,index y);取不到y,只能取到y-1;

(3)pageStartRow = (page-1)*rows;  和  pageEndRow = page*rows; 在计算开始行数和结束行数的时候,要注意最终的数据是需要从List中获取的,结合List的索引和subList()方法的特性,(做一个小例子)就会很容易理解;


三:在底层工具类做好了以后:编写数据访问对象类:PaintingDao类:

在XmlDataSource类和PageModel这两个工具类开发完成后,需要开发PaintingDao类需要调用XmlDataSource类以获取xml完整的原始的数据信息,然后再创建PageModel对象对数据进行分页处理;这样以后,PaintingDao类就实现了数据分页;然后PaintingDao就会将数据分页的分页对象传递给PaintingService就可以了;由此,底层的数据查询部分就完成了;

创建PaintingDao类:

package com.imooc.mgallery.dao;

import java.util.List;

import com.imooc.mgallery.entity.Painting;
import com.imooc.mgallery.utils.PageModel;
import com.imooc.mgallery.utils.XmlDataSource;

/**
 * Dao类;调用PageModel类和XmlDataSource这个两个工具类;
 * 数据访问对象类,作用是获取最原始的xml数据,并且对其进行分页;
 * @author dell
 *
 */
public class PaintingDao {

	/**
	 * 实现分页的方法
	 * @param page 查询第几页数据;
	 * @param rows 每一页显示几条
	 * @return
	 */
	public PageModel pagination(int page,int rows) {
		List<Painting> xmlDataSourceList = XmlDataSource.getRawData();  // 先获取xml完整的数据;
		PageModel pageModel = new PageModel(xmlDataSourceList,page,rows);
		return pageModel;	
	}
}

PaintingDao类需要注意:

(1)PaintingDao类先调用XmlDataSource类,获取完整的xml数据;

(2)然后调用PageModel的有参构造获取分页对象;将分页对象返回就好了;

(3)PaintingDao类向上提供完整的数据访问对象;Dao除了调用工具类以外,为了满足数据要求,可能会加一些处理数据的代码,将获取的数据进行稍微加工后,再向后传递;即还是那句话,底层工具类只是完成某些模块化的具体功能,而不参与业务逻辑的编写;Dao类调用底层工具类,获取结果后,加上一些业务逻辑代码(如果需要的话)对从工具类获取的数据进行一下加工,然后向上提供完整的数据访问对象!!!


由此,Model中的,Dao部分就开发完成了;

猜你喜欢

转载自blog.csdn.net/csucsgoat/article/details/114812333
今日推荐