All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.abubusoft.kripton.android.annotation.BindSqlSelect Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright 2015, 2017 Francesco Benincasa ([email protected]).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package com.abubusoft.kripton.android.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 

* Allows to query a database table. When you define the query through * interface's method you can define query parameter by a DAO's associated bean * instance, or directly with fields. *

* *

Query parameters

*

* Almost all parameters used in method can be used as query parameter. *

* *
 * @BindSqlSelect(where = "name=${name} and surname=${surname}")
 * Person selectOne(String name, BindSqlParam("surname") String temp);
 * 
* *

* Parameters of where condition are linked to method parameters * with the syntax ${<name of parameter>} *

* *

Return query result

* *

* There are many return type allowed for method which define a query: *

*
    *
  • a DAO's associated bean instance
  • *
  • list of associated bean
  • *
  • set of associated bean
  • *
  • Cursor: it is possible to wrap cursor with the cursor wrapper generated * for bean associated to DAO. For example, given a Person and * PersonDAO, will be generated BindPersonCursor
  • *
  • It is possible to set return type as Void and define a * OnReadBeanListener which a method * void onRead(E bean, int row, int rowCount) allow to manage each * row of result with only one bean (reused) instance.
  • *
  • It is possible to set return type as Void and define a * OnReadCursorListener which a method * void onRead(Cursor cursor) allows to manage resultset iteration * with a cursor.
  • *
* *

Attributes

*
    *
  • distinct: if true insert distinct clause in SQL * statement.
  • *
  • excludedFields: properties to exclude from the SELECT * statement.
  • *
  • fields: properties to include into the SELECT * statement.
  • *
  • groupBy: GROUP BY statement. It is not necessary to * include GROUP BY words in statements, they are added automatically.
  • *
  • having: HAVING statement. It is not necessary to include * HAVING words in statements, they are added automatically.
  • *
  • jql: allows specifying the entire query with JQL.
  • *
  • orderBy: ORDER BY statement. It is not necessary to * include ORDER BY words in statements, they are added automatically.
  • *
  • pageSize: If the method returns a paginated result, this * attribute allows to specify the size of the page.
  • *
  • where: WHERE statement. It is not necessary to include * WHERE words in statements, they have added automatically.
  • *
* *

Query parameters

*

* Almost all parameters used in method can be used as query parameter. *

* *
 * @BindSqlSelect(where = "name=${name} and surname=${surname}")
 * Person selectOne(String name, @BindSqlParam("surname") String temp);
 * 
*

* Parameters of where condition are linked to method parameters with the syntax * ${name of parameter} *

* *

Return query result

*

* There are many return type allowed for method which define a query: *

* *
    *
  • a DAO's associated bean instance
  • *
  • list of associated bean
  • *
  • set of associated bean *
  • Cursor: it is possible to wrap cursor with the cursor wrapper generated * for bean associated to DAO. For example, given a Person and PersonDAO, will * be generated BindPersonCursor. *
  • It is possible to set return type as Void and define a OnReadBeanListener * which a method void onRead(E bean, int row, int rowCount) allow to manage * each row of result with only one bean (reused) instance. *
  • It is possible to set return type as Void and define a * OnReadCursorListener which a method void onRead(Cursor cursor) allows to * manage resultset iteration with a cursor. *
  • LiveData
  • *
  • Paginated result
  • *
* *

Example

*

* Given a Java class definition: *

* *
 * @BindType
 * public class Person {
 * 	public long id;
 * 	public String name;
 * 	public String surname;
 * 	public String birthCity;
 * 	public Date birthDay;
 * }
 * 
*

* And a associated DAO definition: *

* *
 * @BindDao(Person.class)
 * public interface PersonDAO {
 * 	@BindSqlSelect(orderBy = "name")
 * 	List<Person> selectAll();
 * 
 * 	@BindSqlSelect(where = "name like ${name} || '%%' ", orderBy = "name")
 * 	Set<Person> selectAll(String name);
 * 
 * 	@BindSqlSelect(orderBy = "name")
 * 	void selectBeanListener(OnReadBeanListener<Person> beanListener);
 * 
 * 	@BindSqlSelect(orderBy = "name")
 * 	void selectCursorListener(OnReadCursorListener cursorListener);
 * }
 * 
*

* When Kripton annotation processor examine BindDao annotation, it * generates the following DAO implementations: *

