1. 程式人生 > >java物件序列化並存儲到檔案和資料庫

java物件序列化並存儲到檔案和資料庫

Java中要實現將物件儲存起來持久化,需要讓物件實現Serializable介面,這樣就能將java物件用二進位制流儲存並恢復。下面我將以儲存到檔案和儲存到mysql來進行解析。先給出序列化類的定義:

package model;

import java.io.Serializable;
import java.util.Date;
/*
 * 實現可序列化介面
 */
public class Person implements Serializable{
	private String name;                                 //名字
	private int year;                                    //年齡
	private String city;                                 //城市
	private Date birth;                                  //生日
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
		this.year=year;
		this.city=city;
	}
	public int getYear() {
		return year;
	}
	public void setYear(int year) {
		this.year = year;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	
	
	public Date getBirth() {
		return birth;
	}
	public void setBirth(Date birth) {
		this.birth = birth;
	}
	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#toString()
	 * 重寫toString,不然序列化之後顯示的是記憶體地址
	 */
	public String toString(){
		return this.name+" "+this.year+" "+this.city+" "+this.birth.toString();
	}
}


1.儲存物件到檔案並恢復
要儲存到檔案首先必須得獲得檔案輸入流,然後將檔案輸入流作為引數,構造物件輸入流,然後就能直接將物件輸入到檔案中。而要將物件恢復,則需要先獲得檔案輸出流,然後將檔案輸出流作為引數,構造物件輸出流,就能夠得到物件,然後再強制性轉換為原始物件即可,實現程式碼如下:

package saveobject;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import model.Person;

public class FileHelper {
	private String fileName;
	
	public FileHelper(){
		
	}
	
	public FileHelper(String fileName){
		this.fileName=fileName;
	}
	
	/*
	 * 將person物件儲存到檔案中
	 * params:
	 * 	p:person類物件
	 */
	public void saveObjToFile(Person p){
		try {
			//寫物件流的物件
			ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(fileName));
			
			oos.writeObject(p);                 //將Person物件p寫入到oos中
			
			oos.close();                        //關閉檔案流
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}
	
	/*
	 * 從檔案中讀出物件,並且返回Person物件
	 */
	public Person getObjFromFile(){
		try {
			ObjectInputStream ois=new ObjectInputStream(new FileInputStream(fileName));
			
			Person person=(Person)ois.readObject();              //讀出物件
			
			return person;                                       //返回物件
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}
}

2.儲存物件到資料庫並恢復

物件序列化之後得到的二進位制流,所以要想儲存序列化之後的物件,則必須用blob欄位來儲存。mysql中blob欄位是用來儲存二進位制資料的。可以直接用PreparedStatement.setObject()方法來儲存物件到資料庫中。

而要將物件恢復,則首先需要讀出二進位制資料,讀出的方法是用ResultSet.getBlob()方法,然後用Blob對的getBinaryStream()方法來獲得二進位制流物件,然後將該二進位制流物件作為引數構造帶緩衝區的流物件BufferedStream,然後用byte[]陣列從BufferedInputStream流中讀取二進位制資料,然後用該byte陣列來構造

ByteArrayInputStream,然後用ByteArrayInputStream來構造ObjectInputStream,最後直接用ObjectInputStream物件的readObject方法讀出物件資料,並強制性轉化為原始的物件資料。

實現程式碼如下所示:

package saveobject;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import model.Person;

public class DBHelper {
	private static Connection conn;                                      //連線
	private PreparedStatement pres;                                      //PreparedStatement物件
	
	static{
		try {
			Class.forName("com.mysql.jdbc.Driver");              //載入驅動
			System.out.println("資料庫載入成功!!!");
			String url="jdbc:mysql://localhost:3306/testdb";
			String user="root";
			String password="20130436";
			
			conn=DriverManager.getConnection(url,user,password); //建立連線
			System.out.println("資料庫連線成功!!!");
		} catch (ClassNotFoundException | SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/*
	 * 向資料庫中的表testobj中插入多個Person物件
	 * params:
	 * 	persons:Person物件list
	 */
	public void savePerson(List<Person> persons){
		String sql="insert into objtest(obj) values(?)";
		
		try {
			pres=conn.prepareStatement(sql);
			for(int i=0;i<persons.size();i++){
				pres.setObject(1, persons.get(i));
				 
				pres.addBatch();                                   //實現批量插入
			}
			
			pres.executeBatch();                                      //批量插入到資料庫中
			
			if(pres!=null)
				pres.close();
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/*
	 * 從資料庫中讀出存入的物件
	 * return:
	 * 	list:Person物件列表
	 */
	public List<Person> getPerson(){
		List<Person> list=new ArrayList<Person>();
		String sql="select obj from objtest";
		
		try {
			pres=conn.prepareStatement(sql);
			
			ResultSet res=pres.executeQuery();
			while(res.next()){
				Blob inBlob=res.getBlob(1);                             //獲取blob物件
				
				InputStream is=inBlob.getBinaryStream();                //獲取二進位制流物件
				BufferedInputStream bis=new BufferedInputStream(is);    //帶緩衝區的流物件
				
				byte[] buff=new byte[(int) inBlob.length()];
				while(-1!=(bis.read(buff, 0, buff.length))){            //一次性全部讀到buff中
					ObjectInputStream in=new ObjectInputStream(new ByteArrayInputStream(buff));
					Person p=(Person)in.readObject();                   //讀出物件
					
					list.add(p);
				}
				
			}
		} catch (SQLException | IOException | ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return list;
	}
}

測試用的main方法:
package controller;

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

import model.Person;
import saveobject.DBHelper;
import saveobject.FileHelper;

public class MainApp {
	public static void main(String[] args){
		FileHelper fh=new FileHelper("E:\\obj.txt");
		
		Person p=new Person();
		p.setName("張斌");
		p.setYear(24);
		p.setCity("威海");
		p.setBirth(new Date(95,2,16));
		fh.saveObjToFile(p);                               //存入person物件
		
		Person person=fh.getObjFromFile();                 //取出person物件
		System.out.println(person.toString());
		
		Person p1=new Person();
		p1.setName("張斌");
		p1.setYear(24);;
		p1.setCity("江西");
		p1.setBirth(new Date(94,1,2));
		
		
		Person p2=new Person();
		p2.setName("福國");
		p2.setYear(30);
		p2.setCity("吉林");
		p2.setBirth(new Date(95,4,23));
		
		Person p3=new Person();
		p3.setName("羿赫");
		p3.setYear(20);
		p3.setCity("海南");
		p3.setBirth(new Date(93,9,29));
		
		DBHelper db=new DBHelper();
		List<Person> slist=new ArrayList<Person>();
		slist.add(p1);
		slist.add(p2);
		slist.add(p3);
		
		//db.savePerson(slist);
		
		List<Person> glist=db.getPerson();
		
		for(int i=0;i<glist.size();i++){
			System.out.println(glist.get(i).toString());
		}
	}
}
程式結果截圖:


資料庫截圖: