Build Android ORM Framework Opendroid (VI)--Cascade query

Source: Internet
Author: User
Tags case statement switch case

In the previous blog, "Build Android ORM Framework Opendroid (v)--Data Update implementation" We introduced the Opendroid data update process, also in the last time, we opendroid all the operations in the class are covered, the query operation? Not in the opendroid? The query operation is in Opendroid, but is presented in the form of an inner class.
Let's see if you use Opendroid to query the data.

OpenDroid.query.find (Student.class)

OpenDroid.query.columns ("Stuname"). where ("_ID>?", "1"). Limit (1, 4). Order ("_id DESC"). Find (Student.class);  

This is the query method provided by Opendroid, is also the most common cascade query, understand the other ORM framework friends are certainly not unfamiliar with it, but, looking at the second code, we are more than the traditional cascade operation of a method columns (), the method is to set the field to query.
Well, into the focus of our day, through the above code, we find that it is by calling the opendroid of a static field query method to combine the query. Let's take a look at query.

public static Query query = new query ();

This is the query Type field in Opendroid and is instantiated at the time of definition. Let's look at the inner class of query again.

 /** * Query * @author qibin */public static class query {private string[] mcocumns = null;   The field to query private String mwhere = null; The condition of the query private string[] Mwhereargs = null; parameter of the condition of the query private String morder = null; Order statement private String Mlimit;  The Limit statement/** * Sets the field of the query * @param columns field to query * @return Query Object */Public query          Columns (String ... columns) {mcocumns = columns;      return this; }/** * Sets the WHERE condition of the query * @param where WHERE Condition * @param whereargs where parameter * @return query to          Like */Public Query where (string where, String ... whereargs) {mwhere = where;          Mwhereargs = Whereargs;      return this; }/** * Sets the order of the query * @param order Order statement * @return The Query Object */Public query Order (stri          ng order) {morder = order;      return this;      }/** * Set limit for query* @param limit LIMIT statement * @return Query Object */Public query limit (int ... limit) {StringBuilder build          ER = new StringBuilder ();                        Builder.append (Limit[0]);          if (limit.length = = 2) {builder.append (","). Append (limit[1]);                        } Mlimit = Builder.tostring ();      return this; }/** * Query * @param klass mapped bean * @return Query result */public <t extends Opendroid                   > list<t> Find (class<t> Klass) {return crud.query (Klass, Mcocumns, Mwhere, Mwhereargs,      Morder, Mlimit, ssqlitedatabase);      /** * Query data based on ID * @param Klass klass mapped bean * @param ID to query the ID of the data * @return Query results */Public <t extends Opendroid> T find (class<t> klass, int id) {list<t> result = Crud.qu Ery (Klass, Mcocumns, "_id=", new string[] {string.valueof (id)}, NULL, "1", ssqlitedatabase); return result.size () > 0?      Result.get (0): null; } public <t extends Opendroid> list<t> find (class<t> klass, int ... ids) {String          Builder builder = new StringBuilder ("_id in (");          string[] Whereargs = new String[ids.length];                        Buildin (builder, Whereargs, IDS);      Return Crud.query (Klass, Mcocumns, Builder.tostring (), Whereargs, Morder, Mlimit, ssqlitedatabase);      /** * Query with SQL statement * @param SQL SQL statement * @param selectionargs Precompiled parameter * @return */ Public Cursor querybysql (String sql, string[] selectionargs) {return ssqlitedatabase.rawquery (SQL, Selectionargs      ); }  }



In this inner class, the list of 5 fields, the comments have been made clear, in fact, the combination of query statements used.
Looking down, we see familiar methods, these are used in the above introduction, and some of the return value of the method is this, we should be very clear, we want to cascade operation, we must return the current object.
Okay, the first way.

/**  * Set query fields  * @param columns fields to query  * @return Query Object *  /Public  query Columns (String ... columns) {      mcocumns = columns;      return this;  }  

The simple thing is to save the field you want to query, and then return to the current object.

/**  * Set the WHERE condition of the query  * @param where WHERE Condition  * @param whereargs where parameter  * @return Query Object  */ Public Query where (string where, String ... whereargs) {      mwhere = where;      Mwhereargs = Whereargs;      return this;  

The Where method is also simple, preserving the where condition and the parameters of the Where condition.

/**  * Sets the order of the query  * @param order Order Statement  * @return Query Object *  /Public  Query Order (String order) {      morder = order;      return this;  

Well, the same logic (where there is logic!!!) )

/**  * Set limit for query *  @param limit limit statement  * @return Query Object  *  /Public query limit (int ... limit) {      StringBuilder builder = new StringBuilder ();      Builder.append (Limit[0]);                    if (limit.length = = 2) {          builder.append (","). Append (Limit[1]);      }                    Mlimit = Builder.tostring ();                    return this;  

Set limit, this method is still a little bit longer, but not a bit of content, is to combine a limit statement, but here to do an array length of judgment, mainly to fit the limit 1 and limit of the two ways.

/** *  Query  * @param klass mapped bean  * @return Query result */public  <t extends opendroid> list<t& Gt Find (Class<t> Klass) {      return crud.query (Klass, Mcocumns, Mwhere, Mwhereargs, Morder, Mlimit, ssqlitedatabase);  }

This query method directly calls the Crud.query and returns its return value, I believe you see the crud must be familiar with, we navigate to the CRUD query this method to see it.

/** * Query Data * @param klass the class to be mapped * @param the field columns query, NULL takes all * @param where WHERE condition, NULL ignores condition * @param whereargs where parameter, null no argument * @param order order statement, NULL ignores ORDER by * @param limit limit statement, NULL ignores limit * @param DB database handle * @ Return query data */protected static <t extends opendroid> list<t> query (Class<t> Klass, string[] Columns , string where, string[] Whereargs, string order, string limit, Sqlitedatabase db) {list<t> Resultli st = new Arraylist<t> (); Storage result String TableName = Klass.getsimplename ();                Gets the class name (table name) cursor cursor = NULL;          try {cursor = db.query (tableName, columns, where, Whereargs, NULL, NULL, order, limit);      Foreachcursor (Klass, cursor, resultlist);      } catch (Exception e) {e.printstacktrace ();          } finally {if (cursor! = NULL) {cursor.close ();  }} return resultlist; }

There are a bit more parameters, so let's start with the parameters.
The first parameter is a class, it should be very clear, we have to get to the query according to the indication, the next series is to query the field, condition, order statement, limit statement, the last is the database handle we manipulate.
Continue to look at the code, first the new Class A ArrayList, and get the table name to manipulate, next in the try, directly call the Android native API query returned a cursor object, this is the result of our query. Next Call the Foreachcursor method, the results are traversed into the new ArrayList, the query operation is complete!
So let's take a look at the Foreachcursor method.

/** * Traverse Database cursor * @param klass the class to be mapped * @param cursor to traverse * @param resultlist Store returned results * @throws Instantiationexceptio n * @throws illegalaccessexception */private static <t extends opendroid> void Foreachcursor (class<t> klas      s, cursor cursor, list<t> resultlist) throws Instantiationexception, Illegalaccessexception { T T; The reflected instance of String ColumnName; database field name String methodName; Methods name method M; Reflected method for (Cursor.movetofirst ();!  Cursor.isafterlast (); Cursor.movetonext ()) {t = klass.newinstance (); Instantiate for (int i=0;i<cursor.getcolumncount (); i++) {columnName = Cursor.getcolumnname (i) by reflection); /Get database field name try {switch (Cursor.gettype (i)) {case Cursor.field_type_intege R://If the field name is _id, the corresponding method is SetID methodName = columnname.equals ("_id")? "SetId": Getmethodname (cUrsor.getcolumnname (i)); m = Klass.getmethod (MethodName, Int.class); The Reflective method M.invoke (T, Cursor.getint (i));                  Execution method break;                      Case Cursor.FIELD_TYPE_FLOAT:methodName = Getmethodname (Cursor.getcolumnname (i));                      m = Klass.getmethod (MethodName, Float.class);                      M.invoke (t, cursor.getfloat (i));                  Break                      Default:methodname = Getmethodname (Cursor.getcolumnname (i));                      m = Klass.getmethod (MethodName, String.class);                      M.invoke (t, cursor.getstring (i));                  Break              }}catch (Exception e) {e.printstacktrace ();      }} resultlist.add (t); }  }

It's a big long ...
Let's take a little analysis. First look at the parameters, the first two needless to say, the last parameter is to store the results of our traversal, this way in the previous blog has been introduced.
The general look at this method, although very long, but not difficult, the switch case of the statement only need to understand the rest of the understanding.
First we define 4 variables, first of all, a bit of an impression. Then a for loop, the For loop is also very familiar with Android, is to go through the cursor, if you are not clear here, it is recommended to look at the Android native API.
18 Rows, we get an instance of class, and the instantiation is primarily to save the data query in the table to our Java bean.
The next 19 lines, another for loop, what is the loop? Well, here is the loop for all the fields of the row.
20 row to get the field name of the current index.
In the next switch case, we'll just look at the code in the first case statement.
25 line is to put together a setter, but this is a bit special, there is a two mesh operator, I first explain why, remember I have mentioned that the ID is opendroid by default, and do not need us to define the bean field? And we also saw the code to create the _ID field automatically in the source of the analysis creation database, but now there is a problem. We do not have ID field, how to put ID in bean? So in the Opendroid class I've forced to define an ID field, and in the process of using it, you should also find that your bean instance has a GetID and SetID method. Look at the source to prove it:

private int id;  public int getId () {      return ID;  }    public void setId (int id) {      this.id = ID;  }

Knowing this, we will understand this sentence, if the query is the _id field, then we go to call SetID this method, otherwise we call Getmethodname () to put together a setter method based on the field names in the current database.
Well, then, parsing the code, 27~28 the line, reflecting the method we pieced together, and using invoke to execute the method, here, for example, if we want to get the Stuname field, then Student.stuname has a value.
After the current row data has been obtained, the 46 rows of the generated object are added to the ArrayList to be saved.
In summary, the function of this method is to instantiate the corresponding class by reflection and set the value through the setter method in the class.
It also uses a Getmethodname () method, which is simple, which is to cobble together a Setxxx method based on the database field name.

/**  * Build method name based on field name  * @param columnName  * @return *  /public  static string Getmethodname (string ColumnName) {      String methodName = columnName;      MethodName = character.touppercase (Methodname.charat (0)) + methodname.substring (1);      MethodName = "Set" + MethodName;                return methodName;  

Very simple, not much to say, the only thing to note is the 8th line, meaning to capitalize the first letter of the field name.

At this point, the process of a Find method is analyzed, in fact, the rest of the Find method is called the same Crud.query method to query.

/**  * Query data by ID  * @param klass Klass mapped bean  * @param ID to query the ID of the data  * @return  query  Results  */Public & Lt T extends opendroid> t find (class<t> klass, int id) {      list<t> result = Crud.query (Klass, Mcocumns, "_id =? ",               new string[] {string.valueof (ID)}, NULL," 1 ",              ssqlitedatabase);      return result.size () > 0? Result.get (0): null;  

This method calls the Crud.query method to query, but we have determined the condition.

Public <t extends Opendroid> list<t> find (class<t> klass, int ... ids) {      StringBuilder builder = new StringBuilder ("_id in (");      string[] Whereargs = new String[ids.length];      Buildin (builder, Whereargs, IDS);                    Return Crud.query (Klass, Mcocumns, Builder.tostring (), Whereargs, Morder,               Mlimit, ssqlitedatabase);  

The same principle of this method, only need to be multiple IDs, as long as the number of IDs, we are all through the in statement to implement, so called the Buildin method to piece together an in statement, the rest of the same as the other Find method.


Well, so far, Opendroid's query operation we also finished, that is opendroid all crud operations have to go through, that is not opendroid all functions are finished? Of course not, there is our database upgrade program! So the next blog will introduce Opendroid's database upgrade program!


Finally, Opendroid's Open source address: http://git.oschina.net/qibin/OpenDroid

Build Android ORM Framework Opendroid (VI)--Cascade query

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.