* *
 * public class PersonDAOImpl extends AbstractDao implements PersonDAO {
 * 	public PersonDAOImpl(BindPersonDataSource dataSet) {
 * 		super(dataSet);
 * 	}
 * 
 * 	@Override
 * 	public List<Person> selectAll() {
 * 		// build where condition
 * 		String[] args = {};
 * 
 * 		Logger.info(StringUtils.formatSQL("SELECT id, name, surname, birth_city, birth_day FROM person WHERE 1=1 ORDER BY name"), (Object[]) args);
 * 		Cursor cursor = database().rawQuery("SELECT id, name, surname, birth_city, birth_day FROM person WHERE 1=1 ORDER BY name", args);
 * 		Logger.info("Rows found: %s", cursor.getCount());
 * 
 * 		LinkedList<Person> resultList = new LinkedList<Person>();
 * 		Person resultBean = null;
 * 
 * 		if (cursor.moveToFirst()) {
 * 
 * 			int index0 = cursor.getColumnIndex("id");
 * 			int index1 = cursor.getColumnIndex("name");
 * 			int index2 = cursor.getColumnIndex("surname");
 * 			int index3 = cursor.getColumnIndex("birth_city");
 * 			int index4 = cursor.getColumnIndex("birth_day");
 * 
 * 			do {
 * 				resultBean = new Person();
 * 
 * 				if (!cursor.isNull(index0)) {
 * 					resultBean.id = cursor.getLong(index0);
 * 				}
 * 				if (!cursor.isNull(index1)) {
 * 					resultBean.name = cursor.getString(index1);
 * 				}
 * 				if (!cursor.isNull(index2)) {
 * 					resultBean.surname = cursor.getString(index2);
 * 				}
 * 				if (!cursor.isNull(index3)) {
 * 					resultBean.birthCity = cursor.getString(index3);
 * 				}
 * 				if (!cursor.isNull(index4)) {
 * 					resultBean.birthDay = DateUtils.read(cursor.getString(index4));
 * 				}
 * 
 * 				resultList.add(resultBean);
 * 			} while (cursor.moveToNext());
 * 		}
 * 		cursor.close();
 * 
 * 		return resultList;
 * 	}
 * 
 * 	@Override
 * 	public Set<Person> selectAll(String name) {
 * 		// build where condition
 * 		String[] args = { (name == null ? null : name) };
 * 
 * 		Logger.info(StringUtils.formatSQL("SELECT id, name, surname, birth_city, birth_day FROM person WHERE name like '%s' || \'%%\' ORDER BY name"), (Object[]) args);
 * 		Cursor cursor = database().rawQuery("SELECT id, name, surname, birth_city, birth_day FROM person WHERE name like ? || \'%%\' ORDER BY name", args);
 * 		Logger.info("Rows found: %s", cursor.getCount());
 * 
 * 		HashSet<Person> resultList = new HashSet<Person>();
 * 		Person resultBean = null;
 * 
 * 		if (cursor.moveToFirst()) {
 * 
 * 			int index0 = cursor.getColumnIndex("id");
 * 			int index1 = cursor.getColumnIndex("name");
 * 			int index2 = cursor.getColumnIndex("surname");
 * 			int index3 = cursor.getColumnIndex("birth_city");
 * 			int index4 = cursor.getColumnIndex("birth_day");
 * 
 * 			do {
 * 				resultBean = new Person();
 * 
 * 				if (!cursor.isNull(index0)) {
 * 					resultBean.id = cursor.getLong(index0);
 * 				}
 * 				if (!cursor.isNull(index1)) {
 * 					resultBean.name = cursor.getString(index1);
 * 				}
 * 				if (!cursor.isNull(index2)) {
 * 					resultBean.surname = cursor.getString(index2);
 * 				}
 * 				if (!cursor.isNull(index3)) {
 * 					resultBean.birthCity = cursor.getString(index3);
 * 				}
 * 				if (!cursor.isNull(index4)) {
 * 					resultBean.birthDay = DateUtils.read(cursor.getString(index4));
 * 				}
 * 
 * 				resultList.add(resultBean);
 * 			} while (cursor.moveToNext());
 * 		}
 * 		cursor.close();
 * 
 * 		return resultList;
 * 	}
 * 
 * 	@Override
 * 	public void selectBeanListener(OnReadBeanListener<Person> beanListener) {
 * 		// build where condition
 * 		String[] args = {};
 * 
 * 		Logger.info(StringUtils.formatSQL("SELECT id, name, surname, birth_city, birth_day FROM person WHERE 1=1 ORDER BY name"), (Object[]) args);
 * 		Cursor cursor = database().rawQuery("SELECT id, name, surname, birth_city, birth_day FROM person WHERE 1=1 ORDER BY name", args);
 * 		Logger.info("Rows found: %s", cursor.getCount());
 * 		Person resultBean = new Person();
 * 		try {
 * 			if (cursor.moveToFirst()) {
 * 
 * 				int index0 = cursor.getColumnIndex("id");
 * 				int index1 = cursor.getColumnIndex("name");
 * 				int index2 = cursor.getColumnIndex("surname");
 * 				int index3 = cursor.getColumnIndex("birth_city");
 * 				int index4 = cursor.getColumnIndex("birth_day");
 * 
 * 				int rowCount = cursor.getCount();
 * 				do {
 * 					// reset mapping
 * 					resultBean.id = 0L;
 * 					resultBean.name = null;
 * 					resultBean.surname = null;
 * 					resultBean.birthCity = null;
 * 					resultBean.birthDay = null;
 * 
 * 					// generate mapping
 * 					if (!cursor.isNull(index0)) {
 * 						resultBean.id = cursor.getLong(index0);
 * 					}
 * 					if (!cursor.isNull(index1)) {
 * 						resultBean.name = cursor.getString(index1);
 * 					}
 * 					if (!cursor.isNull(index2)) {
 * 						resultBean.surname = cursor.getString(index2);
 * 					}
 * 					if (!cursor.isNull(index3)) {
 * 						resultBean.birthCity = cursor.getString(index3);
 * 					}
 * 					if (!cursor.isNull(index4)) {
 * 						resultBean.birthDay = DateUtils.read(cursor.getString(index4));
 * 					}
 * 
 * 					beanListener.onRead(resultBean, cursor.getPosition(), rowCount);
 * 				} while (cursor.moveToNext());
 * 			}
 * 		} finally {
 * 			if (!cursor.isClosed()) {
 * 				cursor.close();
 * 			}
 * 		}
 * 	}
 * 
 * 	@Override
 * 	public void selectCursorListener(OnReadCursorListener cursorListener) {
 * 		// build where condition
 * 		String[] args = {};
 * 
 * 		Logger.info(StringUtils.formatSQL("SELECT id, name, surname, birth_city, birth_day FROM person WHERE 1=1 ORDER BY name"), (Object[]) args);
 * 		Cursor cursor = database().rawQuery("SELECT id, name, surname, birth_city, birth_day FROM person WHERE 1=1 ORDER BY name", args);
 * 		Logger.info("Rows found: %s", cursor.getCount());
 * 
 * 		try {
 * 			if (cursor.moveToFirst()) {
 * 
 * 				do {
 * 					cursorListener.onRead(cursor);
 * 				} while (cursor.moveToNext());
 * 			}
 * 		} finally {
 * 			if (!cursor.isClosed()) {
 * 				cursor.close();
 * 			}
 * 		}
 * 	}
 * }
 * 
