Refactoring Database Access in Marauroa: Difference between revisions
Jump to navigation
Jump to search
Content deleted Content added
imported>Kymara grammar and spelling and readability |
imported>Kymara |
||
| (49 intermediate revisions by 3 users not shown) | |||
| Line 1: | Line 1: | ||
Database access in marauroa was designed for a single thread application. While this works most of the time in turn based games (yes, Stendhal is turn based internally), it prevents doing non time critical stuff in another thread. In Stendhal we have the problem that any update or delete operation to the gameEvents table that takes more than a couple of seconds, kills the server. |
|||
== Requirements == |
== Requirements == |
||
| Line 27: | Line 27: | ||
=== What are those new ...DAO classes? How do they work? === |
=== What are those new ...DAO classes? How do they work? === |
||
DAO stands for "data access object". The basic idea is, and has been from the start, that the database related code is not in the original classes but at some central point outside the game logic. This used to be JDBCDatabase, but one single class for all database operations is very |
DAO stands for "data access object". The basic idea is, and has been from the start, that the database related code is not in the original classes but at some central point outside the game logic. This used to be JDBCDatabase, but one single class for all database operations is very hard to maintain. So JDBCDatabase has been split into a number of small classes focused on one area each: AccountDAO, CharacterDAO, GameEventDAO... |
||
These classes replace the old IDatabase / JDBCDatabase and do the database stuff. All of their methods have two signatures: One with a DBTransaction object as first parameter and one without. This is for your convenience: In most cases those functions are not part of a larger context so you do not have to care about transactions at all: the DAO-classes do the transaction handling on their own. There are, however, a small number of cases in which you want to do multiple calls to DAOs in one single transaction. In this case you get a DBTransaction from the TransactionPool and provide it as first parameter to DAO-methods. After you are done you must either commit or rollback your changes with the appropriate methods in the class TransactionPool. |
These classes replace the old IDatabase / JDBCDatabase and do the database stuff. All of their methods have two signatures: One with a DBTransaction object as first parameter and one without. This is for your convenience: In most cases those functions are not part of a larger context so you do not have to care about transactions at all: the DAO-classes do the transaction handling on their own. There are, however, a small number of cases in which you want to do multiple calls to DAOs in one single transaction. In this case you get a DBTransaction from the TransactionPool and provide it as first parameter to DAO-methods. After you are done you must either commit or rollback your changes with the appropriate methods in the class TransactionPool. |
||
| Line 36: | Line 36: | ||
Imagine you want to subclass the CharacterDAO with your class SomeGameCharacterDAO: |
Imagine you want to subclass the CharacterDAO with your class SomeGameCharacterDAO: |
||
<source lang="java"> |
|||
public class SomeGameCharacterDAO extends CharacterDAO { |
public class SomeGameCharacterDAO extends CharacterDAO { |
||
... |
... |
||
</source> |
|||
You simply register it as |
You simply register it as |
||
<source lang="java"> |
|||
DAORegistry.get().register(CharacterDAO.class, new SomeGameCharacterDAO()); |
DAORegistry.get().register(CharacterDAO.class, new SomeGameCharacterDAO()); |
||
</source> |
|||
Note: In the register call the first parameter is the parent class you want to replace. |
Note: In the register call the first parameter is the parent class you want to replace. |
||
| Line 46: | Line 49: | ||
=== What are those database adapters for? === |
=== What are those database adapters for? === |
||
They are a thin layer of database abstraction. This allows us to not only support MySQL but also database systems |
They are a thin layer of database abstraction. This allows us to not only support MySQL but also database systems which don't require an external server. |
||
=== Why is there a method getLastInsertId? === |
=== Why is there a method getLastInsertId? === |
||
| Line 80: | Line 82: | ||
The following diff shows the complete list of changes that were required to port JMaPacman. I think it may help you to get a feeling on how to adjust your own code. |
The following diff shows the complete list of changes that were required to port JMaPacman. I think it may help you to get a feeling on how to adjust your own code. |
||
<!-- |
|||
Don't use syntax highlighting here because it does not work well with the diff characters and bold formation |
|||
<source lang="java"> |
|||
--> |
|||
public class MaPacmanRPRuleProcessor implements IRPRuleProcessor |
public class MaPacmanRPRuleProcessor implements IRPRuleProcessor |
||
{ |
{ |
||
| Line 162: | Line 167: | ||
} |
} |
||
} |
} |
||
[[Category:Marauroa]] |
|||