Package com.reflectiondao.dao

Source Code of com.reflectiondao.dao.Dao

package com.reflectiondao.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

import com.reflectiondao.model.IModel;
import com.reflectiondao.strategy.DaoQueryStrategy;

/**
* This is abstract generic Dao class. When using this in a new project, extend
* this class:
*
* <pre>
* public class ProjectDao&lt;T extends IModel&gt; extends Dao&lt;T&gt; {
*
*   private static String connectionType = &quot;jdbc:sqlite&quot;;
*
*   private static String database = &quot;project.db3&quot;;
*
*   private static String jdbcClassName = &quot;org.sqlite.JDBC&quot;;
*
*   protected ProjectDao(Class&lt;T&gt; c) {
*     super(c, connectionType, database, jdbcClassName);
*   }
* }
* </pre>
*
* This class houses all the generalized create, select, selectAll, etc methods
* that are normally used to talk to the database. If you want to add new base
* methods for your DAOs, just add them to the class that extends this class.
*
* Once this class has been extended, you can then make Dao instances from it.
*
*
* @param <T>
*            the generic type that extends IModel
*/
public abstract class Dao<T extends IModel> {

  /** A static HashMap of the create statements. Acts as a cache. */
  protected static Map<Class<? extends IModel>, String> createStatements = new HashMap<>();

  /** A static HashMap of the select statements. Acts as a cache. */
  protected static Map<Class<? extends IModel>, String> selectStatements = new HashMap<>();

  /** A static HashMap of the select statements. Acts as a cache. */
  protected static Map<Class<? extends IModel>, String> deleteStatements = new HashMap<>();

  /** A static HashMap of the select statements. Acts as a cache. */
  protected static Map<Class<? extends IModel>, String> updateStatements = new HashMap<>();

  /** A static HashMap of the select all statements. Acts as a cache. */
  protected static Map<Class<? extends IModel>, String> selectAllStatements = new HashMap<>();

  /** A static HashMap of the delete all statements. Acts as a cache. */
  protected static Map<Class<? extends IModel>, String> deleteAllStatements = new HashMap<>();

  /** The data source. */
  protected DriverManagerDataSource dataSource = new DriverManagerDataSource();

  /** The strat. */
  protected DaoQueryStrategy<T> strat = null;

  /** The type. */
  private Class<T> type;

  /**
   * Instantiates a new dao.
   *
   * @param cName
   *            the c name
   * @param connectionType
   *            the connection type
   * @param database
   *            the database
   * @param jdbcClassName
   *            the jdbc class name
   */
  protected Dao(Class<T> cName, String connectionType, String database,
      String jdbcClassName) {
    this.type = cName;
    dataSource.setDriverClassName(jdbcClassName);
    dataSource.setUrl(connectionType + ":" + database);

    this.strat = new DaoQueryStrategy<T>(cName);
  }

  /**
   * Instantiates a new dao using a DataSource.
   *
   * @param cName
   *            the c name
   * @param db
   *            the db
   */
  protected Dao(Class<T> cName, DriverManagerDataSource db) {
    this.dataSource = db;

    this.strat = new DaoQueryStrategy<T>(cName);
  }

  /**
   * Sets the data source.
   *
   * @param ds
   *            the new data source
   */
  public void setDataSource(DataSource ds) {
    this.dataSource = (DriverManagerDataSource) ds;
  }

  /**
   * Creates a instance of T t in the database. This uses Reflection for the
   * first usage; but caches the create statement, speeding it up slightly
   * after the first run.
   *
   * @param t
   *            the t
   * @return the t
   */
  public T create(final T t) {
    JdbcTemplate insert = new JdbcTemplate(dataSource);

    final Class<T> type = this.type;
    final String createStatement = Dao.createStatements.get(type);

    KeyHolder holder = new GeneratedKeyHolder();
    try {
      // Create a prepared statement.
      insert.update(new PreparedStatementCreator() {

        @Override
        public PreparedStatement createPreparedStatement(
            Connection connection) throws SQLException {

          String createStatementToUse = null;

          // Use the cached value if we have one, otherwise, generate
          // one and cache it.
          if (createStatement != null) {
            createStatementToUse = createStatement;
          } else {
            createStatementToUse = strat.generateCreateStatement(t);

            Dao.createStatements.put(type, createStatementToUse);
          }

          PreparedStatement ps = connection.prepareStatement(
              createStatementToUse,
              Statement.RETURN_GENERATED_KEYS);

          strat.prepareStatement(ps, t);

          return ps;
        }

      }, holder);
    } catch (Exception e) {
      e.printStackTrace();
    }

    int id = holder.getKey().intValue();

    // Get the T that we just inserted.
    return this.select(id);
  }