*

* So, the code to execute query selection: *

* *
 * // open database
 * instance.openReadOnlyDatabase();
 * 
 * // select 1
 * Set<Person> list = instance.getPersonDAO().selectAll("name");
 * 
 * // select 2
 * instance.getPersonDAO().selectBeanListener(new OnReadBeanListener<Person>() {
 * 
 * 	@Override
 * 	public void onRead(Person bean, int row, int rowCount) {
 * 		// work with
 * 
 * 	}
 * });
 * 
 * // select 3
 * instance.getPersonDAO().selectCursorListener(new OnReadCursorListener() {
 * 
 * 	@Override
 * 	public void onRead(Cursor cursor) {
 * 		// work directly with cursor
 * 
 * 	}
 * });
 * 
 * // close database
 * instance.close();
 * 
* * @author Francesco Benincasa ([email protected]) * @since 05/mag/2016 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface BindSqlSelect { /** * if true, set distinct clause. * * @return distinct clause */ boolean distinct() default false; /** * properties to include into SELECT command. * * @return property's names to include */ String[] fields() default {}; /** * properties to exclude from SELECT statement. * * @return property's names to exclude */ String[] excludedFields() default {}; /** * where condition. * * @return where condition */ String where() default ""; /** * having statement. * * @return having statement */ String having() default ""; /** * having statement. * * @return groupBy statement */ String groupBy() default ""; /** * order statement. * * @return order statement */ String orderBy() default ""; /** *

* Allow to define limit for query result. Default no limit is defined. *

* * @return the int */ int pageSize() default 0; /** * *

* JQL value. With this attribute, it is possibile to specify directly the * JQL code. JQL means that you can write SQL using field's names and class * name indeed of column and table names. Moreover, it is possibile to * specify where to use the dynamic parts of query through dynamic * statements like DYNAMIC_WHERE, DYNAMIC_ORDER_BY, DYNAMIC_PAGE_SIZE, * DYNAMIC_PAGE_OFFSET, encapsulated in #{ dynamic-part-name } *

* *

* For example, for a select statement, you can write: *

* *
	 * SELECT * FROM media WHERE mediaId IN (SELECT mediaId FROM fav WHERE #{DYNAMIC_WHERE}) ORDER BY indx DESC LIMIT 0, 100
	 * 
* * If you use this attribute, no other attributes can be defined for * the annotation. * * @return JQL code specified by user */ String jql() default ""; /** *

* Used to specify which queries need to be invoked to fill fields that * represent relation with other entities. *

* * @return set of selects used to fill fields defined as relation * */ BindSqlChildSelect[] childrenSelects() default {}; }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy