知識點
SQLit數據庫(安卓自帶的)
- 常見數據庫
- 創建一個工具類
- 純sql方式操作數據庫
- 添加
- 刪除
- 更新
- 查詢
- 面向對象的方式操作數據庫
- 添加
- 刪除
- 更新
- 查詢
ListView(安卓核心控件)
- ListView(理解)
- ListView入門
- ListView優化
- 複雜的ListView
具體細節以及案例
- ##### 常見數據庫
- Oracle:大型的數據庫 ,性能最高
- Mysql:小型數據庫 開源的 免費的
- DB2:大型數據庫,收費
- Sqlite:微型,免費,美國軍艦(Android自帶)
- ###### 創建一個工具類繼承SQLiteOpenHelper
要明白的:
-構造方法裏傳的三個參數分別是什麼意思 作用是什麼?
- 參數1:Context 上下文環境
- 參數2:name 數據庫文件的名稱(xxx.db)
- 參數3:factory 遊標工廠,傳入null使用系統默認的遊標(可以理解爲指向數據庫中數據的指針)
參數4:version 數據庫版本,==必須大於1==
- 作用:給創建的子類對象設置好數據庫名字以及版本號
明白OnCreate()方法什麼時候使用,使用的特點是什麼
- ==當第一次創建數據庫的時候調用==
- 特點: 由系統調用,且只會調用一次
思路:
- 在==onCrate方法==裏創建表
- 創建表的SQL語句:
- ==create table 數據表名(_id integer primary key,列名2 數據類型 約束,列名3 數據類型 約束);==
- SQLite的主鍵會自動自增,不需要加auto_increment
- 在==onUpgrade==方法內升級數據庫
- 修改表
- ==alter table t_user add c_money float==
代碼
@Override
public void onCreate(SQLiteDatabase db) {
// 創建表結構
String sql = "create table t_user (_id integer primary key,t_name varchar(20),t_age integer ,t_gender varchar(20))";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String sql = "alter table t_user add c_money float";
db.execSQL(sql);
}
- ###### 使用SQLiteOpenHelper創建數據庫文件
思路
- 先寫UI,創建一個按鈕,點擊按鈕觸發創建數據庫事件
創建工具類的對象(有參數的構造)
- MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this, DB_NAME, null, VERSION);
通過.getReadableDatabase()或.getWriteableDatabase()來獲取數據庫
- SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase();
- 調用.close() 釋放資源
// 創建數據庫
public void create(View view) {
// 創建工具類的對象
MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this,
DB_NAME, null, VERSION);
// 通過.getReadableDatabase()來獲取數據庫
SQLiteDatabase database = mySQLiteOpenHelper.getReadableDatabase();
// 釋放資源
database.close();
Toast.makeText(this, "創建數據庫成功", Toast.LENGTH_SHORT).show();
}
- #### 純sql方式操作數據庫
思路
添加,刪除,更新都是調用execSQL(sql,Object[]{})方法,只是sql語句不一樣
先寫UI,創建一個按鈕,點擊按鈕觸發添加數據事件
獲取操作的數據庫
- ==MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this, DB_NAME, null, VERSION);==
- ==SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase();==
- 用一個字符串接收添加數據的sql語句,一般會使用佔位符的格式
- 調用的是 ==execSQL(sql,Object[]{})== 方法
- 釋放資源
- 查詢
- 先寫UI,創建一個按鈕,點擊按鈕觸發添加數據事件
- 獲取操作的數據庫(跟添加,刪除,更新一樣)
- 用一個字符串接收添加數據的sql語句,一般會使用佔位符的格式
- 調用 ==rewQuery(sql,String[]{})== 方法,返回值是Cursor 結果集
- 判斷結果集裏是否存在下一個符合條件數據,調用 ==moveToNext()== 方法,用while循環來遍歷出要查詢的數據
- 如果存在,通過字段索引,獲取字段的內容,調用 ==getXxx()== 方法獲取,索引從0開始
- ==注意:通過索引獲取時,是根據你查詢的結果爲準==
- 釋放資源
// 添加數據
public void insert(View view) {
// 獲取操作的數據庫
MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this,
DB_NAME, null, VERSION);
SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase();
// 用一個字符串接收添加數據的sql語句,一般會使用佔位符的格式
String sql = "insert into t_user (t_name,t_age,t_gender) values(?,?,?)";
database.execSQL(sql, new Object[] { "王莉莉" + new Random().nextInt(100),
new Random().nextInt(108), "" + new Random().nextInt(2) });
// 釋放資源
database.close();
Toast.makeText(this, "1成功", Toast.LENGTH_SHORT).show();
}
// 刪除數據
public void delete(View view) {
// 獲取操作的數據庫
MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this,
DB_NAME, null, VERSION);
SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase();
// 用一個字符串接收添加數據的sql語句,一般會使用佔位符的格式
String sql = "delete t_user where t_age>?";
database.execSQL(sql, new Object[] { "60" });
// 釋放資源
database.close();
Toast.makeText(this, "2成功", Toast.LENGTH_SHORT).show();
}
// 更新數據
public void update(View view) {
// 獲取操作的數據庫
MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this,
DB_NAME, null, VERSION);
SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase();
// 用一個字符串接收添加數據的sql語句,一般會使用佔位符的格式
String sql = "update t_user set t_name=? where t_age<?";
database.execSQL(sql, new Object[] { "王麗麗", 20 });
// 釋放資源
database.close();
Toast.makeText(this, "3成功", Toast.LENGTH_SHORT).show();
}
// 查詢數據
public void select(View view) {
// 獲取操作的數據庫
MySQLiteOpenHelper mySQLiteOpenHelper = new MySQLiteOpenHelper(this,
DB_NAME, null, VERSION);
SQLiteDatabase database = mySQLiteOpenHelper.getWritableDatabase();
// 用一個字符串接收添加數據的sql語句,一般會使用佔位符的格式
String sql = "select * from t_user where t_age>?";
// 調用 rawQuery() 方法進行查詢,第二個參數是string數組,返回的是一個Cursor 結果集
Cursor cursor = database.rawQuery(sql, new String[] { "50" });
// 判斷結果集裏是否存在下一個符合條件數據,調用moveToNext()方法,用while循環來遍歷出要查詢的數據
List<User> list = new ArrayList<User>();
while (cursor.moveToNext()) {
// 如果存在,通過字段索引,獲取字段的內容,調用getXxx()方法獲取,索引從0開始
// 注意:通過索引獲取時,是根據你查詢的結果爲準
String name = cursor.getString(0);
int age = cursor.getInt(1);
String gender = cursor.getString(2);
User user = new User();
user.name = name;
user.age = age;
user.gender = gender;
list.add(user);
}
Log.w("tag", list.toString());
textView.setText(list.toString());
// 釋放資源
database.close();
Toast.makeText(this, "5成功", Toast.LENGTH_SHORT).show();
}
- #### 面向對象的方式操作數據庫
- 思路:
- 添加數據
- 先寫UI,創建一個按鈕,點擊按鈕觸發添加數據事件
- 獲取操作的數據庫
- 調用 ==insert()== 方法
- 參數1:表名
- 參數2:一般是null
- 參數3是一個ContenValues對象,這個類封裝的是一個Map數組
- 調用put(key,values)方法,添加數據
- 返回值是插入的行數,==long== 類型的,如果插入爲0,返回-1
-
- 添加數據
// 添加數據
public void insert(View v) {
// 獲取工具類的對象
MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this,
DB_USER, null, VERSION);
// 通過.getReadableDatabase()創建數據庫
SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase();
// 調用insert方法,參數3是一個ContenValues對象,這個類封裝的是一個Map數組
// insert 返回值是插入的行數,long類型的
ContentValues values = new ContentValues();
values.put("t_name", "王麗麗" + new Random().nextInt(20));
values.put("t_age", 20 + new Random().nextInt(10));
values.put("t_gender", "" + new Random().nextInt(2));
long len = database.insert("s_user", null, values);
database.close();
Toast.makeText(this, "在" + len + "插入了數據", Toast.LENGTH_SHORT).show();
}
- 刪除數據
- 先寫UI,創建一個按鈕,點擊按鈕觸發添加數據事件
- 獲取操作的數據庫
- 調用 ==delete()== 方法
- 參數1:表名
- 參數2放的是where條件
- 參數3是參數2裏面?的真實值
- 返回值是受影響的行數,返回類型 ==int==
- 釋放資源 -
// 獲取工具類的對象
MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this,
DB_USER, null, VERSION);
// 通過.getReadableDatabase()創建數據庫
SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase();
// 調用delete()方法,參數2放的是where條件,參數3是參數2裏面?的真實值,返回值是受影響的行數,返回類型int
int len = database.delete("s_user", "t_age>?", new String[] { "20" });
database.close();
Toast.makeText(this, len + "受影響", Toast.LENGTH_SHORT).show();
}
- 更新數據
- 先寫UI,創建一個按鈕,點擊按鈕觸發添加數據事件
- 獲取操作的數據庫
- 調用 ==update()== 方法
- 參數1:表名
- 參數2是一個ContenValues對象,這個類封裝的是一個Map數組
- 調用put(key,values)方法,添加數據
- 參數3放的是where條件
- 參數4是參數3裏面?的真實值
- 返回值是受影響的行數,返回類型 ==int==
- 釋放資源
-
// 更新
public void update(View view) {
// 獲取工具類的對象
MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this,
DB_USER, null, VERSION);
// 通過.getReadableDatabase()創建數據庫
SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase();
// 調用update()方法,參數2是一個ContenValues對象,這個類封裝的是一個Map數組,參數3放的是where條件,參數4是參數2裏面?的真實值,返回值是受影響的行數,返回類型int
ContentValues values = new ContentValues();
values.put("t_money", "1000");
int len = database.update("s_user", values, "t_age>?",
new String[] { "19" });
database.close();
Toast.makeText(this, len + "受影響", Toast.LENGTH_SHORT).show();
}
- 查詢數據
- 先寫UI,創建一個按鈕,點擊按鈕觸發添加數據事件
- 獲取操作的數據庫
- 調用 ==query()== 方法
- 參數1:表名
- 參數2:要查詢的字段,放到字符串數組中
- 參數3放的是where條件
- 參數4是參數3裏面?的真實值
- 參數5:null
- 參數6:null
- 參數7:排序表達式
- 返回值返回值是 Cursor 結果集
- 判斷結果集裏是否存在下一個符合條件數據,調用 ==moveToNext()== 方法,用while循環來遍歷出要查詢的數據
- 如果存在,通過字段索引,獲取字段的內容,調用 ==getXxx()== 方法獲取,索引從0開始
- ==注意:通過索引獲取時,是根據你查詢的結果爲準==
- 釋放資源 -
public void select(View view) {
// 獲取工具類的對象
MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this,
DB_USER, null, VERSION);
// 通過.getReadableDatabase()創建數據庫
SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase();
// 調用了query()方法 參數2:要查詢的字段,放到字符串數組中
// 參數3:就是where表達式
// 參數4:用於替換參數3中?號的真實的值,String[]數組中形式
// 參數5:null
// 參數6:null
// 參數7:排序表達式
// 返回類型是一個Cursor對象,結果集
Cursor cursor = database.query("s_user", new String[] { "*" },
"t_age>?", new String[] { "20" }, null, null, "t_age");
List<User> list = new ArrayList<User>();
while (cursor.moveToNext()) {
String name = cursor.getString(1);
int age = cursor.getInt(2);
String gender = cursor.getString(3);
User user = new User();
user.name = name;
user.age = age;
user.gender = gender;
list.add(user);
}
database.close();
Toast.makeText(this, list.toString(), Toast.LENGTH_SHORT).show();
}
- ##### 數據庫升級
- 思路:
- 更新數據庫:
- ==注意,只能升版本,不能降版本==
- 先寫UI,創建一個按鈕,點擊按鈕觸發添加數據事件
- 獲取操作的數據庫
- 設置版本號,必須大於上一個版本號
- 釋放資源
- 更新數據庫:
// 更新數據庫
public void shengji(View view) {
// 更新數據庫:注意,只能升版本,不能降版本
// 獲取工具類的對象
MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this,
DB_USER, null, VERSION);
// 通過.getReadableDatabase()創建數據庫
SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase();
database.close();
Toast.makeText(this, "升級成功", Toast.LENGTH_SHORT).show();
}
- ###### 數據庫事物(模擬轉賬)
- 對事物的理解:
- 同時執行的多個數據庫操作,要麼同時成功,要麼同時失敗,不能出現一個成功一個失敗的情況,==事物就是爲了確保安全性的==
- 思路:
- 先寫UI,創建一個按鈕,點擊按鈕觸發添加數據事件
- 獲取操作的數據庫
- 開啓事物,調用了 ==beginTransaction()== ;方法
- 提交事物, ==setTransactionSuccessful()==
- 關閉事務, ==endTransaction()==
- 釋放資源
// 開啓事物
public void change(View view) {
// 獲取工具類的對象
MeSQLiteOpenHelper meSQLiteOpenHelper = new MeSQLiteOpenHelper(this,
DB_USER, null, VERSION);
// 通過.getReadableDatabase()創建數據庫
SQLiteDatabase database = meSQLiteOpenHelper.getReadableDatabase();
// 更新表中數據,進行模擬轉賬操作!
// 開啓事物,之後的代碼都是在臨時內存中執行的,並未真正的寫入到數據庫文件中
database.beginTransaction();
String sql = "update s_user set t_money = t_money-500 where t_name=?";
database.execSQL(sql, new Object[] { "jjjj" });
String sql2 = "update s_user set t_money = t_money+500 where t_name=?";
database.execSQL(sql2, new Object[] { "王麗麗" });
// 提交事物,事物只有提交了纔會寫到數據庫中
database.setTransactionSuccessful();
// 使用完後關閉事務功能
database.endTransaction();
database.close();
Toast.makeText(this, "轉賬成功", Toast.LENGTH_SHORT).show();
}
- ###### ListView(理解)
- 對ListView的理解:
- ListView是一個可以放很多條目的控件,可以滑動,可以顯示一個數據集,如果數據超出屏幕可以上下滑動
- ==注意,ListView的寬高必須設置爲match_parent,不能使用wrap_content。只有加了id才能在佈局中看到示例頁面==
- 使用ListView一般都會使用適配器Adapter,在適配器一般會用Adapter的子類BaseAdapter
- ==getCount()==:ListView一共有多少個條目
- ==getView()==:設置每一個條目數據,==最後一定要返回對象==
- ==注意:界面上顯示多少個條目該方法就調用多少次,之後滾出來一個條目就調用一次==。
- ==public View getView(int position, View convertView, ViewGroup parent)==
- 有三個參數
- 參數一:int position,放的是索引,跟集合的索引是一樣的
- 參數二:View convertView 一個可以複用的view控件
- 參數三:一般是null
- getItem():返回每個條目的對象
- getItemId():返回當前條目位置。
- 對ListView的理解:
- 如果是操作是一個TextView,可以用 ==ArrayAdapter== ,這個類底層就已經實現好了,只需要用就行
- ###### ListView入門
思路:
- 在main xml中創建一個ListViewko 控件
- 在MainActivity寫業務邏輯
- 創建一個成員集合,來存放數據
- 初始化ListView
- 設置快速滑動 調用 .setsetFastScrollEnabled(true);
- 設置適配器調用setAdapter()
- 參數傳的一個Adapter一個子類BaseAdapter對象,
- 創建一個類去繼承BaseAdapter,重寫BaseAdapter的方法
- 在getCount()方法裏獲取總共的條目
- 在getView裏創建一個textView(可以直接new一個)
- 定義一個字符串根據索引獲取集合裏的內容
- 調用 .setText()給TextView賦值
ListView優化
- 爲了防止內存溢出
- 在getView()方法裏複用convertView
view view=null;
if(convertView==null){
view = View.inflate(MainActivity.this, R.layout.listview_my, null);//創建view時,調用inflate()方法,獲取id時是獲取view存在的xml中的xml名字:R.layout.listview_my
}else {
view = convertView;
}
- ###### 複雜的ListView
- 思路:
- 先在main xml 創建一個ListView 控件
- 自己定義一個 xml 放的是存在ListView裏面的佈局
- 在MainActivity裏面寫業務邏輯
- 創建一個成員集合,來存放數據
- 初始化ListView
- 設置快速滑動 調用 ==.setsetFastScrollEnabled(true);==
- 設置適配器調用==setAdapter()==
- 參數傳的一個Adapter一個子類BaseAdapter對象,
- 創建一個類去繼承==BaseAdapter==,重寫BaseAdapter的方法
- 在 ==getCount()== 方法裏獲取總共的條目
- 要用ListView優化->>>(上一個優化代碼)
- 在getView裏創建一個View
- 獲取view資源
```
ImageView imageView = (ImageView) view.findViewById(R.id.image);
TextView name = (TextView) view.findViewById(R.id.name);
TextView ageTextView = (TextView) view.findViewById(R.id.age);
TextView genderTextView = (TextView) view.findViewById(R.id.gender);
```
- **注意:獲取View資源一定要調用==View的findViewById==(R.id.image)**
- 調用 ==.setText()== 給TextView賦值
```
name.setText(user.name);
ageTextView.setText(user.age+"");
genderTextView.setText(user.gender);
```
- 給條目添加圖片
- 具體代碼
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化listview
listView = (ListView) findViewById(R.id.contects);
for (int i = 0; i < 100; i++) {
User user = new User();
user.name = "khk"+i;
user.age = i;
user.gender = "女"+i;
alist.add(user);
}
// 設置滑動加速器
listView.setFastScrollEnabled(true);
// 添加適配器
listView.setAdapter(new BaseAdapter() {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 獲取view對象
View view =null;
if (convertView==null) {
view = View.inflate(MainActivity.this, R.layout.listview_my, null);
}else {
view = convertView;
}
// 根據索引獲取數據
User user = alist.get(position);
// 獲取view資源
ImageView imageView = (ImageView) view.findViewById(R.id.image);
TextView name = (TextView) view.findViewById(R.id.name);
TextView ageTextView = (TextView) view.findViewById(R.id.age);
TextView genderTextView = (TextView) view.findViewById(R.id.gender);
name.setText(user.name);
ageTextView.setText(user.age+"");
genderTextView.setText(user.gender);
// 給條目添加圖片
switch (position%10) {
case 0:
imageView.setImageResource(R.drawable.iv0);
break;
case 1:
imageView.setImageResource(R.drawable.iv1);
break;
case 2:
imageView.setImageResource(R.drawable.iv2);
break;
case 3:
imageView.setImageResource(R.drawable.iv3);
break;
case 4:
imageView.setImageResource(R.drawable.iv4);
break;
case 5:
imageView.setImageResource(R.drawable.iv5);
break;
case 6:
imageView.setImageResource(R.drawable.iv6);
break;
case 7:
imageView.setImageResource(R.drawable.iv7);
break;
case 8:
imageView.setImageResource(R.drawable.iv8);
break;
case 9:
imageView.setImageResource(R.drawable.iv9);
break;
default:
break;
}
return view;
}
@Override
public int getCount() {
// 獲取條目的個數
return alist.size();
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public Object getItem(int position) {
return null;
}
});
}
- 計時器:
步驟:
- 在LinearLayout定義一個button和一個ListView控件
- 先分配button的空間,把ListView的高度設置match…
- 也可以設置權重
- 獲取ListView和button
點擊按鈕獲取當前時間
調用SimpleDataFormat裏面format()方法
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String timeString = format.format(new Date()); timeList.add(timeString);
定義一個集合接收時間字符串
- Adapter裏有一個方法:notifyDataSetChange() ==讓arraylistview(ListView)更新一下數據,重新調用Adapter的getCount和getview();==
- //list集合有一個add(adaption,String)讓添加的數據加載第一條list.add(0,要添加的數據);
- 讓ListView滾動到最後一個條目
- 方法一.
- 平滑 調用 ==smoothScrollToPosition(一般是放的最後一個條目的索引)== 方法
- 方法二.
- 不平滑 讓ListView定位定位到哪個條目 調用 ==setSelection()==;
- 方法一.
- 在LinearLayout定義一個button和一個ListView控件
感受和問題
今天主要學了SQLite 和ListView控件 數據庫存儲數據的兩種方式,出現了大量的新方法,雖然操作數據時很多都是相似的,但是大部分都是需要記得東西,感覺一下子接受這些東西有些吃力,可能手速還是跟不上,練習的時間總感覺不夠用.
在練習的時候總會因爲一些粗心犯了一些很低級的錯誤,在使用這些方法時容易記混裏面參數的意思,在學習ListView時,感覺吃力很多,新單詞有些多,容易記混使用方法
經過這些天的學習,明白了就業班和基礎班的區別,相比之下在基礎班節奏還是慢的,明白了不能拿在基礎班的態度,對待就業班,努力的去改善自己的學習方法和節奏,也慢慢的去適應就業班,跟着節奏一點一點的往前跟,希望自己不要掉隊,加油!!!