java对象序列化并存储到文件和数据库

java 专栏收录该内容
14 篇文章 0 订阅

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());
		}
	}
}
程序结果截图:



数据库截图:




©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值