精华内容
下载资源
问答
  • Java对象存储到Oracle数据库

    千次阅读 2010-10-26 14:12:00
    Java对象存储到Oracle数据库

    对象持久化,也就是可以把这个对象永远的保存起来,这里的保存不仅是对象本身,还包括他的属性和所依赖的其他类。通常,对象可以持久化到文件或者是数据库中。我这里只介绍如何将对象存储到数据库中。恰巧Oracle数据库为我们提供了这样的方便。
       在Oracle中,有一种blog的字段类型,它是用来存储大量的二进制数据的。我们就利用这个字段去存储对象信息。
       首先建立一个测试表:

       只用三个字段,其中id是属性,content是我们要存储对象的字段。
       先来看看我们要存入的对象:

        记得要实现Serializable接口,可以看到这是一个包含了string,date,和list类型的对象,为了给测试增加复杂度,我们的list是另外一个对象(city)的list,如下:

         City对象包括了城市名称和区号。下面是主要的应用了。

      代码的蓝色部分创建了要存储的对象。再看红色的对象写入部分,它首先把对象转化成二进制流的形式。对于blob字段,我们不能简单的在insert时插入,实际上,insert时,对于blob字段,只能先插入一个空的blob对象empty_blob(),然后再进行"select CONTENT from TESTBLOB where ID=1 for update"对blob字段进行更新。返回后,我们只要把对象的二进制流写入即可。
    OutputStream outStream = blob.getBinaryOutputStream();
    outStream.write(objbytes, 0, objbytes.length);
      需要注意的是,上述步骤必须设置con.setAutoCommit(false),否则oracle会抛出异常。
      接下来,绿色的代码是读取数据库中blob字段的对象,并恢复。我们要知道的是,所有对blob字段的操作都是二进制的,即插入时是二进制流,读出时也是二进制流。然后用io修饰器(ObjectInputStream)去修饰。以前学习java时,感觉它的io好繁琐啊,现在感觉还真是各有其用。下面是测试的输出结果。
    yangsq
    111
    Tue Mar 27 12:11:28 CST 2007
    北京    010
    上海    020
    天津    021
        需要说明一下,buff的size一定要足够大,否则将抛出异常。在这里,我使用的是inblob.getBufferSize()来设置buff的size,这并不是一种好的方法,因为一般inblob.getBufferSize()都是32768,很可能出现异常,所以这个size最好自己设置,或系统运行时刻设置(幸好java提供数组长度的运行时刻设置)。
    上面是我本人研究的结果,当然少不了网友们的知识奉献。下面就转自一位网友的blog。
    转:
    1.新建记录,插入BLOB数据
     1.1首先新建记录的时候,使用oracle的函数插入一个空的BLOB,假设字段A是BLOB类型的:
      insert xxxtable(A,B,C) values(empty_blob(),'xxx','yyyy')
     1.2后面再查询刚才插入的记录,然后更新BLOB,在查询前,注意设置Connection的一个属性:
      conn.setAutoCommit(false);如果缺少这一步,可能导致fetch out of sequence等异常.
     1.3 查询刚才插入的记录,后面要加“ for update ”,如下:
      select A from xxxtable where xxx=999 for update ,如果缺少for update,可能出现row containing the LOB value is not locked
    的异常
     1.4 从查询到的 BLOB字段中,获取blob并进行更新,代码如下:
      BLOB blob = (BLOB) rs.getBlob("A");
      OutputStream os = blob.getBinaryOutputStream();
      BufferedOutputStream output = new BufferedOutputStream(os);
      后面再使用output.write方法将需要写入的内容写到output中就可以了。例如我们将一个文件写入这个字段中:
      BufferedInputStream input = new BufferedInputStream(new File("c://hpWave.log").toURL().openStream());
      byte[] buff = new byte[2048];  //用做文件写入的缓冲
      int bytesRead;
      while(-1 != (bytesRead = input.read(buff, 0, buff.length))) {
       output.write(buff, 0, bytesRead);
       System.out.println(bytesRead);
      }
      上面的代码就是从input里2k地读取,然后写入到output中。
     1.5上面执行完毕后,记得关闭output,input,以及关闭查询到的ResultSet
     1.6最后执行conn.commit();将更新的内容提交,以及执行conn.setAutoCommit(true); 改回Connction的属性
    2.修改记录,方法与上面的方法类似,
     2.1首先更新BLOB以外的其他字段
     2.2 使用1.3中类似的方法获取记录
     2.3 修改的过程中,注意以下:a 需要更新的记录中,BLOB有可能为NULL,这样在执行blob.getBinaryOutputStream()获取的值可能为
    null,那么就关闭刚才select的记录,再执行一次update xxxtable set A = empty_blob() where xxx, 这样就先写入了一个空的BLOB(不是null),然后再
    使用1.3,1.4中的方法执行更新记录.b 注意别忘了先执行setAutoCommit(false),以及"for update",以及后面的conn.commit();等。
    3.读取BLOB字段中的数据.
     3.1 读取记录不需要setAutoCommit(),以及 select ....for update.
     3.2 使用普通的select 方法查询出记录
     3.3 从ResultSet中获取BLOB并读取,如下:
      BLOB b_to = (BLOB) rs.getBlob("A");
      InputStream is = b_from.getBinaryStream();
      BufferedInputStream input = new BufferedInputStream(is);
      byte[] buff = new byte[2048];
      while(-1 != (bytesRead = input.read(buff, 0, buff.length))) {
       //在这里执行写入,如写入到文件的BufferedOutputStream里
       System.out.println(bytesRead);
      }
      通过循环取出blob中的数据,写到buff里,再将buff的内容写入到需要的地方
    4.两个数据库间blob字段的传输
    类似上面1和3的方法,一边获取BufferedOutputStream,另外一边获取BufferedInputStream,然后读出写入,需要注意的是写入所用的
    Connection要执行conn.setAutoCommit(false);以及获取记录时添加“ for update ”以及最后的commit();
    总结以上方法,其根本就是先创建空的BLOB,再获取其BufferedOutputStream进行写入,或获取BufferedInputStream进行读取

    展开全文
  • Java对象存储到Oracle数据库

    千次阅读 2011-12-27 20:16:55
    我这里只介绍如何将对象存储数据库中。恰巧Oracle数据库为我们提供了这样的方便。 在Oracle中,有一种blog的字段类型,它是用来存储大量的二进制数据的。我们就利用这个字段去存储对象信息。 首先建立一个测试表...
    对象持久化,也就是可以把这个对象永远的保存起来,这里的保存不仅是对象本身,还包括他的属性和所依赖的其他类。通常,对象可以持久化到文件或者是数据库中。我这里只介绍如何将对象存储到数据库中。恰巧Oracle数据库为我们提供了这样的方便。
       在Oracle中,有一种blog的字段类型,它是用来存储大量的二进制数据的。我们就利用这个字段去存储对象信息。
       首先建立一个测试表:
    create table TESTBLOB
    (
      NAME    VARCHAR2(50) not null,
      CONTENT BLOB not null,
      ID      NUMBER(8) not null
    )alter table TESTBLOB
      add constraint IDFORTEST primary key (ID);
    
       只用三个字段,其中id是属性,content是我们要存储对象的字段。
    
       先来看看我们要存入的对象:
    
    import java.io.Serializable;
    import java.util.Date;
    import java.util.List;
    
    public class TestObject implements Serializable {
     
     private static final long serialVersionUID = 4558876142427402513L;
     /**
      * @param args
      */
     private String name;
     private String password;
     private Date date;
     private List<City> cityList;
     
     public List<City> getCityList() {
      return cityList;
     }
     public void setCityList(List<City> cityList) {
      this.cityList = cityList;
     }
     public Date getDate() {
      return date;
     }
     public void setDate(Date date) {
      this.date = date;
     }
     public String getName() {
      return name;
     }
     public void setName(String name) {
      this.name = name;
     }
     public String getPassword() {
      return password;
     }
     public void setPassword(String password) {
      this.password = password;
     }
    }
        记得要实现Serializable接口,可以看到这是一个包含了string,date,和list类型的对象,为了给测试增加复杂度,我们的list是另外一个对象(city)的list,如下:
    
    import java.io.Serializable;
    
    public class City implements Serializable{
     private static final long serialVersionUID = 4558876127402513L;
     private String name;
     private String code;
     public String getCode() {
      return code;
     }
     public void setCode(String code) {
      this.code = code;
     }
     public String getName() {
      return name;
     }
     public void setName(String name) {
      this.name = name;
     }
    }
    
         City对象包括了城市名称和区号。下面是主要的应用了。
    
    import java.io.BufferedInputStream;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.InputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.OutputStream;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    import oracle.sql.BLOB;
    
    public class Test {
    
     public static void main(String[] args) {
      //创建测试用对象
      City beijing = new City();
      beijing.setName("北京");
      beijing.setCode("010");
      
      City shanghai = new City();
      shanghai.setName("上海");
      shanghai.setCode("020");
      
      City tianjin = new City();
      tianjin.setName("天津");
      tianjin.setCode("021");
      
      List<City> cityList = new ArrayList<City>();
      cityList.add(beijing);
      cityList.add(shanghai);
      cityList.add(tianjin);
      
      TestObject obj = new TestObject();
      obj.setName("yangsq");
      obj.setPassword("111");
      obj.setDate(new Date());
      obj.setCityList(cityList);
      
      try{
       //将对象存入blob字段
       ByteArrayOutputStream byteOut=new ByteArrayOutputStream();
       ObjectOutputStream outObj=new ObjectOutputStream(byteOut);
       outObj.writeObject(obj) ;
       final byte[] objbytes=byteOut.toByteArray();
       
       Class.forName("oracle.jdbc.driver.OracleDriver");
       Connection con = DriverManager.getConnection(
         "jdbc:oracle:thin:@***.***.***.***:1521:****", "yangsq", "yangsq");
       con.setAutoCommit(false);
       Statement st = con.createStatement();
       
       st.executeUpdate("insert into TESTBLOB (ID, NAME, CONTENT) values (1, 'test1', empty_blob())");
       ResultSet rs = st.executeQuery("select CONTENT from TESTBLOB where ID=1 for update");
       
       if (rs.next()) {
        BLOB blob = (BLOB) rs.getBlob("CONTENT");
        OutputStream outStream = blob.getBinaryOutputStream();
        outStream.write(objbytes, 0, objbytes.length);
        outStream.flush();
           outStream.close();
       }
       
       byteOut.close();
       outObj.close();
       con.commit();
       
       //取出blob字段中的对象,并恢复
       rs = st.executeQuery("select CONTENT from TESTBLOB where ID=1");
       BLOB inblob = null;
       if (rs.next()) {
        inblob = (BLOB) rs.getBlob("CONTENT");
       }
       InputStream is = inblob.getBinaryStream();
       BufferedInputStream input = new BufferedInputStream(is);
       
       byte[] buff = new byte[inblob.getBufferSize()];
       while(-1 != (input.read(buff, 0, buff.length)));
       
       ObjectInputStream in =
              new ObjectInputStream(
                new ByteArrayInputStream(
                  buff));
       TestObject w3 = (TestObject)in.readObject();
       System.out.println(w3.getName());
       System.out.println(w3.getPassword());
       System.out.println(w3.getDate());
       
       List<City> list = w3.getCityList();
       for(City city : list){
        System.out.println(city.getName() + "    " + city.getCode());
       }
       
       st.close();
       con.close();
      } catch (Exception ex) {
       ex.printStackTrace();
       System.exit(1);
      }
     }
    }
      代码的蓝色部分创建了要存储的对象。再看红色的对象写入部分,它首先把对象转化成二进制流的形式。对于blob字段,我们不能简单的在insert时插入,实际上,insert时,对于blob字段,只能先插入一个空的blob对象empty_blob(),然后再进行"select CONTENT from TESTBLOB where ID=1 for update"对blob字段进行更新。返回后,我们只要把对象的二进制流写入即可。
    OutputStream outStream = blob.getBinaryOutputStream();
    outStream.write(objbytes, 0, objbytes.length);
    
      需要注意的是,上述步骤必须设置con.setAutoCommit(false),否则oracle会抛出异常。
    
      接下来,绿色的代码是读取数据库中blob字段的对象,并恢复。我们要知道的是,所有对blob字段的操作都是二进制的,即插入时是二进制流,读出时也是二进制流。然后用io修饰器(ObjectInputStream)去修饰。以前学习java时,感觉它的io好繁琐啊,现在感觉还真是各有其用。下面是测试的输出结果。
    yangsq
    111
    Tue Mar 27 12:11:28 CST 2007
    北京    010
    上海    020
    天津    021
    
        需要说明一下,buff的size一定要足够大,否则将抛出异常。在这里,我使用的是inblob.getBufferSize()来设置buff的size,这并不是一种好的方法,因为一般inblob.getBufferSize()都是32768,很可能出现异常,所以这个size最好自己设置,或系统运行时刻设置(幸好java提供数组长度的运行时刻设置)。
    
    上面是我本人研究的结果,当然少不了网友们的知识奉献。下面就转自一位网友的blog。
    
    转:
    
    1.新建记录,插入BLOB数据
     1.1首先新建记录的时候,使用oracle的函数插入一个空的BLOB,假设字段A是BLOB类型的:
      insert xxxtable(A,B,C) values(empty_blob(),'xxx','yyyy')
     1.2后面再查询刚才插入的记录,然后更新BLOB,在查询前,注意设置Connection的一个属性:
      conn.setAutoCommit(false);如果缺少这一步,可能导致fetch out of sequence等异常.
     1.3 查询刚才插入的记录,后面要加“ for update ”,如下:
      select A from xxxtable where xxx=999 for update ,如果缺少for update,可能出现row containing the LOB value is not locked
    
    的异常
     1.4 从查询到的 BLOB字段中,获取blob并进行更新,代码如下:
      BLOB blob = (BLOB) rs.getBlob("A");
      OutputStream os = blob.getBinaryOutputStream();
      BufferedOutputStream output = new BufferedOutputStream(os);
    
      后面再使用output.write方法将需要写入的内容写到output中就可以了。例如我们将一个文件写入这个字段中:
      BufferedInputStream input = new BufferedInputStream(new File("c:\hpWave.log").toURL().openStream());
      byte[] buff = new byte[2048];  //用做文件写入的缓冲
      int bytesRead;
      while(-1 != (bytesRead = input.read(buff, 0, buff.length))) {
       output.write(buff, 0, bytesRead);
       System.out.println(bytesRead);
      }
      上面的代码就是从input里2k地读取,然后写入到output中。
     1.5上面执行完毕后,记得关闭output,input,以及关闭查询到的ResultSet
     1.6最后执行conn.commit();将更新的内容提交,以及执行conn.setAutoCommit(true); 改回Connction的属性
    2.修改记录,方法与上面的方法类似,
     2.1首先更新BLOB以外的其他字段
     2.2 使用1.3中类似的方法获取记录
     2.3 修改的过程中,注意以下:a 需要更新的记录中,BLOB有可能为NULL,这样在执行blob.getBinaryOutputStream()获取的值可能为
    
    null,那么就关闭刚才select的记录,再执行一次update xxxtable set A = empty_blob() where xxx, 这样就先写入了一个空的BLOB(不是null),然后再
    
    使用1.3,1.4中的方法执行更新记录.b 注意别忘了先执行setAutoCommit(false),以及"for update",以及后面的conn.commit();等。
    3.读取BLOB字段中的数据.
     3.1 读取记录不需要setAutoCommit(),以及 select ....for update.
     3.2 使用普通的select 方法查询出记录
     3.3 从ResultSet中获取BLOB并读取,如下:
      BLOB b_to = (BLOB) rs.getBlob("A");
      InputStream is = b_from.getBinaryStream();
      BufferedInputStream input = new BufferedInputStream(is);
      byte[] buff = new byte[2048];
      while(-1 != (bytesRead = input.read(buff, 0, buff.length))) {
       //在这里执行写入,如写入到文件的BufferedOutputStream里
       System.out.println(bytesRead);
      }
      通过循环取出blob中的数据,写到buff里,再将buff的内容写入到需要的地方
    4.两个数据库间blob字段的传输
    类似上面1和3的方法,一边获取BufferedOutputStream,另外一边获取BufferedInputStream,然后读出写入,需要注意的是写入所用的
    
    Connection要执行conn.setAutoCommit(false);以及获取记录时添加“ for update ”以及最后的commit();
    
    总结以上方法,其根本就是先创建空的BLOB,再获取其BufferedOutputStream进行写入,或获取BufferedInputStream进行读取


    展开全文
  • java 数据库存储对象 上次更新时间:2020年1月 尽管贪睡按钮可能是闹钟上最常用的按钮,但即使是简单的AlarmClock类也需要更多功能。 例如,您可能想控制闹钟在小睡模式下停留多长时间。 为了添加这样的功能,您...

    java 数据库中存储对象

    上次更新时间:2020年1月

    尽管贪睡按钮可能是闹钟上最常用的按钮,但即使是简单的AlarmClock类也需要更多功能。 例如,您可能想控制闹钟在小睡模式下停留多长时间。 为了添加这样的功能,您需要了解Java如何控制数据。

    开发人员使用Java中的变量来保存数据,所有变量都具有数据类型和名称。 数据类型确定变量可以保存的值。 在本教程中,您将学习整数类型如何保存整数,浮点类型如何保存实数以及字符串类型如何保存字符串。 然后,您将开始在Java类中使用实例变量。

    变量和原始类型

    称为基本类型 ,整数和浮点类型是Java中最简单的数据类型。 以下程序说明了整数类型,它可以同时包含正整数和负整数。 该程序还说明了注释,这些注释记录了您的代码,但丝毫不影响该程序。

    /*
      * This is also a comment. The compiler ignores everything from
      * the first /* until a "star slash" which ends the comment.
      *
      * Here's the "star slash" that ends the comment.
      */
    public class IntegerTest {
      public static void main(String[] args) {
        // Here's the declaration of an int variable called anInteger,
        // which you give an initial value of 100.
        int anInteger = 100;      // Declare and initialize anInteger
        System.out.println(anInteger); // Outputs 100
        // You can also do arithmetic with primitive types, using the
        // standard arithmetic operators.
        anInteger = 100 + 100;
        System.out.println(anInteger); // Outputs 200
      }
    }

    Java还使用浮点类型,该类型可以包含实数,即包含小数位的数字。 这是一个示例程序:

    public class DoubleTest {
      public static void main(String[] args) {
        // Here's the declaration of a double variable called aDouble.
        // You also give aDouble an initial value of 5.76.
        double aDouble = 5.76;     // Declare and initialize aDouble
        System.out.println(aDouble);  // Outputs 5.76
        // You can also do arithmetic with floating point types.
        aDouble = 5.76 + 1.45;
        System.out.println(aDouble);  // Outputs 7.21
      }
    }

    尝试运行上面的程序。 请记住,必须先编译才能运行它们:

    javac *.java
    java IntegerTest
    java DoubleTest

    Java使用四种整数类型和两种浮点类型,它们都拥有不同的数字范围并占用不同的存储空间,如下表所示。

    整体类型

    类型 字节 整数
    大小(位) 8 16 32 64
    范围 -128至127 -32,768至32,767 -2,147,483,648至2,147,483,647 -2 63至2 63 -1

    浮点类型(IEEE 754格式)

    类型 单精度浮点 双精度浮点
    大小(位) 32 64
    范围 +/- 1.18x10 -38至+/- 3.4x10 38 +/- 2.23x10 -308至+/- 1.8x10 308

    字符串类型保存字符串,并以与整数和浮点类型处理数字不同的方式处理字符串。 Java语言包括一个String类来表示字符串。 您可以使用String类型声明一个字符串,并使用带引号的字符串(包含在双引号中的一系列字符)对其进行初始化,如下所示。 您还可以使用+运算符组合两个字符串。

    // Code fragment
    // Declaration of variable s of type String,
    // and initialization with quoted string "Hello."
    String s = "Hello";
    // Concatenation of string in s with quoted string " World"
    String t = s + " World";
    System.out.println(t);     // OutputsHello World
    

    可变范围

    除类型外, 范围也是变量的重要特征。 范围确定何时创建和销毁变量以及开发人员可以在程序中访问该变量的位置。 在程序中声明变量的位置决定了变量的范围。

    到目前为止,我已经讨论了局部变量 ,该局部变量包含您在方法中使用的临时数据。 您可以在方法内部声明局部变量,并且只能从这些方法内部访问它们。 这意味着你只能检索局部变量anInteger ,您在使用IntegerTestaDouble ,您在使用DoubleTest ,从他们被宣布和其他地方的主要方法。

    您可以在任何方法中声明局部变量。 下面的示例代码在AlarmClock snooze()方法中声明了一个局部变量:

    public class AlarmClock {
         public void snooze() {
             // Snooze time in millisecond = 5 secs
             long snoozeInterval = 5000;
             System.out.println("ZZZZZ for: " + snoozeInterval);
         }
    }

    您只能从snoozeInterval snooze()方法进入snoozeInterval ,这是您声明snoozeInterval, as shown here:

    public class AlarmClockTest {
      public static void main(String[] args) {
        AlarmClock aClock = new AlarmClock();
        aClock.snooze();        // This is still fine.
        // The next line of code is anERROR .
        // You can't access snoozeInterval outside the snooze method.
        snoozeInterval = 10000;
      }
    }
    

    方法参数

    方法参数的范围类似于局部变量,是另一种变量。 方法参数将参数传递给方法。 声明该方法时,可以在参数列表中指定其参数。 您在调用方法时传递参数。 方法参数的作用与局部变量类似,因为它们位于它们所链接的方法的范围内,并且可以在整个方法中使用。 但是,与局部变量不同,方法参数在调用方法时从调用方获取值。 这是闹钟的修改形式,使您可以传递snoozeInterval

    public class AlarmClock {
      public void snooze(long snoozeInterval) {
        System.out.println("ZZZZZ for: " + snoozeInterval);
      }
    }
    public class AlarmClockTest {
      public static void main(String[] args) {
        AlarmClock aClock = new AlarmClock();
        // Pass in the snooze interval when you call the method.
        aClock.snooze(10000);  // Snooze for 10000 msecs.
      }
    }

    成员变量:对象如何存储数据

    局部变量很有用,但是由于它们仅提供临时存储,因此其值受到限制。 由于它们的生命周期跨越声明它们的方法的长度,因此局部变量与记事本进行比较,该记事本在您每次接到电话时出现,但在挂断电话时消失。 该设置对于记笔记非常有用,但是有时您需要一些更永久的东西。 程序员要做什么? 输入成员变量

    成员变量(其中有实例静态两个)构成类的一部分。

    范围和寿命可变

    开发人员实现实例变量以包含对类有用的数据。 一个实例变量在其范围和生存期方面与本地变量不同。 整个类构成一个实例变量的范围,而不是声明它的方法的范围。 换句话说,开发人员可以在类中的任何位置访问实例变量。 另外,实例变量的生存期不依赖于该类的任何特定方法。 也就是说,它的生存期就是包含它的实例的生存期。

    实例是从类定义中设计的蓝图创建的实际对象。 您在类定义中声明实例变量,从而影响从蓝图创建的每个实例。 每个实例都包含那些实例变量,并且变量中保存的数据因实例而异。

    考虑AlarmClock类。 将snoozeInterval传递到snoozeInterval snooze()方法中并不是一个很好的设计。 想象一下,每次您摸索到贪睡按钮时都必须在闹钟上输入贪睡间隔。 而是给整个闹钟一个snoozeInterval 。 使用AlarmClock类中的实例变量完成此操作,如下所示:

    public class AlarmClock {
      // You declare snoozeInterval here. This makes it an instance variable.
      // You also initialize it here.
      long m_snoozeInterval = 5000;   // Snooze time in millisecond = 5 secs.
      public void snooze() {
        // You can still get to m_snoozeInterval in an AlarmClock method
        // because you are within the scope of the class.
        System.out.println("ZZZZZ for: " + m_snoozeInterval);
       }
    }

    您可以在声明实例变量的类中的几乎任何位置访问实例变量。 为了对此进行技术性介绍,您可以在类范围内声明实例变量,然后可以从该范围内的几乎任何位置检索它。 实际上,您可以在开始类的第一个大括号和右括号之间的任何位置访问变量。 由于您还在类范围内声明方法,因此它们也可以访问实例变量。

    只要实例存在,您还可以从类外部访问实例变量,并且您具有引用该实例的变量。 要通过实例检索实例变量,可以将点运算符与实例一起使用。 这可能不是访问变量的理想方法,但出于说明目的,现在以这种方式完成该操作:

    public class AlarmClockTest {
      public static void main(String[] args) {
        // Create two clocks. Each has its own m_snoozeInterval
        AlarmClock aClock1 = new AlarmClock();
        AlarmClock aClock2 = new AlarmClock();
        // Change aClock2
        // You'll soon see that there are much better ways to do this.
        aClock2.m_snoozeInterval = 10000;
        aClock1.snooze();    // Snooze with aClock1's interval
        aClock2.snooze();    // Snooze with aClock2's interval
      }
    }

    尝试一下该程序,您会看到aClock1的间隔为5,000,而aClock2的间隔为10,000。 同样,每个实例都有其自己的实例数据。

    别忘了,类定义只是一个蓝图,因此在您从该蓝图创建实例之前,实例变量实际上并不存在。 一个类的每个实例都有自己的实例变量副本,并且该蓝图定义了这些实例变量将是什么。

    闹钟变量的两个实例 Java世界

    图1.一个带有实例变量的AlarmClock的两个实例

    封装形式

    封装是面向对象编程的基础之一。 使用封装时,用户通过公开的行为与类型进行交互,而不是直接与内部实现进行交互。 通过封装,您可以隐藏类型实现的详细信息。 在Java中,封装基本上转化为以下简单准则:“不要直接访问对象的数据;请使用其方法。”

    这是一个基本的想法,但它减轻了我们作为程序员的生活。 例如,假设您想指示一个Person对象站起来。 如果没有封装,您的命令可能会如下所示:“好吧,我想您需要在腿的前面收紧这块肌肉,在腿的后面收紧这块肌肉。嗯-需要弯曲腰部也是如此。哪些肌肉引发了这种运动?需要收紧这些肌肉,松开那些。哎呀!忘了另一条腿。该死的,看它-不要翻倒……” 使用封装,您只需要调用standUp()方法。 很简单,是吗?

    封装的一些优点:

    • 详细信息的抽象 :用户在更高级别上与类型进行交互。 如果使用standUp()方法,则不再需要知道启动该动作所需的所有肌肉。
    • 与变更隔离:内部实施的变更不会影响用户。 如果一个人扭伤了脚踝,并依靠拐杖一会儿,则用户仍然仅调用standUp()方法。
    • 正确性:用户不能随意更改对象的内部。 他们只能完成您所允许的编写方法。

    这是一个简短的示例,其中封装明显有助于提高程序的准确性:

    // Bad -- doesn't use encapsulation
    public class Person {
      int m_age;
    }
    public class PersonTest {
      public static void main(String[] args) {
        Person p = new Person();
        p.m_age = -5; // Hey -- how can someone be minus 5 years old?
      }
    }
    // Better - uses encapsulation
    public class Person {
      int m_age;
      public void setAge(int age) {
        // Check to make sure age is greater than 0. I'll talk more about
        // if statements at another time.
        if (age > 0) {
          m_age = age;
        }
      }
    }
    public class PersonTest {
      public static void main(String[] args) {
        Person p = new Person();
        p.setAge(-5); // Won't have any effect now.
      }
    }

    即使是那个简单的程序,也显示了如果直接访问类的内部数据将如何陷入麻烦。 程序越大,越复杂,封装就越重要。 还请记住,许多程序从小开始,然后无限期发展,因此从一开始就正确设计它们至关重要。 要将封装应用于AlarmClock ,您可以仅创建方法来控制暂停间隔。

    关于方法的注释

    方法可以返回调用者使用的值。 要返回值,请声明非空返回类型,并使用return语句。 下面示例中显示的getSnoozeInterval()方法对此进行了说明。

    编写程序

    翻译自: https://www.infoworld.com/article/2076301/learn-how-to-store-data-in-objects.html

    java 数据库中存储对象

    展开全文
  • Redis不支持直接将Java对象存储数据库中,所以需要将java对象进行序列化得到字节数组,然后将字节数组存入到redis中,需要数据的时候就从redis数据库中取出字节数组,再经过反序列化将自己数组转换成对象使用(jdk...

    Redis不支持直接将Java对象存储到数据库中,所以需要将java对象进行序列化得到字节数组,然后将字节数组存入到redis中,需要数据的时候就从redis数据库中取出字节数组,再经过反序列化将自己数组转换成对象使用(jdk序列化性能比谷歌公司的Protobuf序列化性能要差一些,而且序列化后的字节长度要也会长一些,所以推荐使用Protobuf,Protobuf如何进行序列化请看我的另一篇帖子)
    实体类
    User.java

    [java]  view plain  copy     在CODE上查看代码片 派生到我的代码片
    1. import java.io.Serializable;  
    2. public class User implements Serializable{  
    3. private static final long serialVersionUID = 2724888087391664167L;  
    4. private String id;  
    5. private String username;  
    6. private String password;  
    7. public User() {  
    8. }  
    9. public User(String id, String username, String password) {  
    10. this.id = id;  
    11. this.username = username;  
    12. this.password = password;  
    13. }  
    14. public String getId() {  
    15. return id;  
    16. }  
    17. public void setId(String id) {  
    18. this.id = id;  
    19. }  
    20. public String getUsername() {  
    21. return username;  
    22. }  
    23. public void setUsername(String username) {  
    24. this.username = username;  
    25. }  
    26. public String getPassword() {  
    27. return password;  
    28. }  
    29. public void setPassword(String password) {  
    30. this.password = password;  
    31. }  
    32. public static long getSerialversionuid() {  
    33. return serialVersionUID;  
    34. }  
    35. @Override  
    36. public String toString() {  
    37. return "User [id=" + id + ", username=" + username + ", password="  
    38. + password + "]";  
    39. }  
    40. }  
    序列化反序列化工具类
    SerializeUtils.java

    [java]  view plain  copy     在CODE上查看代码片 派生到我的代码片
    1. import java.io.ByteArrayInputStream;  
    2. import java.io.ByteArrayOutputStream;  
    3. import java.io.IOException;  
    4. import java.io.ObjectInputStream;  
    5. import java.io.ObjectOutputStream;  
    6. public class SerializeUtils {  
    7. public static byte[] serialize(Object obj){  
    8. byte[] bytes = null;  
    9. try {  
    10. ByteArrayOutputStream baos=new ByteArrayOutputStream();;  
    11. ObjectOutputStream oos=new ObjectOutputStream(baos);  
    12. oos.writeObject(obj);  
    13. bytes=baos.toByteArray();  
    14. baos.close();  
    15. oos.close();  
    16. catch (IOException e) {  
    17. e.printStackTrace();  
    18. }  
    19. return bytes;  
    20. }  
    21. public static Object deSerialize(byte[] bytes){  
    22. Object obj=null;  
    23. try {  
    24. ByteArrayInputStream bais=new ByteArrayInputStream(bytes);  
    25. ObjectInputStream ois=new ObjectInputStream(bais);  
    26. obj=ois.readObject();  
    27. catch (Exception e) {  
    28. e.printStackTrace();  
    29. }  
    30. return obj;  
    31. }  
    32. }  
    测试类RedisTest.java
    [java]  view plain  copy     在CODE上查看代码片 派生到我的代码片
    1. import java.util.HashMap;  
    2. import java.util.List;  
    3. import java.util.Map;  
    4. import java.util.Set;  
    5. import org.junit.Test;  
    6. import redis.clients.jedis.Jedis;  
    7. public class RedisTest{  
    8. private static Jedis jedis;  
    9. static{  
    10. //访问本地redis  
    11. jedis = new Jedis("127.0.0.1",6379);  
    12. }  
    13. @Test  
    14. public void serialize(){  
    15. User user=new User("1000""宝宝""xioabao");  
    16. jedis.set(user.getId().getBytes(), SerializeUtils.serialize(user));  
    17. byte[] bytes=jedis.get(user.getId().getBytes());  
    18. System.out.println((User)SerializeUtils.deSerialize(bytes));  
    19. }  
    20. }
    展开全文
  • redis不支持直接将java对象存储数据库中,所以需要将java对象进行序列化得到字节数组,然后将字节数组存入到redis中,需要数据的时候就从redis数据库中取出字节数组,再经过反序列化将自己数组转换成对象使用(jdk...
  • java对象序列化并存储到文件和数据库

    万次阅读 热门讨论 2017-04-25 09:15:45
    Java中要实现将对象保存起来持久化,需要让对象实现Serializable接口,这样就能将java对象用二进制流保存并恢复。下面我将以保存到文件和保存到mysql来进行解析。先给出序列化类的定义:package model; import java....
  • redis主要存储类型最常用的五种数据类型: String Hash List Set Sorted set redis不能直接存取对象,如何解决呢? 两种方式 1、利用序列化和反序列化的方式 两层对象存取到redis 示例: 序列化工具类 ...
  • 源码greenDAO,greenDAO是一个可以帮助Android开发者快速将Java对象映射到SQLite数据库的表单中的ORM解决方案,通过使用一个简单的面向对象API,开发者可以对Java对象进行存储、更新、删除和查询。 greenDAO的主要...
  • 崇德易城市数据
  • HSQLDB(Hypersonic SQL)是纯Java开发的关系型数据库,并提供JDBC驱动存取数据。支持ANSI-92标准SQL语法。而且他占的空间很小。大约只有160K,拥有快速的数据库引擎。  Axion  Axion是一个小型,快速,开源的关系型...
  • 存储过程和函数以命名的数据库对象形式存储数据库当中。 存储数据库中的优点是很明显的,因为代码不保存在本地,用户可以在任何客户机上登录到数据库,并调用或修改代码。 * 存储过程和函数可由数据库提供安全...
  • 小型键值数据库,用于存储Java对象 对Java初学者来说很简单 强大的专家 什么是键值? 键值对(KVP)是一组两个链接的数据项:一个键(它是某些数据项的唯一标识符)和一个值(该值是所标识的数据或指向该数据的...
  • Java 轻量级库,用于在基于 JDBC 的关系数据库存储和检索 Java 对象。 目前仅支持 MySQL。 这是一项正在进行的工作...... 设置 在 main/resources 文件夹中需要一个配置文件,名为 mysql.conf 例如文件: ...
  • Java进阶(二十五)Java连接mysql数据库(底层实现) 前言 很长时间没有系统的使用java做项目了。现在需要使用java完成一个实验,其中涉及到java连接数据库。让自己来写,记忆中已无从搜索。特将之前使用的方法做一简单...
  • java访问MySQL数据库

    千次阅读 2014-06-08 14:22:44
    java访问MySQL数据库  一、java连接MySQL数据库 1、安装mysql connector/j驱动  添加jdbc驱动: mysql-connection-java-5.1.10-bin.jar 2、连接MySQL数据库  在java.sql包中存在DriverManager类、...
  • java获取数据库连接对象

    千次阅读 2016-11-06 13:29:25
    javaweb连接数据库
  • 那么在选择了省市县中的某一个城市 ,存储数据库中需要存储所选城市的代码。所以需要一个能将JSON数据(一般存储在javascript脚本中)结构全部导入到数据库中的功能。 JSON的特点是支持层级结构、支持数组表示的...
  • JDBC:java数据库连接对象

    千次阅读 2020-03-19 17:28:32
    全称为Java数据库连接对象,是java程序和数据库的连接桥梁。 作用:可以为多种关系型数据库DBMS提供统一的访问方式,用Java来操作数据库。 1. JDBC API主要功能:主要干三件事,具体通过以下类/接口实现: ...
  • 利用JAVA向Oracle数据库中插入大对象

    千次阅读 2010-05-04 14:48:00
    通过JDBC,我们可以向oracle插入大对象...这是一个存储文本的例子,解释我会在程序中以注释的形式写出/** * 将生成的表样存储数据库 * * @param htmlParam * @return */ public static boolean addToDB(HtmlPara
  • Java操作Sqlite数据库

    千次阅读 2017-09-24 21:21:03
    3.Java操作Sqlite 1.介绍 SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其它数据库不同,不需要在系统中配置。 就像其它...
  • Redis存储java对象或者java对象数组

    千次阅读 2020-03-01 17:47:08
    1. 先将java对象或者java对象数组用ObjectMapper转换为json对象 2. 再用jedis对象的put方法,将数据写入Redis数据库
  • java操作MongoDB数据库

    万次阅读 2016-07-22 12:58:58
    1、如何启动MongoDB数据库? 如图所示:安装好MongoDB之后,文件夹显示如下: MongoDB默认开启27017端口,打开浏览器,输入http://localhost:27017/,显示如下: 启动数据库步骤: (1)cd d:\...
  • 最近用SpringBoot重构一个PHP项目,用JPA操作MySQL数据库,由于要维持原来的表结构,应用中要把许多表转化为Java类,一般的ORM框架可以很方便地把Java类映射为关系数据库表,但这里显然是它的逆过程,这个好像没有...
  • Java 连接 Access 数据库

    千次阅读 2012-02-27 11:23:46
    测试代码如下: ... * @描述: TODO java连接Access数据库 * * * 建立Access数据库: * * 1.建立Access数据库db.mdb,并创建tUser表,字段有两个: ID字段和Password字段。 * 2.打开控制面板 ->
  • Java对MySQL数据库进行操作【java

    万次阅读 多人点赞 2016-09-23 14:28:34
    Java访问数据库主要用的方法是JDBC,它是java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法,接下来进行总结。 一、操作的一般过程 1、连接数据库 2、调用...
  • java JDBC连接数据库步骤及代码

    万次阅读 多人点赞 2018-12-06 09:34:01
    在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.lang.Class类的静态方法forName(String className)实现,成功加载后,会将Driver类的实例注册到DriverManager类中。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 375,926
精华内容 150,370
关键字:

java对象存储数据库

java 订阅