編輯:關於Android編程
上一篇Android中XUtils3框架使用方法詳解(一)文章,主要介紹了XUtil3的注解模塊,網絡模塊,圖片加載模塊,今天給大家帶來數據庫模塊的講解,現在主流的ORM框架很多,比如OrmLite,GreenDao,Active Android,Realm等等,這些框架每個都有自己的優點和缺點,大家完全可以根據自己項目的實際需求進行選擇,下面開始進入今天的數據庫模塊的介紹。
今天主要給大家帶來以下幾個模塊:
如何創建刪除一張表
如何對表進行增刪查改操作
如何創建數據庫和刪除數據庫
如何建立一表對一表,多表對一表,多表對多表的外鍵操作。
相信對ORM框架有過了解的人,大概都知道只要創建一個JavaBean對象,在類的上面和屬性的上面添加注釋標簽,這樣就能生成一個表。下面帶大家看一下XUtils3的實體bean的寫法:
@Table(name="person") public class PersonTable { @Column(name="id",isId=true,autoGen=true) private int id; //姓名 @Column(name="name") private String name; //年齡 @Column(name="age") private int age; //性別 @Column(name="sex") private String sex; //工資 @Column(name="salary") private String salary; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSalary() { return salary; } public void setSalary(String salary) { this.salary = salary; } @Override public String toString() { return "PersonTable [id=" + id + ", name=" + name + ", age=" + age + ", sex=" + sex + ", salary=" + salary + "]"; } }
通過上方的實體bean,我們需要知道一個表對應的實體bean需要注意以下幾點:
1.在類名上面加入@Table標簽,標簽裡面的屬性name的值就是以後生成的數據庫的表的名字
2.實體bean裡面的屬性需要加上@Column標簽,這樣這個標簽的name屬性的值會對應數據庫裡面的表的字段。
3.實體bean裡面的普通屬性,如果沒有加上@Column標簽就不會在生成表的時候在表裡面加入字段。
4.實體bean中必須有一個主鍵,如果沒有主鍵,表以後不會創建成功,@Column(name=”id”,isId=true,autoGen=true)這個屬性name的值代表的是表的主鍵的標識,isId這個屬性代表的是該屬性是不是表的主鍵,autoGen代表的是主鍵是否是自增長,如果不寫autoGen這個屬性,默認是自增長的屬性。
既然知道怎麼寫實體bean了,下面看看如何在程序中創建一個數據庫和如何生成表的吧。
public class XUtil { static DbManager.DaoConfig daoConfig; public static DaoConfig getDaoConfig(){ File file=new File(Environment.getExternalStorageDirectory().getPath()); if(daoConfig==null){ daoConfig=new DbManager.DaoConfig() .setDbName("shiyan.db") .setDbDir(file) .setDbVersion(1) .setAllowTransaction(true) .setDbUpgradeListener(new DbUpgradeListener() { @Override public void onUpgrade(DbManager db, int oldVersion, int newVersion) { } }); } return daoConfig; } }
通過XUti.getDaoConfig()方法,我們能夠獲取到一個DaoConfig對象。通過getDaoConfig()方法,我們可以知道這個方法主要可以做以下事情:
1.setDbName 設置數據庫的名稱
2.setDbDir 設置數據庫存放的路徑
3.setDbVersion 設置數據庫的版本
4.setAllowTransaction(true) 設置允許開啟事務
5.setDbUpgradeListener 設置一個版本升級的監聽方法
那麼具體我們什麼時候創建的表呢?如果我們單純的調用XUti.getDaoConfig()方法是不能夠創建PersonTable這個實體對應的person這張表的,那麼如何創建表呢?
只需要一下幾步:
1.DaoConfig daoConfig=XUtil.getDaoConfig();
2.DbManager db = x.getDb(daoConfig);
這裡我要告訴大家的是,數據庫裡面表的創建的時間,只有在你對數據庫裡面的操作涉及到這張表的操作時,會先判斷當前的表是否存在,如果不存在,才會創建一張表,如果存在,才會進行相應的CRUD操作,但是只要我們想進行一張表的CRUD操作,我們必須先執行上面的2步,通俗點說就是必須拿到一個Dbmanger這個對象,我為什麼這麼說呢?那麼咱們就先看一下DbManger的廬山真面目吧。
DbManager部分源碼如下:
public interface DbManager extends Closeable { DaoConfig getDaoConfig(); SQLiteDatabase getDatabase(); /** * 保存實體類或實體類的List到數據庫, * 如果該類型的id是自動生成的, 則保存完後會給id賦值. * * @param entity * @return * @throws DbException */ boolean saveBindingId(Object entity) throws DbException; /** * 保存或更新實體類或實體類的List到數據庫, 根據id對應的數據是否存在. * * @param entity * @throws DbException */ void saveOrUpdate(Object entity) throws DbException; /** * 保存實體類或實體類的List到數據庫 * * @param entity * @throws DbException */ void save(Object entity) throws DbException; /** * 保存或更新實體類或實體類的List到數據庫, 根據id和其他唯一索引判斷數據是否存在. * * @param entity * @throws DbException */ void replace(Object entity) throws DbException; ///////////// delete void deleteById(Class<?> entityType, Object idValue) throws DbException; void delete(Object entity) throws DbException; void delete(Class<?> entityType) throws DbException; void delete(Class<?> entityType, WhereBuilder whereBuilder) throws DbException; ///////////// update void update(Object entity, String... updateColumnNames) throws DbException; void update(Object entity, WhereBuilder whereBuilder, String... updateColumnNames) throws DbException; ///////////// find <T> T findById(Class<T> entityType, Object idValue) throws DbException; <T> T findFirst(Class<T> entityType) throws DbException; <T> List<T> findAll(Class<T> entityType) throws DbException; <T> Selector<T> selector(Class<T> entityType) throws DbException; DbModel findDbModelFirst(SqlInfo sqlInfo) throws DbException; List<DbModel> findDbModelAll(SqlInfo sqlInfo) throws DbException; ///////////// table /** * 刪除表 * * @param entityType * @throws DbException */ void dropTable(Class<?> entityType) throws DbException; /** * 添加一列, * 新的entityType中必須定義了這個列的屬性. * * @param entityType * @param column * @throws DbException */ void addColumn(Class<?> entityType, String column) throws DbException; ///////////// db /** * 刪除庫 * * @throws DbException */ void dropDb() throws DbException; /** * 關閉數據庫, * xUtils對同一個庫的鏈接是單實例的, 一般不需要關閉它. * * @throws IOException */ void close() throws IOException; ///////////// custom void execNonQuery(SqlInfo sqlInfo) throws DbException; void execNonQuery(String sql) throws DbException; Cursor execQuery(SqlInfo sqlInfo) throws DbException; Cursor execQuery(String sql) throws DbException; }
通過DbManager這個類我們知道主要它做了以下幾件事情:
1.getDaoConfig 獲取數據庫的配置信息
2.getDatabase 獲取數據庫實例
3.saveBindingId saveOrUpdate save 插入數據的3個方法(保存數據)
4.replace 只有存在唯一索引時才有用 慎重
5.delete操作的4種方法(刪除數據)
6.update操作的2種方法(修改數據)
7.find操作6種方法(查詢數據)
8.dropTable 刪除表
9.addColumn 添加一列
10.dropDb 刪除數據庫
插入操作
private void insert() { try { PersonTable person=new PersonTable(); person.setName("小麗"); person.setAge(19); person.setSex("woman"); person.setSalary(4000); db.save(person); //db.saveOrUpdate(person); //db.saveBindingId(person); } catch (DbException e) { e.printStackTrace(); } }
結果如下:
3種插入操作所需要的參數都是一個實體bean。save和saveOrUpdate的區別就是當一個實體裡面的主鍵一樣時如果使用saveOrUpdate會將當前主鍵對應的這條數據進行替換,而如果你使用了save就會報錯。
saveBindingId主要是存進去的數據如果當前表有主鍵回合主鍵進行綁定關聯。
當你執行完這個方法後,你會看到數據庫裡面person表裡面多了一條數據.
查詢操作
當前數據庫中的表的效果如下:
1.findById的使用
該方法主要是通過主鍵的值來進行查找表裡面的數據
需求:查找上方person表裡面id為3的數據
private void query(){ try { PersonTable person = db.findById(PersonTable.class, "2"); Log.e("person",person.toString()); } catch (DbException e) { e.printStackTrace(); } }
結果如下:
2.findFirst的使用
該方法主要是返回當前表裡面的第一條數據
需求:查找上方person表裡面的第一條數據
private void query() { try { PersonTable person = db.findFirst(PersonTable.class); Log.e("person", person.toString()); } catch (DbException e) { e.printStackTrace(); } }
3.findAll的使用
該方法主要是返回當前表裡面的所有數據
需求:查找person表裡面的所有數據
private void query() { try { List<PersonTable> persons = db.findAll(PersonTable.class); Log.e("persons", persons.toString()); } catch (DbException e) { e.printStackTrace(); } }
4.selector的使用
該方法主要是用來進行一些特定條件的查找
需求:查找person表裡面age大於30並且性別為man的數據
private void query() { try { List<PersonTable> persons = db.selector(PersonTable.class).where("age", ">", 30).and("sex", "=", "man").findAll(); for(PersonTable person:persons){ Log.e("person",person.toString()); } } catch (DbException e) { e.printStackTrace(); } }
5.findDbModelFirst的使用
說起這個方法,該方法返回一個DbModel對象,那麼該對象是什麼呢?
DbMobel源碼如下:
public final class DbModel { /** * key: columnName * value: valueStr */ private HashMap<String, String> dataMap = new HashMap<String, String>(); public String getString(String columnName) { return dataMap.get(columnName); } public int getInt(String columnName) { return Integer.valueOf(dataMap.get(columnName)); } public boolean getBoolean(String columnName) { String value = dataMap.get(columnName); if (value != null) { return value.length() == 1 ? "1".equals(value) : Boolean.valueOf(value); } return false; } public double getDouble(String columnName) { return Double.valueOf(dataMap.get(columnName)); } public float getFloat(String columnName) { return Float.valueOf(dataMap.get(columnName)); } public long getLong(String columnName) { return Long.valueOf(dataMap.get(columnName)); } public Date getDate(String columnName) { long date = Long.valueOf(dataMap.get(columnName)); return new Date(date); } public java.sql.Date getSqlDate(String columnName) { long date = Long.valueOf(dataMap.get(columnName)); return new java.sql.Date(date); } public void add(String columnName, String valueStr) { dataMap.put(columnName, valueStr); } /** * @return key: columnName */ public HashMap<String, String> getDataMap() { return dataMap; } /** * @param columnName * @return */ public boolean isEmpty(String columnName) { return TextUtils.isEmpty(dataMap.get(columnName)); } }
通過源碼,我們分析發現DbModel本質就是一個key為當前表的字段,value為當前某條記錄的值的一個HashMap.
需求:查找person表中第一條數據的那個人的年齡age是多少。
private void query() { try { DbModel model = db.findDbModelFirst(new SqlInfo("select * from person")); Log.e("age", model.getString("age")); } catch (DbException e) { e.printStackTrace(); } }
注意上面的sqlInfo對象的創建的構造參數只需要傳入一個sql語句即可。
6.findDbModelAll的用法
該方法的用途就是返回滿足sqlInfo信息的所有數據的字段的一個集合。
需求:查找person表中年齡age大於25裡面的所有人的姓名
private void query() { try { List<DbModel> persons = db.findDbModelAll(new SqlInfo("select * from person where age > 25")); for(DbModel person:persons){ Log.e("name", person.getString("name")); } } catch (DbException e) { e.printStackTrace(); } }
基本把查詢的6種方式都說了一遍,當然上面的6種需求不一定完全用上面的查詢方法可以查出結果,我這麼查詢的目的主要是帶領大家熟悉一下XUtils3的6種查詢方法是如何使用的,會了上面的6種方法,我相信你的查詢不會有太大問題,至於復雜的查詢無非就是sql語句的基本功力了,大家趕緊動手操練一下吧。
修改操作
當前數據庫中的表的效果如下:
修改一共有2種方法:
第一種:
需求:我們把上面的id為1的這條記錄的age修改為25歲
private void update() { try{ PersonTable person = db.findById(PersonTable.class, 1); person.setAge(25); db.update(person, "age"); }catch(Exception e){ e.printStackTrace(); } }
通過方法,我們知道首先要通過DBManager通過查找的方法先找到id為1的這個實體bean,如果你對裡面的哪個字段需要修改,只需要重新set這個屬性的值,然後調用DBManager.update方法,第一個參數是需要修改的實體,第二個參數是對應的屬性。
第二種:
需求:將person表中性別為man的工資salary都變成6000。
private void update() { try { List<PersonTable> persons = db.findAll(PersonTable.class); for(PersonTable person:persons){ person.setSalary(6000); db.update(person, WhereBuilder.b("sex", "=", "man"), "salary"); } } catch (Exception e) { e.printStackTrace(); } }
修改數據一共就2種方法,基本都是需要一個實體bean對象去進行操作的,上面的第二種方法無非就是在修改數據時,多了一個限制條件,這樣修改數據顯得靈活一些。
上面第二種update的方法的參數簡單介紹一下:
第一個參數:實體bean對象
第二個參數:一個WhereBuilder對象,主要是通過靜態b方法去構造一個where條件語句
第三個參數:需要修改的字段名,如果你的需求是修改了2個或者更多個字段,只需要在後面加上相應的參數即可,例如第二種方法我不止修改salary還需要修改age統一為40歲,參考如下;
private void update() { try { List<PersonTable> persons = db.findAll(PersonTable.class); for(PersonTable person:persons){ person.setSalary(6000); person.setAge(40); db.update(person, WhereBuilder.b("sex", "=", "man"), "salary","age"); } } catch (Exception e) { e.printStackTrace(); } }
刪除操作
當前數據庫中的person表的效果如下:
1.deleteById的用法
該方法主要是根據表的主鍵進行單條記錄的刪除
需求:刪除上方person表中id為5的記錄
private void delete() { try { db.deleteById(PersonTable.class, 5); } catch (DbException e) { e.printStackTrace(); } }
結果如下:
2.delete(Object entity)的用法
該方法主要是根據實體bean進行對表裡面的一條或多條數據進行刪除
需求:刪除name為駱駝這條信息的記錄
private void delete() { try { PersonTable person = db.selector(PersonTable.class).where("name", "=", "駱駝").findFirst(); db.delete(person); } catch (DbException e) { e.printStackTrace(); } }
3.delete(Class<?> entityType)
該方法主要是用來刪除表格裡面的所有數據,但是注意:表還會存在,只是表裡面數據沒有了
private void delete() { try { db.delete(PersonTable.class); } catch (DbException e) { e.printStackTrace(); } }
4.delete(Class<?> entityType, WhereBuilder whereBuilder)
該方法主要是根據where語句的條件進行刪除操作
需求:將person表總sex為woman並且salary為5000的信息刪除
private void delete() { try { db.delete(PersonTable.class, WhereBuilder.b("sex", "=", "woman").and("salary", "=", "5000")); } catch (DbException e) { e.printStackTrace(); } }
5.dropTable(Class<?> entityType)
該方法是用來刪除表
private void delete() { try { db.dropTable(PersonTable.class); } catch (DbException e) { e.printStackTrace(); } }
6.dropDb()
該方法是用來刪除數據庫
db.dropDb();
其他方法
1.addColumn(Class<> entityType, String column)
需求:在上方表中加入一個country字段
PersonTable的實體代碼如下:
@Table(name="person") public class PersonTable { @Column(name="id",isId=true,autoGen=true) private int id; //姓名 @Column(name="name") private String name; //年齡 @Column(name="age") private int age; //性別 @Column(name="sex") private String sex; //工資 @Column(name="salary") private int salary; //國家 @Column(name="country",property="中國") private String country; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } @Override public String toString() { return "PersonTable [id=" + id + ", name=" + name + ", age=" + age + ", sex=" + sex + ", salary=" + salary + ", country=" + country + "]"; } } private void addColumn() { try { db.addColumn(PersonTable.class, "country"); } catch (DbException e) { e.printStackTrace(); } }
執行完addColumn方法,我們看到person表裡面多了一個country字段.
結果如下:
總結
上面主要介紹了XUtils3的數據庫模塊,包括如何創建數據庫,如何創建表,如何給表進行添加一列,如何對表進行增刪查改的操作。說了這麼多,相信大家肯定對XUtils3的數據庫模塊有了一個基本的理解,至於一表對一表,多表對一表,多表對多表等等這類需求,無非就是在某個表裡面加入一個字段,或者創建一個第三方表用來維護表與表之間的關系,這種類型的例子我就不舉例說明了,原因是那些需求都離不開上面的增刪查改的方法,我相信你只要把上面的方法完全會用,你的XUtils3的數據庫模塊的基本使用就不會有問題了。
用過android手機的人都知道android使用app的時候屏幕上方的狀態欄都是黑色的,就算不是黑色的都與正在打開的app顏色不同。有一種灰常不搭調的感覺。
前言最經研究了一下拖拽排序的ListView,跟酷狗裡的播放列表排序一樣,但因為要添加自己特有的功能,所以研究了好長時間。一開始接觸的是GitHub的開源項目&mdash
多線程案例——計時器 這個案例中,屏幕啟動之後,進入如圖所示的界面。 屏幕上有一個文本框用於顯示逝去的時間,此外還有一個“停止計時”按鈕。案例的用例圖如圖所示。 &nbs
RelativeLayout是相對布局控件:以控件之間相對位置或相對父容器位置進行排列。相對布局常用屬性:子類控件相對子類控件:值是另外一個控件的idandroid:la