java物件序列化並存儲到檔案和資料庫
阿新 • • 發佈:2019-01-02
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陣列來構造
實現程式碼如下所示:
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());
}
}
}
程式結果截圖:資料庫截圖: