Kripton ORM: how to store byte arrays

Abubusoft Blog

Kripton ORM: how to store byte arrays

Stackoverflow is always a good place to get ideas to write posts. Today I answer to this question. The original question is about using Room Library. But I want to change the question: how can I persist a byte array using Kripton ORM Library?

With kripton, you can easily manage byte[] fields. Just to show you how to do:

I define a bean FileBean binded to a table file_bean:

@BindTable
public class FileBean {
  public long id;
  public Date date;
  public String title;
  public String text;
  public String address;
  public byte[] image;
}

A DAO definition:

@BindDao(FileBean.class)
public interface FileBeanDao {
 
  @BindSqlInsert
  long insert(FileBean bean);
 
  @BindSqlSelect(where="id=${id}")
  List selectById(long id);
}

And a data source interface:

@BindDataSource(daoSet={FileBeanDao.class}, fileName = "example.db")
public interface ExampleDataSource {
 
}

After project configuration to use Kripton and its annotation processor in Gradle config file:

dependencies {
    ...
    // annotation processors
    annotationProcessor"com.abubusoft:kripton-processor:6.0.0"
    ...
    // dependencies
    implementation "com.abubusoft:kripton-android-library:6.0.0"
    ...
}

Kripton will generate for you a DAO implementation like this (Javadoc too):

/**
 * <p>
 * DAO implementation for entity <code>FileBean</code>, based on interface <code>FileBeanDao</code>
 * </p>
 *
 *  @see FileBean
 *  @see FileBeanDao
 *  @see FileBeanTable
 */
public class FileBeanDaoImpl extends AbstractDao implements FileBeanDao {
  public FileBeanDaoImpl(BindExampleDataSource dataSet) {
    super(dataSet);
  }
 
  /**
   * <p>SQL insert:</p>
   * <pre>INSERT INTO file_bean (date, title, text, address, image) VALUES (${bean.date}, ${bean.title}, ${bean.text}, ${bean.address}, ${bean.image})</pre>
   *
   * <p><code>bean.id</code> is automatically updated because it is the primary key</p>
   *
   * <p><strong>Inserted columns:</strong></p>
   * <dl>
   *    <dt>date</dt><dd>is mapped to <strong>${bean.date}</strong></dd>
   *    <dt>title</dt><dd>is mapped to <strong>${bean.title}</strong></dd>
   *    <dt>text</dt><dd>is mapped to <strong>${bean.text}</strong></dd>
   *    <dt>address</dt><dd>is mapped to <strong>${bean.address}</strong></dd>
   *    <dt>image</dt><dd>is mapped to <strong>${bean.image}</strong></dd>
   * </dl>
   *
   * @param bean
   *    is mapped to parameter <strong>bean</strong>
   *
   * @return <strong>id</strong> of inserted record
   */
  @Override
  public long insert(FileBean bean) {
    ContentValues contentValues=contentValues();
    contentValues.clear();
 
    if (bean.date!=null) {
      contentValues.put("date", DateUtils.write(bean.date));
    } else {
      contentValues.putNull("date");
    }
    if (bean.title!=null) {
      contentValues.put("title", bean.title);
    } else {
      contentValues.putNull("title");
    }
    if (bean.text!=null) {
      contentValues.put("text", bean.text);
    } else {
      contentValues.putNull("text");
    }
    if (bean.address!=null) {
      contentValues.put("address", bean.address);
    } else {
      contentValues.putNull("address");
    }
    if (bean.image!=null) {
      contentValues.put("image", bean.image);
    } else {
      contentValues.putNull("image");
    }
 
    // log for insert -- BEGIN 
    StringBuffer _columnNameBuffer=new StringBuffer();
    StringBuffer _columnValueBuffer=new StringBuffer();
    String _columnSeparator="";
    for (String columnName:contentValues.keySet()) {
      _columnNameBuffer.append(_columnSeparator+columnName);
      _columnValueBuffer.append(_columnSeparator+":"+columnName);
      _columnSeparator=", ";
    }
    Logger.info("INSERT INTO file_bean (%s) VALUES (%s)", _columnNameBuffer.toString(), _columnValueBuffer.toString());
 
    // log for content values -- BEGIN
    Object _contentValue;
    for (String _contentKey:contentValues.keySet()) {
      _contentValue=contentValues.get(_contentKey);
      if (_contentValue==null) {
        Logger.info("==> :%s = <null>", _contentKey);
      } else {
        Logger.info("==> :%s = '%s' (%s)", _contentKey, StringUtils.checkSize(_contentValue), _contentValue.getClass().getCanonicalName());
      }
    }
    // log for content values -- END
    // log for insert -- END 
 
    long result = database().insert("file_bean", null, contentValues);
    bean.id=result;
 
    return result;
  }
 
  /**
   * <h2>Select SQL:</h2>
   *
   * <pre>SELECT id, date, title, text, address, image FROM file_bean WHERE id=${id}</pre>
   *
   * <h2>Projected columns:</h2>
   * <dl>
   *    <dt>id</dt><dd>is associated to bean's property <strong>id</strong></dd>
   *    <dt>date</dt><dd>is associated to bean's property <strong>date</strong></dd>
   *    <dt>title</dt><dd>is associated to bean's property <strong>title</strong></dd>
   *    <dt>text</dt><dd>is associated to bean's property <strong>text</strong></dd>
   *    <dt>address</dt><dd>is associated to bean's property <strong>address</strong></dd>
   *    <dt>image</dt><dd>is associated to bean's property <strong>image</strong></dd>
   * </dl>
   *
   * <h2>Query's parameters:</h2>
   * <dl>
   *    <dt>${id}</dt><dd>is binded to method's parameter <strong>id</strong></dd>
   * </dl>
   *
   * @param id
   *    is binded to <code>${id}</code>
   * @return collection of bean or empty collection.
   */
  @Override
  public List<FileBean> selectById(long id) {
    StringBuilder _sqlBuilder=getSQLStringBuilder();
    _sqlBuilder.append("SELECT id, date, title, text, address, image FROM file_bean");
    // generation CODE_001 -- BEGIN
    // generation CODE_001 -- END
    ArrayList<String> _sqlWhereParams=getWhereParamsArray();
 
    // manage WHERE arguments -- BEGIN
 
    // manage WHERE statement
    String _sqlWhereStatement=" WHERE id=?";
    _sqlBuilder.append(_sqlWhereStatement);
 
    // manage WHERE arguments -- END
 
    // build where condition
    _sqlWhereParams.add(String.valueOf(id));
    String _sql=_sqlBuilder.toString();
    String[] _sqlArgs=_sqlWhereParams.toArray(new String[_sqlWhereParams.size()]);
    Logger.info(_sql);
 
    // log for where parameters -- BEGIN
    int _whereParamCounter=0;
    for (String _whereParamItem: _sqlWhereParams) {
      Logger.info("==> param%s: '%s'",(_whereParamCounter++), StringUtils.checkSize(_whereParamItem));
    }
    // log for where parameters -- END
    try (Cursor cursor = database().rawQuery(_sql, _sqlArgs)) {
      Logger.info("Rows found: %s",cursor.getCount());
 
      LinkedList<FileBean> resultList=new LinkedList<FileBean>();
      FileBean resultBean=null;
 
      if (cursor.moveToFirst()) {
 
        int index0=cursor.getColumnIndex("id");
        int index1=cursor.getColumnIndex("date");
        int index2=cursor.getColumnIndex("title");
        int index3=cursor.getColumnIndex("text");
        int index4=cursor.getColumnIndex("address");
        int index5=cursor.getColumnIndex("image");
 
        do
         {
          resultBean=new FileBean();
 
          resultBean.id=cursor.getLong(index0);
          if (!cursor.isNull(index1)) { resultBean.date=DateUtils.read(cursor.getString(index1)); }
          if (!cursor.isNull(index2)) { resultBean.title=cursor.getString(index2); }
          if (!cursor.isNull(index3)) { resultBean.text=cursor.getString(index3); }
          if (!cursor.isNull(index4)) { resultBean.address=cursor.getString(index4); }
          if (!cursor.isNull(index5)) { resultBean.image=cursor.getBlob(index5); }
 
          resultList.add(resultBean);
        } while (cursor.moveToNext());
      }
 
      return resultList;
    }
  }
}

Kripton, how you can see from generated code, natively persists byte[] fields into BLOB type columns. No special operation or configuration is required.

Quite easy no? For any question does not hesitate to comment on this post.

For more information about Kripton Persistence Library:

 

Leave a Reply

Your email address will not be published. Required fields are marked *