4

I guess I'm new to basic Java -- Android and .NET both have simple ways of storing application-specific data to private databases, but I'm seeing no such method for data storage in plain ol' Java.

What am I missing here? Hibernate and JPA seem a little excessive.


Edit: I was not looking for a lot of data storage in my application (yet) -- just a persistent record of a few settings like the current user should be good enough. I was basically looking for an analog to Android's shared preferences or .Net's properties.

(This is after the fact, however, since I've received a wealth of responses.)

  • 3
    Java isn't an operating system. – Hot Licks Aug 27 '14 at 21:30
  • 4
    Yes, Properties is one, Serializing is another one... which type of data is the question and in which volume. On the other hand, based on your question I understand that you are just looking for tables, is this correct? Good luck. – Fer Aug 27 '14 at 21:30
  • 1
    There's no such feature in Java. At most you can store data in .properties files through [`Properties`](http://docs.oracle.com/javase/8/docs/api/java/util/Properties.html) class or store binary data. – Luiggi Mendoza Aug 27 '14 at 21:30
  • 1
    Properties is (as far as I can tell right now) the exact analog to C#'s data persistence I was looking for. @Fer The amount of data I want to store right now is really small, and serializing it would be a bit silly. –  Aug 27 '14 at 21:32
  • 2
    What about the [Preferences API](http://docs.oracle.com/javase/8/docs/technotes/guides/preferences/index.html)? – David Conrad Aug 27 '14 at 22:48
  • 1
    @LuiggiMendoza No such feature apart from Properties, Preferences, Serialization, XMLEncoder, JDBC, JNDI, JAXB, ... – user207421 Aug 28 '14 at 08:48
  • 1
    @DavidConrad - I would certainly recommend the `Preferences` API over the `Properties` API. – Rudi Kershaw Aug 28 '14 at 09:04
  • Seems so..... http://stackoverflow.com/questions/2358651/are-java-properties-effectively-deprecated –  Aug 28 '14 at 13:27
  • @HotLicks I do not understand what makes you think I believed Java was an OS, or what your comment adds to the discussion. –  Aug 28 '14 at 13:28

4 Answers4

3

If the Preferences API is not comprehensive enough and Hibernate/JPA seem excessive, then probably the most simple intermediate alternative, and easiest to learn, method of storing application data in a database is Java JDBC.

Simple example below;

    // Database URL including driver, username, password, database name etc.
    String URL = "jdbc:oracle:thin:username/password@amrood:1521:EMP";
    Connection conn = DriverManager.getConnection(URL);
    // Create your SQL Query.
    PreparedStatement st = conn.prepareStatement("UPDATE YourTable SET YourColumn = 12 WHERE TableID = 1337");
    // Execute (If your statement doesn't need to return results).
    st.execute();

SQLite can run locally and within your application. The drivers also can be integrated. No server required. So between the two you have simple, local persistence in the form of an SQL database.


Edit:

After seeing that you only require persisting settings/preferences I would recommend the newer Preferences API (tutorial linked above) over the older Properties API, because the Preferences API handles file location more elegantly for you.

Example;

// This will define a node in which the preferences can be stored
prefs = Preferences.userRoot().node(this.getClass().getName());
// First we get the values
// Define a boolean value with the default true
prefs.getBoolean("Test1", true);
// Define a string with default "Hello World"
prefs.get("Test2", "Hello World");
// Define a integer with default 50
prefs.getInt("Test3", 50);
// now set the values
prefs.putBoolean("Test1", false);
prefs.put("Test2", "Hello Europa");
prefs.putInt("Test3", 45);
// Delete the preference settings for the first value
prefs.remove("Test1");
Rudi Kershaw
  • 12,332
  • 7
  • 52
  • 77
  • 1
    In my last project I made use of JDBC and SQlite and it worked out pretty nicely. Nothing fancy or refreshing but it does the job. – zubergu Aug 27 '14 at 21:41
  • But -- forgive my lack of knowledge -- doesn't this require some externally hosted... thing? Extra SQLite drivers? etc? (edit: apparently, yes. https://bitbucket.org/xerial/sqlite-jdbc) –  Aug 27 '14 at 21:59
  • @user .Net also needs a externally hosted database when writing to MySQl, SQL Server or Oracle. No difference there. – Namphibian Aug 27 '14 at 22:48
  • @user - Updated my answer to include reference to `Preferences` API. Also, [SQLite](http://www.sqlite.org/) can run locally and within your application. The drivers also can be integrated. No server required. – Rudi Kershaw Aug 28 '14 at 08:45
  • @Namphibian for my purposes (which I really didn't specify, so I can't complain), JDBC is a bit of overkill. I should have asked to persist "settings" instead of something so vague. –  Aug 28 '14 at 13:13
1

Are you trying to save a java object to a file or DB? Maybe look at the Serializable interface

http://www.mkyong.com/java/how-to-write-an-object-to-file-in-java/

Justin
  • 1,356
  • 2
  • 9
  • 16
1

Properties is a great suggestion for simple key/value configuration type data.

Since you suggested Hibernate/JPA, I'll throw out embedded Derby. It is a database you can embed in your application & in memory. http://db.apache.org/derby/

Serialization is better avoided for this purpose. I'd save it for clustering or sending objects between VM's.

Barett
  • 5,826
  • 6
  • 51
  • 55
1

If you need a simple key-value store, consider Properties.

Here's an example simple usage of Properties.

public class Program {
    static final Properties Prefs = new Properties();
    static final String Default_Path = "prefs.properties";

    static void loadPreferences() throws IOException { 
        try (FileInputStream fis = new FileInputStream(Default_Path)) {
            Prefs.loadFromXML(fis);
        } catch (FileNotFoundException ex) { 
            // Okay - if not found we'll save it later
        }
    }

    static void savePreferences() throws FileNotFoundException, IOException {
        try (FileOutputStream fos = new FileOutputStream(Default_Path)) {
            Prefs.storeToXML(fos, "Program Preferences");
        }

    }

    public static void main(String[] args) throws IOException {
        loadPreferences();

        if (Prefs.getProperty("FavoriteColor") == null) {
            Prefs.setProperty("FavoriteColor", "black"); 
        }

        System.out.println(Prefs.getProperty("FavoriteColor"));

        savePreferences();
    }
}

Which generates an XML files, prefs.properties:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Program Preferences</comment>
<entry key="FavoriteColor">black</entry>
</properties>

Key notes

  • Don't use Properties.put(). Use Properties.setProperty() and Properties.getProperty().
  • Tend to prefer methods declared as part of Properties and not those inherited from Hashtable.

You specifically asked about serialzation in comments. I would not use it for this task. (I'd probably not use it for any task actually, but...).

  • Serialzation allows your class's invariants to be broken. i.e. serialize an instance, that instance is edited outside, then deserialized back into an object.
  • implements Serializable effectively gives your class a constructor, so it doesn't work with Singletons and other creational patterns.
  • implements Serializable also exposes all your fields, except those you declare as transient. That means that private parts of your class are part of the public interface. Boo on you if you change it later (by that I mean, later versions will likely break it without careful controls.)
  • this list is incomplete...

Some argue that serialization can be done right, but it's a hard one to get right for sure.

jdphenix
  • 15,022
  • 3
  • 41
  • 74