This example uses SQLite as the data access carrier.
In "sharedpreferences", the automatic storage principle of known data is to use the Java reflection method to obtain the field in the data entity class for storage.
When using SQLite as the data access carrier, we need to solve the following problem: how to indicate that a field in the class is a primary key (primary key.
To solve this problem, Java annotation (inner note) is introduced and used here ). Annotation can retain some custom annotation information, which can be obtained after compilation or even by JVM runtime. For more information, see [Java] annotation (inner note) instance 1.
The code in this example implements a mark annotation (Mark inner Note), which is used to modify the field to indicate it as the primary key.
Keywords in SQL statements such as "order" and "group" should be avoided when naming attributes of object classes. Otherwise, the following exception may occur ):
Android. database. SQLite. sqliteexception:Near "order": syntax error (Code 1 ):, While compiling: Create Table if not exists emopackage (_ id integer primary key autoincrement, EPID integer unique, Name text,Order integer, Price
Integer)
The modified primary key will affect the automatically generated SQL statement. The following code:
/** Create a table based on the class structure. */Private string gettablebuildingsql (class <?> Clazz) {stringbuilder strbuilder = new stringbuilder ("create table if not exists"); strbuilder. append (clazz. getsimplename (); strbuilder. append ("("); // getdeclaredfields (): only obtain the fields declared in this type of file // getfields (): obtains the field [] arrfield = clazz. getfields (); For (INT I = arrfield. length-1; I> = 0; I --) {field F = arrfield [I]; string type = types. get (F. getType (); If (type = NULL) {continue;} else {strbuilder. append (F. getname () + "" + type); If (F. isannotationpresent (primary. class) {strbuilder. append ("primary key");} if (I> 0) {strbuilder. append (",") ;}} strbuilder. append (")"); Return strbuilder. tostring ();}
The rest of the code is a common SQLite operation and is consistent with the processing method in "sharedpreferences. Do not repeat it.
This article is sodino all, reprint please note the Source: http://blog.csdn.net/sodino/article/details/7996088
Code: lab. sodino. autosave. annotation. Primary
package lab.sodino.autosave.annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface primary {}
Lab. sodino. autosave. DB. dbhelper
Package lab. sodino. autosave. DB; import Java. io. file; import Java. lang. reflect. field; import Java. util. hashmap; import Java. util. map; import lab. sodino. autosave. goodsbean; import lab. sodino. autosave. logout; import lab. sodino. autosave. annotation. primary; import android. content. context; import android. database. cursor; import android. database. SQLite. sqlitedatabase; import android. database. SQLite. sqliteopenhelper; Public class dbhelper extends sqliteopenhelper {private sqlitedatabase sqldb; public static final int version = 1; public static final map <class <?>, String> types; static {types = new hashmap <class <?>, String> (); types. put (byte. class, "Byte"); types. put (Boolean. class, "integer"); types. put (short. class, "short"); types. put (Int. class, "integer"); types. put (Long. class, "long"); types. put (string. class, "text"); types. put (byte []. class, "blob"); types. put (float. class, "float"); // realtypes. put (double. class, "double"); // real} public dbhelper (context) {super (context, context. getpackagename (), null, VE Rsion); file dbfile = context. getdatabasepath (context. getpackagename (); If (dbfile. exists () = false) {logout. out (this, "dbfile does not exist. "); // call oncreate () and onupgrade () to create the getwritabledatabase (); // initalldbitem (); close (); logout. out (this, "initdb finished !!! ");} Else {logout. out (this, "dbfile does exist. ") ;}} public void opendbhelper () {sqldb = getwritabledatabase ();} public void close () {If (sqldb! = NULL) {sqldb. close ();} super. close () ;}@ overridepublic void oncreate (sqlitedatabase dB) {string sqltablebuilding = gettablebuildingsql (goodsbean. class); logout. out (this, "SQL [" + sqltablebuilding + "]" )mongodb.exe csql (sqltablebuilding);}/** create a table based on the class structure. */Private string gettablebuildingsql (class <?> Clazz) {stringbuilder strbuilder = new stringbuilder ("create table if not exists"); strbuilder. append (clazz. getsimplename (); strbuilder. append ("("); // getdeclaredfields (): only obtain the fields declared in this type of file // getfields (): obtains the field [] arrfield = clazz. getfields (); For (INT I = arrfield. length-1; I> = 0; I --) {field F = arrfield [I]; string type = types. get (F. getType (); If (type = NULL) {continue;} else {strbuilder. append (F. getname () + "" + type); If (F. isannotationpresent (primary. class) {strbuilder. append ("primary key");} if (I> 0) {strbuilder. append (",") ;}} strbuilder. append (")"); Return strbuilder. tostring () ;}@ overridepublic void onupgrade (sqlitedatabase dB, int oldversion, int newversion) {logout. out (this, "onupgrade"); string SQL = "Drop table if exists" + goodsbean.class.getsimplename(mongomongodb.exe csql (SQL);} public int insert (goodsbean bean) {int ROW =-1; row = (INT) sqldb. insert (goodsbean. class. getsimplename (), null, goodsbean. translate2contentvalues (bean); logout. out (this, "ROW =" + row); Return row;} public goodsbean query () {cursor = sqldb. rawquery ("select * from" + goodsbean. class. getsimplename (), null); goodsbean bean = goodsbean. cursor2goodsbean (cursor); cursor. close (); Return bean ;}}
Lab. sodino. autosave. actautosave
package lab.sodino.autosave;import lab.sodino.autosave.db.DBHelper;import lab.sodino.autosave_sqlite.R;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;public class ActAutoSave extends Activity implements OnClickListener {private DBHelper dbHelper;private Button btnAction;private GoodsBean goodsBean;private TextView txtDetail, txtRead;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.act_auto_save);LogOut.out(this, "onCreate");dbHelper = new DBHelper(this);btnAction = (Button) findViewById(R.id.btnAction);btnAction.setOnClickListener(this);txtDetail = (TextView) findViewById(R.id.txtDetail);txtRead = (TextView) findViewById(R.id.txtRead);goodsBean = GoodsBean.newInstance();txtDetail.setText(goodsBean.toString());}public void onClick(View v) {if (v == btnAction) {doSave(goodsBean);GoodsBean beanRead = doRead();showReadBean(beanRead);}}private void showReadBean(GoodsBean bean) {txtRead.setText(bean.toString());}private GoodsBean doRead() {dbHelper.openDBHelper();GoodsBean bean = dbHelper.query();return bean;}private void doSave(GoodsBean bean) {dbHelper.openDBHelper();dbHelper.insert(bean);dbHelper.close();}}
Lab. sodino. autosave. goodsbean
Package lab. sodino. autosave; import Java. lang. reflect. field; import android. content. contentvalues; import android. database. cursor; import lab. sodino. autosave. annotation. primary; public class goodsbean {@ primary/** indicates the primary key */public long _ id; Public string name; Public int price; Public Boolean ispaid;/** for testing. */Public byte testbyte; Public byte [] arrbyte;/** for testing. */Public short testshort; public float cicle; Public double testdouble; Public String tostring () {stringbuffer strbuffer = new stringbuffer (); strbuffer. append ("_ id [" + _ ID + "] \ n"); strbuffer. append ("name [" + name + "] \ n"); strbuffer. append ("price [" + Price + "] \ n"); strbuffer. append ("ispaid [" + ispaid + "] \ n"); strbuffer. append ("cicle [" + cicle + "] \ n"); strbuffer. append ("testbyte [" + testbyte + "] \ n"); s Trbuffer. append ("arrbyte. Len [" + (arrbyte = NULL? "N/A": arrbyte. length) + "] \ n"); strbuffer. append ("testshort [" + testshort + "] \ n"); strbuffer. append ("testdouble [" + testdouble + "] \ n"); Return strbuffer. tostring ();} public static goodsbean newinstance () {goodsbean bean = new goodsbean (); bean. _ id = 128l; bean. name = "autosave"; bean. price = 1024; bean. ispaid = true; bean. cicle = 2.356f; bean. arrbyte = new string ("sodinoarrbytes "). getbytes (); bean. testby Te = 8; bean. testshort = 128; bean. testdouble = 9856.2145d; return bean;} public static contentvalues translate2contentvalues (goodsbean bean) {contentvalues CV = new contentvalues (); field [] arrfield = goodsbean. class. getfields (); try {for (field F: arrfield) {If (F. isaccessible () = false) {f. setaccessible (true);} string name = f. getname (); object value = f. get (bean); logout. out (goodsbean. class. getname (), "Name:" + name + "" + String. valueof (value); If (value instanceof byte) {cv. put (name, (byte) value);} else if (value instanceof short) {cv. put (name, (short) value);} else if (value instanceof integer) {cv. put (name, (integer) value);} else if (value instanceof long) {cv. put (name, (long) value);} else if (value instanceof string) {cv. put (name, (string) value);} else if (value instanceof byte []) {CV. put (name, (byte []) value);} else if (value instanceof Boolean) {cv. put (name, (Boolean) value);} else if (value instanceof float) {cv. put (name, (float) value);} else if (value instanceof double) {cv. put (name, (double) value) ;}} catch (illegalargumentexception e) {e. printstacktrace ();} catch (illegalaccessexception e) {e. printstacktrace ();} return CV;} public static goodsbean cursor2goodsbean (curs Or cursor) {goodsbean bean = new goodsbean (); If (cursor. isbeforefirst () {cursor. movetofirst ();} field [] arrfield = goodsbean. class. getfields (); try {for (field F: arrfield) {string columnname = f. getname (); int columnidx = cursor. getcolumnindex (columnname); If (columnidx! =-1) {If (F. isaccessible () {f. setaccessible (true);} class <?> Type = f. getType (); If (type = byte. class) {f. set (bean, (byte) cursor. getshort (columnidx);} else if (type = short. class) {f. set (bean, cursor. getshort (columnidx);} else if (type = int. class) {f. set (bean, cursor. getint (columnidx);} else if (type = long. class) {f. set (bean, cursor. getlong (columnidx);} else if (type = string. class) {f. set (bean, cursor. getstring (columnidx);} else if (type = byte []. class) {f. set (bean, cursor. getblob (columnidx);} else if (type = Boolean. class) {f. set (bean, cursor. getint (columnidx) = 1);} else if (type = float. class) {f. set (bean, cursor. getfloat (columnidx);} else if (type = double. class) {f. set (bean, cursor. getdouble (columnidx) ;}}} catch (illegalargumentexception e) {e. printstacktrace ();} catch (illegalaccessexception e) {e. printstacktrace ();} return bean ;}}