Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (491)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (556)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  What do Java game developers use for Database persistence?  (Read 7556 times)
0 Members and 1 Guest are viewing this topic.
Offline sproket

Junior Member


Medals: 1



« Posted 2012-05-17 22:50:18 »

Hi All,

I've been hacking at a game for a while and I need a fair amount of data so I use SQLite and store it.  Using JDBC directly is somewhat tedious and I was wondering if anyone had any good ORM type libs they recommend for use for games or smallish apps.

I've looked at Hibernate but it's huge and over complicated for my needs.

Thoughts?

TIA

Offline OttoMeier

Senior Member


Medals: 4
Projects: 1



« Reply #1 - Posted 2012-05-17 23:11:41 »

sounds like mybatis could be the right tool for you.
Offline ReBirth
« Reply #2 - Posted 2012-05-17 23:47:23 »

What we need is something that can automaticlly convert a class into a record in a table, matching field's value and type to table's colomn. That already is available on MVC frmaework such as Play!, but I see no one yet for desktop use.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline sproket

Junior Member


Medals: 1



« Reply #3 - Posted 2012-05-18 00:04:35 »

Yeah I see what you mean. Most ORMs are more complex than they need to be for basic usage.

The closest I found is Persist (http://code.google.com/p/persist/) but it's not well maintained and it has it's fair share of quirks.

I've been hacking around with various solutions and so far found nothing that I like yet.  I see what you mean by Play framework - something could be adapted from it.


Offline SimonH
« Reply #4 - Posted 2012-05-18 00:11:40 »

What we need is something that can automaticlly convert a class into a record in a table, matching field's value and type to table's colomn. That already is available on MVC frmaework such as Play!, but I see no one yet for desktop use.
This is a fairly easy task using reflection. You can pretty much just drop a class and its fields/values into an sql command.

People make games and games make people
Offline sproket

Junior Member


Medals: 1



« Reply #5 - Posted 2012-05-18 00:14:37 »

Hi Otto,

Even MyBatis seems too complex. If (eventually) I need to port to a smaller device - the smaller the library the better.

Let me mull this over for a bit.

Offline ReBirth
« Reply #6 - Posted 2012-05-18 00:24:49 »

What we need is something that can automaticlly convert a class into a record in a table, matching field's value and type to table's colomn. That already is available on MVC frmaework such as Play!, but I see no one yet for desktop use.
This is a fairly easy task using reflection. You can pretty much just drop a class and its fields/values into an sql command.
I had done it before, but that's not reliable. On Play!, you just let the will-be-persisted class to extends Model and call save() like playerData.save() to persist. The framework will take care everything including table creation. If in next day you add more field, it will also update the schema for you. That's most simple DML related operation that I ever use.

Offline sproket

Junior Member


Medals: 1



« Reply #7 - Posted 2012-05-18 00:52:53 »

I had done it before, but that's not reliable. On Play!, you just let the will-be-persisted class to extends Model and call save() like playerData.save() to persist. The framework will take care everything including table creation. If in next day you add more field, it will also update the schema for you. That's most simple DML related operation that I ever use.

Interesting but this is also a huge framework 90 MEG! On server side applications size is not so important. For smaller apps and Games we need something tiny that just does the job with little or no dependencies.

Offline ReBirth
« Reply #8 - Posted 2012-05-18 00:57:05 »

Yeah, if only we could find a way to just rip off that Model library. However it needs other dependencies inside that 90MB.

Offline sproingie

JGO Kernel


Medals: 202



« Reply #9 - Posted 2012-05-18 05:37:42 »

Play 2.0 uses Ebean for Java and Anorm for Scala.  They're both available separately.

Ebean: http://www.avaje.org
Anorm: http://repo.typesafe.com/typesafe/releases/play/anorm_2.9.1/

There's also Siena, another AR type thing: http://www.sienaproject.com/index.html
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline 65K
« Reply #10 - Posted 2012-05-18 05:50:37 »

I use MyBatis.
Pretty simple to use.
Pojos with SQL defined in XML and/or in annotations.
Can't speak how it deals with more complex requirements - I only save players and scores so far.
In compound with JavaDB there is an issue with setting null values, so I might change to HSQLDB.
Overall it is definitely worth a look.

Offline divxdede

Junior Member





« Reply #11 - Posted 2012-05-18 07:58:25 »

(Theses configuration was not always useed for games but for my projects in general)

Database + Persistence Layer : H2 + Hibernate (for larger project that fit he need of an SQL langage)
Database + Persistence Layer : Cassandra + Custom persistence layer (for servers that just need to store some simple data structures)
Database + Persistence Layer : Serialization + Custom persistance layer (for small games)


Offline sproket

Junior Member


Medals: 1



« Reply #12 - Posted 2012-05-18 10:55:06 »

Play 2.0 uses Ebean for Java and Anorm for Scala.  They're both available separately.
There's also Siena, another AR type thing:
<snip>
Thanks that's interesting.

Offline ReBirth
« Reply #13 - Posted 2012-05-18 11:25:55 »

Play 2.0 uses Ebean for Java and Anorm for Scala.  They're both available separately.

Ebean: http://www.avaje.org
Anorm: http://repo.typesafe.com/typesafe/releases/play/anorm_2.9.1/

There's also Siena, another AR type thing: http://www.sienaproject.com/index.html

Siena is what I meant. Beside save() there are useful static method such as find() and fetch(). Thanks for find it.

Offline sproket

Junior Member


Medals: 1



« Reply #14 - Posted 2012-05-18 12:10:19 »

This is a lot of good info. Thanks guys.

I have some code for this I've been working on as well. I have some vacation days so I was thinking of putting it together. 

It does not require any mapping, instead it uses auto-discovery and convention over configuration to figure out table and column names.

If I get something and post a link would anyone be interested in trying it out?  Maybe I could have something in the next week or so.


Offline ReBirth
« Reply #15 - Posted 2012-05-18 12:13:18 »

You can post it on Shared Code section.

Offline cylab

JGO Ninja


Medals: 44



« Reply #16 - Posted 2012-05-18 17:15:01 »

You can also do it the other way around - generating record classes from a db-schema. I had some good experience with JOOQ

Mathias - I Know What [you] Did Last Summer!
Offline sproket

Junior Member


Medals: 1



« Reply #17 - Posted 2012-05-18 18:55:42 »

You can also do it the other way around - generating record classes from a db-schema. I had some good experience with JOOQ

Yeah JOOQ is interesting but really it emphasizes the query.  In many situations especially with games we don't have any complicated queries to worry about. Really I'd prefer just a simple Java Bean and a quick and easy way to read and write it.

Offline sproingie

JGO Kernel


Medals: 202



« Reply #18 - Posted 2012-05-18 19:36:51 »

I used to insist on using a really "proper" O-R mapper so that JPA or JDO were the only real ways, maybe with MyBatis for complex schemas that just weren't going to map cleanly, but these days I figure anything with actually proper behavior that's at least smart enough to avoid the N+1 selects problem is all good.  Mostly it's because I'm finding that directly and transparently mapping entities into domain objects just doesn't work out well for me anyway.  Unless it's a DB app first and foremost, there's always some annoying facet of the ORM that's going to get in your way and force you to compromise the design just to satisfy the ORM.  Despite all the efforts to paper it over, the "impedance mismatch" is still there and probably always will be.


Offline dector

Senior Member


Medals: 3
Projects: 3



« Reply #19 - Posted 2012-05-18 19:44:30 »

Offtopic: By the way, try H2 Database. It has better perfomance than SQLite.
Offline princec

JGO Kernel


Medals: 369
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #20 - Posted 2012-05-18 22:05:56 »

I use straight JDBC. I then got on with my life and wrote some games Smiley

Cas Smiley

Offline Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #21 - Posted 2012-05-19 06:20:21 »

I use straight JDBC. I then got on with my life and wrote some games Smiley
I should totally unleash my minimalistic JDBC wrapper upon you!

It takes the cruft out of the CRUD. persecutioncomplex

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline princec

JGO Kernel


Medals: 369
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #22 - Posted 2012-05-19 13:23:23 »

It barely takes any time at all to write something like that though with a few annotations here and there. I don't have enough database stuff to warrant even bothering with it though.

Cas Smiley

Offline Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #23 - Posted 2012-05-19 13:32:11 »

Sure, it's not hard, but I haven't seen any jdbc wrapper as convenient as mine, yet Smiley

I'll post it in a few days, when I removed the worst bits Smiley

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #24 - Posted 2012-06-11 11:55:29 »

I would really like to see that wrapper, Riven. I've been pondering creating one myself, but I've been busy in school.

We just finished a JSP/EJB 3.0 project. I love EJB, though it is rather complex, and impossible to host cheaply. Please post this wrapper, so I won't have to resort to put up a private EJB-server ^^

- Jonas
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #25 - Posted 2012-06-11 13:52:38 »

I currently only have tested bindings to a MySQL db. It should work on every database that supports simple INSERT,SELECT,UPDATE,DELETE queries, because that's pretty much what this wrapper does.

The wrapper is really 'hands off' and non-intrusive, so the database table-design is leading. No effort is made into even storing metadata like @nullable. You'll get a typical SQLException from the server instead if you try to write a null value where it's not allowed.

A typical Account & Deposit class 'backed' by tables would look like:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
public class Account extends DataObject {
   public String username;
   public String passhash;
   public String passsalt;
   public String emailaddress;
   public int money;

   public Account() { super(); }
   public Account(int id) { super(id); }
}

public class Deposit extends DataObject {
   public Account account;
   public int amount;

   public Deposit() { super(); }
   public Deposit(int id) { super(id); }
}


Usage:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
Account account = new Account(3421); // performs a SELECT

Deposit deposit1 = new Deposit(); // no SELECT
deposit1.account = account;
deposit1.amount = 40;
deposit1.insert();
System.out.println("deposit #1 ID="+deposit1.id());

Deposit deposit2 = new Deposit(); // no SELECT
deposit2.account = account;
deposit2.amount = 42;
deposit2.insert(); // INSERT
System.out.println("deposit #2 ID="+deposit2.id());

deposit2.amount += 3;
deposit2.update(); // UPDATE

deposit1.delete(); // DELETE



Say you want to query all Deposits of an Account:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
public class Account extends DataObject {
   public String username;
   public String passhash;
   public String passsalt;
   public String emailaddress;
   public int money;

   public Account() { super(); }
   public Account(int id) { super(id); }

   public List<Deposit> getDeposits() {
      // this is so common, that I will probably move the actual query behind a utility method.
     return QueryDataObject.selectAll(Deposit.class,
         "SELECT * FROM deposit WHERE account = ?",
         this /* varargs: every '?' in the query requires an additional argument */);
   }
}


Say you want to query the Account of a Deposit:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
public class Deposit extends DataObject {
   public Account account;
   public int amount;

   public Deposit() { super(); }
   public Deposit(int id) { super(id); }

   public Account selectAccount() {
      return (this.account == null) ? null : this.account.select();
   }
}


This shows the following:
1  
2  
3  
Deposit d = new Deposit(37); // SELECT * FROM deposit WHERE somePrimaryKey = 37
// d.account is an instance, but is NOT filled with data, just an identifier, hence:
d.account.select(); // SELECT * FROM account WHERE somePrimaryKey = d.account.id()



The DataObject class allows you to override the default names for the tablename and primarykey column.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
public class DataObject {
   public int id;
   
   //
 
   public String getTableName() {
      return this.getClass().getSimpleName().toLowerCase(); // "Account" -> "account"
  }
   
   public String getPrimaryKey() {
      return this.getTableName() + "id"; // "Account" -> "accountid"
  }
}

public class Account extends DataObject {
   @Override
   public String getPrimaryKey() {
      return "accountnr";
   }
}

The names of the (other) fields/colums are not configurable. They are used as-is. Java enums are supported and map directly to MySQL's ENUM type.



This is really all there is to it. Well, there is more, like connection pools and preInsert / preUpdate / postDelete / postSelect callbacks, so you can implement poor man's java-side triggers.

It's really simple, so you're really doing queries select()s, update()s, delete()s on individual objects. For select()s we have the QueryDataObject class, with methods which return List<...>





Is this what you're looking for? I'll only make it public when somebody actually needs it.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #26 - Posted 2012-06-11 15:07:05 »

Seems legit Cheesy I like it! Very simple and easy to use. You really should publish it. I know I'd love to poke around the code a bit, to see how it all fits together. It might be just what I need.

- Jonas
Offline Roquen
« Reply #27 - Posted 2012-06-11 15:20:52 »

I wonder how well akka's data-store works...that could potentially kill two birds with one stone for massive entity systems.
Offline sproingie

JGO Kernel


Medals: 202



« Reply #28 - Posted 2012-06-11 15:58:42 »

I love EJB, though it is rather complex, and impossible to host cheaply.

How's free grab you?  JavaEE 6 on OpenShift

Offline sproingie

JGO Kernel


Medals: 202



« Reply #29 - Posted 2012-06-11 16:01:11 »

I wonder how well akka's data-store works...that could potentially kill two birds with one stone for massive entity systems.

Akka doesn't have anything like a database or other flavor of data store that I'm aware of.  Is there something specific you're referring to?
Pages: [1] 2
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Nickropheliac (15 views)
2014-08-31 22:59:12

TehJavaDev (23 views)
2014-08-28 18:26:30

CopyableCougar4 (29 views)
2014-08-22 19:31:30

atombrot (41 views)
2014-08-19 09:29:53

Tekkerue (38 views)
2014-08-16 06:45:27

Tekkerue (35 views)
2014-08-16 06:22:17

Tekkerue (25 views)
2014-08-16 06:20:21

Tekkerue (34 views)
2014-08-16 06:12:11

Rayexar (72 views)
2014-08-11 02:49:23

BurntPizza (48 views)
2014-08-09 21:09:32
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!