編輯:關於Android編程
SQLite數據庫
* 輕量級關系型數據庫
* 創建數據庫需要使用的api:SQLiteOpenHelper
創建SQLite數據庫必須要繼承SQLiteOpenHelper (superclass父類)
定義一個數據庫的打開幫助器MyOpenHelper需要實現其三個方法:
public class MyOpenHelper extends SQLiteOpenHelper{ public MyOpenHelper(Context context, String name,CursorFactory factory,int version){ super(context,name,factory,version); //構造函數 new } //數據庫一創建就會調用此方法 public void onCreate(SQLiteDatabase db) { } //數據庫升級時調用 public void onUpgrade(SQLiteDatabase db, Int oldVersion , Int newVersion ){ } }
構造函數裡面的參數的意思:
Parameters:
context : to use to open or create the database
name: of the database file, or null for an in-memory database //數據庫的名字;
factory: to use for creating cursor objects, or null for the default //cursor 游標 在這裡可以理解為resultset 結果集 一般使用默認的null
version: number of the database (starting at 1); if the database is older, onUpgrade will be used to upgrade the database; if the database is newer, onDowngrade will be used to downgrade the database //版本 if version<1 拋出IllegalArgumentException .參數異常
* 數據庫被創建時會調用:onCreate方法
* 數據庫升級時會調用:onUpgrade方法
數據庫建立在測試單元中時,系統沒有啟用,context上下文對象不存在。安卓為了能滿足能在測試狀態下測試數據庫的正確性虛擬了一個context上下文對象。在androidTestCase 中有一種獲取虛擬上下文的方法 getContext();
public class TestCase extends AndroidTestCase { public void test() { //getContext() 獲取虛擬的上下文對象。 MyOpenHelper oh = new MyOpenHelper(getContext(), "mydb.db", null, 1); //oh.getReadableDatabase(); //如果數據庫不存在就創建數據庫並獲取可讀可寫的數據庫對象,如果數據庫存在就直接打開數據庫。 SQLiteDatabase db= oh.getWritableDatabase(); } }
getReadableDatabase與getWritableDatabase用法基本一樣區別就是當(unless some problem, such as a full disk, requires the database to be opened read-only. In that case, a read-only database object will be returned. 可讀可寫不能正常工作)
SQLiteOpenHelper
數據庫對象創建在手機的內部存儲空間內。data/data/包名文件夾/databases/可以通過FileExplorer文件浏覽器查看
數據庫創建好的同時實際當中我們的表單也就創建出來了,創建表的過程通常是在onCreate方法中創建出來的。
這裡面需要注意的是數據庫創建好之後就不會再調用onCreate
數據庫增刪改常用語句:
insert into tablename (字段名)values();
增加表中的行數據:
insert into person(name,salary,phone)values(“zhangsan”,15000,153623);
刪除數據:
delete from person name=”zhangsan”where id=6;
修改數據:
update person set name=”lisi”where id=8;
查詢數據:
select name ,salary from person ;
SQlite數據庫的sql語句的增刪該查:
import com.zh.sqlitedatabase.MyOpenHelper; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.test.AndroidTestCase; public class TestCase extends AndroidTestCase { private MyOpenHelper oh; private SQLiteDatabase db; public void test() { MyOpenHelper oh = new MyOpenHelper(getContext(), "people.db", null, 1); // 如果數據庫不存在就創建數據庫,並獲取可讀可寫的數據庫對象,如果數據庫存在就直接打開數據庫。 SQLiteDatabase db = oh.getWritableDatabase(); } // 測試框架執行完畢,測試方法執行之前進行調用。 protected void setUp() throws Exception { // TODO Auto-generated method stub super.setUp(); oh = new MyOpenHelper(getContext(), "people.db", null, 1); db = oh.getWritableDatabase(); } // 摧毀 此方法是在方法執行完畢後才調用 protected void tearDown() throws Exception { // TODO Auto-generated method stub super.tearDown(); db.close(); } //增 public void insert() { // // db.execSQL("insert into person(name,salary,phone)values('張三',13000,139138)"); db.execSQL("insert into person(name,salary,phone)values(?,?,?)", newObject[] { "小志","12000",159006750 }); db.execSQL("insert into person(name,salary,phone)values(?,?,?)", new Object[] { "小志的老婆", "25000", 1323 }); } //改 update tablename set name= ? where id=? 修改id是xx將其名字設為xx. public void update() { db.execSQL("update person set name=?where _id=3 ", new Object[] { "小志的兒子" }); db.execSQL("update person set name=? where name=?", new Object[] { "李冰冰", "小輝" }); //修改將小輝改為李冰冰。 } public void delete() { // db.execSQL("delete from person where _id=3"); // db.execSQL("delete from person where name=?", new Object[] { "小志" }); db.execSQL("delete from person where name=? and salary= ?", new Object[] { "小輝", 25000 }); db.execSQL("delete from person where name=?", new Object[] { "張三" }); } public void select() { //注意查詢時由於得到有返回值,db.execSQL()語句的返回值為空所以不能再用該方法。 Cursor cusor = db.rawQuery("select name,salary from person", null); while (cusor.moveToNext()) { String name = cusor.getString(cusor.getColumnIndex("name")); String salary = cusor.getString(cusor.getColumnIndex("salary")); System.out.println(name + ";" + salary); } } }
1、這裡注意的是將myopenhelper提升為全局變量的方法:Ctrl+1 找到設置全局變量選項,(需要選中要提升的對象) (ctrl+1快速修復)
提升全局變量後會拋出空指針異常,原因是androidtextcase未加載的時候全局變量已經建立,getContex獲取的上下文虛擬對象為空,source 找到androidtextcase的setup方法,進行從寫(set up測試框架執行完畢,測試方法執行之前進行調用。)此時能保證得到上下文對象。 db.close 數據的關閉方法 teardown(摧毀 此方法是在方法執行完畢後才調用).
2、在mysql數據庫增加表格中的記錄insert into 其中into可以省略,但SQLite數據庫不能省略,否則會報錯。
3、注意占位符 new Object []{} 設置占位符的值。
4、SQLite數據庫查詢時,不能用執行sql語句的方法 用 db.rawQuery() 原始查詢 得到一個Cursor對象,然後進行循環
cusor.moveToNext() getString(Index columnindex)
cusor.getColumnIndex(“name”)通過列索引獲得列的值。
用Android封裝好的api進行數據庫的增刪該查:
insert:增加記錄
public void insertApi(){ //把要插入的數據放入到contenValues 對象當中 ContentValues values = new ContentValues(); values.put("name", "張大輝"); values.put("salary","19000"); db.insert("person", null, values); }
刪除:delete
db.delete(table, whereClause, whereArgs) //刪除的表名,刪除條件,和條件的參數字符串數組
public void deleteApi(){ int i =db.delete("person", "name=? and _id=?", new String[]{"李四","4"}); //刪除id是4name李四 System.out.println(i);
更改數據庫中的數據:update
db.update(table, values, whereClause, whereArgs)參數以字符串數組形式表示
}
public void updateApi(){ //這裡的values是改變後新的數據存放在contentvalues對象中 以鍵值對的形式存放 Contentvalues values= new Contentvalues(); values.put("name","王五") //將表person中_id=4,name="李四"的記錄更改為王五 db.update("person",values,"name=? and _id=?",new String[]{"李四","4"}); }
查詢:query
db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit)
Parameters:
table: The table name to compile the query against.
columns :A list of which columns to return. Passing null will return all columns, which is discouraged to prevent reading data from storage that isn’t going to be used.
selection A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given table.
selectionArgs You may include ?s in selection, which will be replaced by the values from selectionArgs, in order that they appear in the selection. The values will be bound as Strings.
groupBy A filter declaring how to group rows, formatted as an SQL GROUP BY clause (excluding the GROUP BY itself). Passing null will cause the rows to not be grouped.
having A filter declare which row groups to include in the cursor, if row grouping is being used, formatted as an SQL HAVING clause (excluding the HAVING itself). Passing null will cause all row groups to be included, and is required when row grouping is not being used.
orderBy How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered.
limit Limits the number of rows returned by the query, formatted as LIMIT clause. Passing null denotes no LIMIT clause.
Returns:
A Cursor object, which is positioned before the first entry. Note that Cursors are not synchronized, see the documentation for more details.
db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit)
public void selectApi(){ // (String)表名, 要查詢的字段(String[]), 查詢條件(String),查詢條件的參數(String[]),,,orderBy 通過_id 進行desc降序排列,分頁 Cursor cursor= db.query("person",new String[]{"name","salary","_id"},"name=?",new String[]{"王五"},null,null,"_id desc",null); while(cursor.moveToNext()) { String name= cursor.getString(cursor.getColumnIndex("name")); String salary = cursor.getString(cursor.getColumnIndex("salary")); String id = cursor.getString(cursor.getColumnIndex("_id")); System.out.println(name+";"+salary+";"+_id); } }
查詢時得到的Cursor對象
cursor.moveToNext() boolean類型的 它的意思是
Move the cursor to the next row. 移動到下一行 這裡的cursor 將相當於結果集。
This method will return false if the cursor is already past the last entry in the result set.
SQLite 也支持事物 Transaction:
事務
保證所有sql語句要麼一起成功,要麼一起失敗
格式:
開啟事務: db.beginTransaction();
設置事務成功: db.setTransactionSuccessful();
最後 finally 中 : db.endTransaction; 關閉事務 同時提交事務, 如果上面的設置事務執行成功,那麼sql語句就會生效,否則Sql語句就會回滾。
通常情況下開啟事務,和設置事務成功位於try語句塊中,關閉事務位於finally語句塊中。
public void transaction(){ try{ db.beginTransaction(); ContentValues values = new ContentValues(); values.put("salary","20000"); db.update("person",values,"_id=?",new String[]{"8"}); values.clear(); //這一步很重要將上面的數據清空,然後下面的數據進行在賦值。 values.put("salary","18000"); db.update("person",values,"name=?",new String[]{"王五"}); db.setTransactionSuccessful(); //設置 事務成功 位於執行更改的最下邊 注意此時還未提交事務 } finally { //關閉事務,同時提交事務,如果上面的設置事務成功語句執行,那麼sql語句就生效了,否則sql語句回滾。就不能正常執行了。 db.endTransaction(); } }
Android其中最重要的特性之一,就是一個應用可以基於“action”來切換到另一個應用。比如,你的應用想要查找地方,在地圖上顯示。但是不一定要
如今android N都已經出來了,作為一個android開發者如果還不知道如何使用android5.X的 RecyclerView未免有點說不過去了。RecyclerV
公司的以前的項目,看到使用了這個Android自帶的倒計時控件Chronometer,現在整合了一下先看看效果:<Chronometer android:id=
Android-PullRefreshLayout簡介:基於SwipeRefreshLayout,通吃所有的AbsListView、RecyclerViewAndroid