  /**
   * Selects an instance of T from the database with a primary key of id.
   *
   * @param id
   *            the id
   * @return the t
   */
  public T select(int id) {
    JdbcTemplate select = new JdbcTemplate(dataSource);

    final Class<T> type = this.type;
    final String selectStatement = Dao.selectStatements.get(type);
    String selectStatementToUse = null;

    // Use the cached value if we have one, otherwise, generate
    // one and cache it.
    if (selectStatement != null) {
      selectStatementToUse = selectStatement;
    } else {
      selectStatementToUse = strat.createSelectStatement();

      Dao.selectStatements.put(type, selectStatementToUse);
    }

    List<T> results = select.query(selectStatementToUse,
        new Object[] { id }, new TemplateRowMapper<T>(type));

    if (results.size() > 0) {
      return results.get(0);
    }

    return null;
  }

  /**
   * Selects all T from the database.
   *
   * @return the list
   */
  public List<T> selectAll() {
    JdbcTemplate select = new JdbcTemplate(dataSource);

    final Class<T> type = this.type;
    final String selectAllStatement = Dao.selectAllStatements.get(type);
    String selectAllStatementToUse = null;

    // Use the cached value if we have one, otherwise, generate
    // one and cache it.
    if (selectAllStatement != null) {
      selectAllStatementToUse = selectAllStatement;
    } else {
      selectAllStatementToUse = strat.createSelectAllStatement();

      Dao.selectAllStatements.put(type, selectAllStatementToUse);
    }

    List<T> results = select.query(selectAllStatementToUse,
        new Object[] {}, new TemplateRowMapper<T>(type));

    return results;

  }

  /**
   * Deletes all T from the database.
   */
  public void deleteAll() {
    JdbcTemplate delete = new JdbcTemplate(dataSource);

    final Class<T> type = this.type;
    final String deleteAllStatement = Dao.deleteAllStatements.get(type);
    String deleteAllStatementToUse = null;

    // Use the cached value if we have one, otherwise, generate
    // one and cache it.
    if (deleteAllStatement != null) {
      deleteAllStatementToUse = deleteAllStatement;
    } else {
      deleteAllStatementToUse = strat.createDeleteAllStatement();

      Dao.deleteAllStatements.put(type, deleteAllStatementToUse);
    }

    delete.update(deleteAllStatementToUse);
  }

  /**
   * Deletes an instance of T from the database based on the Key.
   *
   * @param t
   *            the t
   */
  public void delete(T t) {
    JdbcTemplate delete = new JdbcTemplate(dataSource);

    final Class<T> type = this.type;
    final String deleteStatement = Dao.deleteStatements.get(type);
    String deleteStatementToUse = null;

    // Use the cached value if we have one, otherwise, generate
    // one and cache it.
    if (deleteStatement != null) {
      deleteStatementToUse = deleteStatement;
    } else {
      deleteStatementToUse = strat.createDeleteStatement(t);

      Dao.deleteStatements.put(type, deleteStatementToUse);
    }

    delete.update(deleteStatementToUse,
        new Object[] { strat.getPrimaryKeyValue(t) });
  }

  /**
   * Update.
   *
   * @param t
   *            the t
   * @return the t
   */
  public T update(T t) {
    JdbcTemplate update = new JdbcTemplate(dataSource);

    final Class<T> type = this.type;
    final String updateStatement = Dao.updateStatements.get(type);
    String updateStatementToUse = null;

    // Use the cached value if we have one, otherwise, generate
    // one and cache it.
    if (updateStatement != null) {
      updateStatementToUse = updateStatement;
    } else {
      updateStatementToUse = strat.createUpdateStatement();

      Dao.updateStatements.put(type, updateStatementToUse);
    }

    update.update(updateStatementToUse, strat.createUpdateObject(t));

    T tNew = select((Integer) strat.getPrimaryKeyValue(t));

    return tNew;

  }

}
TOP

Related Classes of com.reflectiondao.dao.Dao

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.