diff --git a/src/zutil/db/bean/DBBean.java b/src/zutil/db/bean/DBBean.java
index 0bf753f..379c43f 100644
--- a/src/zutil/db/bean/DBBean.java
+++ b/src/zutil/db/bean/DBBean.java
@@ -18,10 +18,23 @@ import java.util.NoSuchElementException;
import zutil.db.DBConnection;
/**
+ *
* The class that extends this will be able to save its state to a DB.
* Fields that are transient will be ignored, and fields that extend
* DBBean will be replaced by the id field of that class.
*
+ * Supported fields:
+ * *Boolean
+ * *Integer
+ * *Short
+ * *Float
+ * *Double
+ * *String
+ * *Character
+ * *DBBean
+ * *List
+ *
+ *
* @author Ziver
*/
public abstract class DBBean {
@@ -35,6 +48,15 @@ public abstract class DBBean {
String value();
}
+ /**
+ * Sets the name of the table that links different DBBeans together
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.FIELD)
+ public @interface DBLinkTable {
+ String value();
+ }
+
/**
* Sets the field as the id column in the table
*/
@@ -57,15 +79,16 @@ public abstract class DBBean {
fields = new ArrayList();
}
}
- /**
- * This is a cache of all the initialized beans
- */
- private static HashMap,DBBeanConfig> beanConfigs = new HashMap,DBBeanConfig>();
+ /** This is a cache of all the initialized beans */
+ private static HashMap,DBBeanConfig> beanConfigs = new HashMap,DBBeanConfig>();
+ /** This value is for preventing recursive loops */
+ private boolean processing;
protected DBBean(){
if( !beanConfigs.containsKey( this.getClass() ) )
initBeanConfig( this.getClass() );
+ processing = false;
}
/**
@@ -119,7 +142,11 @@ public abstract class DBBean {
/**
* Saves the Object to the DB
*/
+ @SuppressWarnings("unchecked")
public void save(DBConnection sql) throws SQLException{
+ if(processing)
+ return;
+ processing = true;
Class extends DBBean> c = this.getClass();
DBBeanConfig config = beanConfigs.get(c);
try {
@@ -141,11 +168,31 @@ public abstract class DBBean {
Field field = config.fields.get(i);
// Another DBBean class
- if( DBBean.class.isAssignableFrom( field.getDeclaringClass() )){
+ if( DBBean.class.isAssignableFrom( field.getType() )){
DBBean subobj = (DBBean)field.get(this);
subobj.save(sql);
stmt.setObject(i+2, getBeanConfig(subobj.getClass()) );
}
+ // A list of DBBeans
+ else if( List.class.isAssignableFrom( field.getType() ) &&
+ field.getAnnotation( DBLinkTable.class ) != null){
+ List list = (List)field.get(this);
+ String subtable = field.getAnnotation( DBLinkTable.class ).value().replace("\"", "");
+
+ DBBeanConfig subConfig = null;
+ for(DBBean subobj : list){
+ if(subConfig == null)
+ subConfig = beanConfigs.get( subobj.getClass() );
+ // Save links in link table
+ PreparedStatement subStmt = sql.getPreparedStatement("REPLACE INTO \""+subtable+"\" "+config.tableName+"=? ?=?");
+ subStmt.setObject(1, config.id_field);
+ subStmt.setString(2, subConfig.tableName);
+ subStmt.setObject(3, subConfig.id_field.get(subobj));
+ DBConnection.exec(subStmt);
+ // Save the sub bean
+ subobj.save(sql);
+ }
+ }
// Normal field
else
stmt.setObject(i+2, field.get(this));
@@ -161,7 +208,7 @@ public abstract class DBBean {
}
/**
- * Deletes the object from the DB
+ * Deletes the object from the DB, WARNING will not delete sub beans
*/
public void delete(DBConnection sql){
Class extends DBBean> c = this.getClass();
@@ -189,16 +236,16 @@ public abstract class DBBean {
* @param c is the class of the bean
* @return a LinkedList with all the Beans in the DB
*/
- public static List load(DBConnection sql, Class c) throws SQLException {
+ public static List load(DBConnection db, Class c) throws SQLException {
// Initiate a BeanConfig if there is non
if( !beanConfigs.containsKey( c ) )
initBeanConfig( c );
DBBeanConfig config = beanConfigs.get(c);
// Generate query
- PreparedStatement stmt = sql.getPreparedStatement( "SELECT * FROM ?" );
+ PreparedStatement stmt = db.getPreparedStatement( "SELECT * FROM ?" );
stmt.setString(1, config.tableName);
// Run query
- List list = DBConnection.exec(stmt, DBBeanResultHandler.createList(c) );
+ List list = DBConnection.exec(stmt, DBBeanSQLResultHandler.createList(c, db) );
return list;
}
@@ -210,18 +257,18 @@ public abstract class DBBean {
* @param id is the id value of the bean
* @return a DBBean Object with the specific id or null
*/
- public static T load(DBConnection sql, Class c, Object id) throws SQLException {
+ public static T load(DBConnection db, Class c, Object id) throws SQLException {
// Initiate a BeanConfig if there is non
if( !beanConfigs.containsKey( c ) )
initBeanConfig( c );
DBBeanConfig config = beanConfigs.get(c);
// Generate query
- PreparedStatement stmt = sql.getPreparedStatement( "SELECT * FROM ? WHERE ?=? LIMIT 1" );
+ PreparedStatement stmt = db.getPreparedStatement( "SELECT * FROM ? WHERE ?=? LIMIT 1" );
stmt.setString(1, config.tableName);
stmt.setString(2, config.id_field.getName());
stmt.setObject(3, id );
// Run query
- T obj = DBConnection.exec(stmt, DBBeanResultHandler.create(c) );
+ T obj = DBConnection.exec(stmt, DBBeanSQLResultHandler.create(c, db) );
return obj;
}
@@ -284,6 +331,7 @@ public abstract class DBBean {
*/
protected Object getFieldValue(Field field){
try {
+ field.setAccessible(true);
return field.get(this);
} catch (Exception e) {
e.printStackTrace();
@@ -299,6 +347,7 @@ public abstract class DBBean {
*/
protected void setFieldValue(Field field, Object o){
try {
+ field.setAccessible(true);
field.set(this, o);
} catch (Exception e) {
e.printStackTrace();
diff --git a/src/zutil/db/bean/DBBeanResultHandler.java b/src/zutil/db/bean/DBBeanResultHandler.java
deleted file mode 100644
index 2d24b5b..0000000
--- a/src/zutil/db/bean/DBBeanResultHandler.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package zutil.db.bean;
-
-import java.lang.reflect.Field;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.sql.ResultSet;
-import java.util.LinkedList;
-import java.util.List;
-
-import zutil.db.SQLResultHandler;
-import zutil.db.bean.DBBean.DBBeanConfig;
-
-public class DBBeanResultHandler implements SQLResultHandler{
-
- private Class extends DBBean> bean_class;
- private DBBeanConfig bean_config;
- private boolean list;
-
- /**
- * Creates a new instance of this class that returns only one bean
- *
- * @param cl is the DBBean class that will be parsed from the SQL result
- * @return a new instance of this class
- */
- public static DBBeanResultHandler create(Class cl){
- return new DBBeanResultHandler(cl, false);
- }
-
- /**
- * Creates a new instance of this class that returns a list of beans
- *
- * @param cl is the DBBean class that will be parsed from the SQL result
- * @return a new instance of this class
- */
- public static DBBeanResultHandler> createList(Class cl){
- return new DBBeanResultHandler>(cl, true);
- }
-
- /**
- * Creates a new instance of this class
- *
- * @param cl is the DBBean class that will be parsed from the SQL result
- */
- protected DBBeanResultHandler(Class extends DBBean> cl, boolean list) {
- this.bean_class = cl;
- this.list = list;
- this.bean_config = DBBean.getBeanConfig( cl );
- }
-
- /**
- * Is called to handle an result from an query.
- *
- * @param stmt is the query
- * @param result is the ResultSet
- */
- @SuppressWarnings("unchecked")
- public T handle(Statement stmt, ResultSet result) throws SQLException{
- if( list ){
- LinkedList bean_list = new LinkedList();
- while( result.next() ){
- DBBean obj = createBean(result);
- bean_list.add( obj );
- }
- return (T) bean_list;
- }
- else{
- if( result.next() )
- return (T) createBean(result);
- return null;
- }
-
- }
-
- /**
- * Instantiates a new bean and assigns field values from the ResultSet
- *
- * @param result is where the field values for the bean will bee read from, the cursor should be in front of the data
- * @return a new instance of the bean
- */
- @SuppressWarnings("unchecked")
- private DBBean createBean(ResultSet result) throws SQLException{
- try {
- DBBean obj = bean_class.newInstance();
-
- for( Field field : bean_config.fields ){
- String name = field.getName();
-
- // Another DBBean class
- if( DBBean.class.isAssignableFrom( field.getDeclaringClass() )){
- DBBean subobj = DBBean.load(null, (Class extends DBBean>)field.getDeclaringClass(), result.getObject(name));
- obj.setFieldValue(field, subobj);
- }
- // Normal field
- else
- obj.setFieldValue(field, result.getObject(name));
- }
- return obj;
-
- } catch (InstantiationException e) {
- throw new SQLException(e);
- } catch (IllegalAccessException e) {
- throw new SQLException(e);
- }
- }
-
-}