长期存储数据,即把数据(如内存中的)保存到可永久保存的存储设备中(如硬盘、U盘),也就是人们常说的持久化。
创新互联公司坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站设计、成都做网站、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的岭东网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!
常用持久化的方案有数据库、XML文件和文件存储。
数据库是按照数据结构来存储和管理数据的仓库,后文不再做详细介绍。
XML是可扩展标记语言,最早是为了简化Internet的文档数据传输,它提供统一的语法格式来描述数据的结构,通常XML文件用于一些少量且无特殊类型要求的文本存储。示例代码使用W3C标准的接口生成XML:
import java.io.FileOutputStream;
import java.io.PrintWriter;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class $ {
public static void main(String[] args) throws Exception {
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
//创建根节点为students的XML文件
Element students = document.createElement("students");
document.appendChild(students);
//在根节点下创建一个子节点学生
Element student = document.createElement("student");
students.appendChild(student);
//创建节点学生姓名,值为张三
Element name = document.createElement("name");
name.appendChild(document.createTextNode("张三"));
student.appendChild(name);
//创建节点学生年龄,值为18
Element age = document.createElement("age");
age.appendChild(document.createTextNode("18"));
student.appendChild(age);
//创建节点学生编号,值为150101
Element number = document.createElement("number");
number.appendChild(document.createTextNode("150101"));
student.appendChild(number);
//在根节点下创建第二个子节点学生
student = document.createElement("student");
students.appendChild(student);
//创建节点学生姓名,值为李四
name = document.createElement("name");
name.appendChild(document.createTextNode("李四"));
student.appendChild(name);
//创建节点学生年龄,值为20
age = document.createElement("age");
age.appendChild(document.createTextNode("20"));
student.appendChild(age);
//创建节点学生编号,值为150102
number = document.createElement("number");
number.appendChild(document.createTextNode("150102"));
student.appendChild(number);
//将XML文件保存到硬盘
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
PrintWriter writer = new PrintWriter(new FileOutputStream("/home/test.xml"));
transformer.transform(new DOMSource(document), new StreamResult(writer));
}
}
无论是数据库还是XML文件,它们都使用了能让数据快速方便进出的标准规范。其它文件如propeties、json,都可以使用类似XML的方式来打包数据,然后通过Java丰富的io流接口保存到磁盘中。
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class Book {
private int no;
private String name;
private double value;
public Book() {
}
public Book(int no, String name, double value) {
this.no = no;
this.name = name;
this.value = value;
}
public double getValue() {
return value;
}
public void setValue(double value) {
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
}
class BookList {
private ListBook bookList;
public BookList() {
bookList = readXML();
}
public long getCount() {
return bookList.size();
}
public ListBook getBookList() {
return bookList;
}
public void setBookList(ListBook bookList) {
this.bookList = bookList;
}
public void add(Book book) {
bookList.add(book);
}
public boolean delete(String name) {
Book book = query(name);
return bookList.remove(book);
}
public void update(Book bookBefore, Book bookAfter) {
bookList.remove(bookBefore);
add(bookAfter);
}
public Book query(String name) {
Book temp = null;
for (Book book : bookList) {
if (book.getName().equals(name)) {
temp = book;
}
}
return temp;
}
public synchronized void writeXmlDocument(Book book) {
try {
File file = new File("D:\\book.xml");
Document document = null;
Element root = null;
if (!file.exists()) {
// 新建student.xml文件并新增内容
document = DocumentHelper.createDocument();
root = document.addElement("Books");//添加根节点
} else {
SAXReader saxReader = new SAXReader();
document = saxReader.read(file);
root = document.getRootElement();//获得根节点
}
Element secondRoot = root.addElement("Book");//二级节点
//为二级节点添加属性,属性值为对应属性的值
secondRoot.addElement("no").setText(book.getNo() + "");
secondRoot.addElement("name").setText(book.getName() + "");
secondRoot.addElement("value").setText(book.getValue() + "");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("GBK");
XMLWriter writer = new XMLWriter(new FileOutputStream("D:\\book.xml"), format);
writer.write(document);
writer.close();
document.clearContent();
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized ListBook readXML() {
ListBook list = new ArrayListBook();//创建list集合
File file = null;
try {
file = new File("D:\\book.xml");//读取文件
if (file.exists()) {
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(file);
List nodeList = document.selectNodes("Books/Book");
for (int i = 0; i nodeList.size(); i++) {
Element el = (Element) nodeList.get(i);
Book book = new Book();
book.setNo(Integer.parseInt(el.elementText("no")));
book.setName(el.elementText("name"));
book.setValue(Double.parseDouble(el.elementText("value")));
list.add(book);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
}
class Test {
public static void main(String args[]) {
BookList bl = new BookList();
boolean bBreak = true;
while (bBreak) {
System.out.println("请输入操作代码:");
System.out.println("1:添加 2:删除 3:修改 4:查询 5:书籍统计 6:退出");
Scanner sc = new Scanner(System.in);
int code = sc.nextInt();
if (code == 1) {
System.out.println("请输入编号");
int no = sc.nextInt();
System.out.println("请输入书名");
String name = sc.next();
System.out.println("请输入售价");
double value = sc.nextDouble();
Book book = new Book(no, name, value);
bl.add(book);
bl.writeXmlDocument(book);
} else if (code == 2) {
System.out.println("请输入要删除的书籍名");
String name = sc.next();
if (bl.delete(name)) {
System.out.println("删除成功");
} else {
System.out.println("书籍不存在");
}
} else if (code == 3) {
System.out.println("请输入要修改的书籍名");
String name = sc.next();
Book bookBefore = bl.query(name);
System.out.println("请输入新的编号");
int newNo = sc.nextInt();
System.out.println("请输入新的书名");
String newName = sc.next();
System.out.println("请输入新的售价");
double value = sc.nextDouble();
Book bookAfter = new Book(newNo, newName, value);
bl.update(bookBefore, bookAfter);
} else if (code == 4) {
System.out.println("请输入要查询的书籍名");
String name = sc.next();
Book book = bl.query(name);
System.out.println("编号:" + book.getNo() + " 书名:" + book.getName() + " 售价:" + book.getValue());
} else if (code == 5) {
ListBook list = bl.getBookList();
System.out.println("总书籍数:" + bl.getCount());
for (Book book : list) {
System.out.println("编号:" + book.getNo() + " 书名:" + book.getName() + " 售价:" + book.getValue());
}
} else if (code == 6) {
bBreak = false;
}
}
}
}
jar 包 dom4j.jar jaxen-1.1.4.jar
看注释:
import java.awt.GridLayout;
import javax.swing.*;
public class LoadForm extends JFrame{
private JPanel jpanel1;
private JTextField jtext1;
private JPasswordField password;
private JLabel jlable1;
private JLabel jlable2;
private JButton button1;
private JButton button2;
public LoadForm()
{
super("商品管理系统");
this.setLayout(null);
GridLayout layout=new GridLayout(3,3,10,10);//这句保留
jpanel1=new JPanel();
//jpanel1.setLayout(null);//jpanel1的布局不能为空
jlable1=new JLabel("用户名");
jlable2=new JLabel("密 码");
jtext1=new JTextField();
password=new JPasswordField();
button1=new JButton("确定");
button2=new JButton("取消");
jpanel1.add(jlable1);
jpanel1.add(jtext1);
jpanel1.add(jlable2);
jpanel1.add(password);
jpanel1.add(button1);
jpanel1.add(button2);
//this.add(jpanel1);//写法错误
this.setContentPane(jpanel1);//设置jpanel1为Frame的内容面版
this.setBounds(200,200,100,100);
//this.setSize(200,200);
this.setVisible(true);
}
//main方法测试
public static void main(String args[]){
new LoadForm();
}
}
java程序中数据储存方法如下:
一种是栈内存,另一种是堆内存
(1)在函数中定义的基本类型变量(即基本类型的局部变量)和对象的引用变量(即对象的变量名)都在函数的栈内存中分配;
(2)堆内存用来存放由new创建的对象和数组以及对象的实例变量(即全局变量)。
在函数(代码块)中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的内存空间;
在堆中分配的内存由java虚拟机的自动垃圾回收器来管理
堆和栈的优缺点
堆的优势是可以动态分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的。
缺点就是要在运行时动态分配内存,存取速度较慢;
栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。
程序运行时,我们最好对数据保存到什么地方做到心中有数。特别要注意的是内在的分配,有六个地方都可以保存数据:
1、 寄存器。这是最快的保存区域,因为它位于和其他所有保存方式不同的地方:处理器内部。然而,寄存器的数量十分有限,所以寄存器是根据需要由编译器分配。我们对此没有直接的控制权,也不可能在自己的程序里找到寄存器存在的任何踪迹。
2、 堆栈。驻留于常规RAM(随机访问存储器)区域。但可通过它的“堆栈指针”获得处理的直接支持。堆栈指针若向下移,会创建新的内存;若向上移,则会释放那些内存。这是一种特别快、特别有效的数据保存方式,仅次于寄存器。创建程序时,java编译器必须准确地知道堆栈内保存的所有数据的“长度”以及“存在时间”。这是由于它必须生成相应的代码,以便向上和向下移动指针。这一限制无疑影响了程序的灵活性,所以尽管有些java数据要保存在堆栈里——特别是对象句柄,但java对象并不放到其中。
3、 堆。一种常规用途的内存池(也在RAM区域),其中保存了java对象。和堆栈不同:“内存堆”或“堆”最吸引人的地方在于编译器不必知道要从堆里分配多少存储空间,也不必知道存储的数据要在堆里停留多长的时间。因此,用堆保存数据时会得到更大的灵活性。要求创建一个对象时,只需用new命令编制相碰的代码即可。执行这些代码时,会在堆里自动进行数据的保存。当然,为达到这种灵活性,必然会付出一定的代价:在堆里分配存储空间时会花掉更长的时间
4、 静态存储。这儿的“静态”是指“位于固定位置”。程序运行期间,静态存储的数据将随时等候调用。可用static关键字指出一个对象的特定元素是静态的。但java对象本身永远都不会置入静态存储空间。
5、 常数存储。常数值通常直接置于程序代码内部。这样做是安全的。因为它们永远都不会改变,有的常数需要严格地保护,所以可考虑将它们置入只读存储器(ROM)。
6、 非RAM存储。若数据完全独立于一个程序之外,则程序不运行时仍可存在,并在程序的控制范围之外。其中两个最主要的例子便是“流式对象”和“固定对象”。对于流式对象,对象会变成字节流,通常会发给另一台机器,而对于固定对象,对象保存在磁盘中。即使程序中止运行,它们仍可保持自己的状态不变。对于这些类型的数据存储,一个特别有用的技艺就是它们能存在于其他媒体中,一旦需要,甚至能将它们恢复成普通的、基于RAM的对象。