上一篇Android中XUtils3框架使用方法詳解(一)文章,主要介紹了XUtil3的注解模塊,網(wǎng)絡(luò)模塊,圖片加載模塊,今天給大家?guī)頂?shù)據(jù)庫模塊的講解,現(xiàn)在主流的ORM框架很多,比如OrmLite,GreenDao,Active Android,Realm等等,這些框架每個都有自己的優(yōu)點(diǎn)和缺點(diǎn),大家完全可以根據(jù)自己項(xiàng)目的實(shí)際需求進(jìn)行選擇,下面開始進(jìn)入今天的數(shù)據(jù)庫模塊的介紹。
今天主要給大家?guī)硪韵聨讉€模塊:
如何創(chuàng)建刪除一張表
如何對表進(jìn)行增刪查改操作
如何創(chuàng)建數(shù)據(jù)庫和刪除數(shù)據(jù)庫
如何建立一表對一表,多表對一表,多表對多表的外鍵操作。
相信對ORM框架有過了解的人,大概都知道只要創(chuàng)建一個JavaBean對象,在類的上面和屬性的上面添加注釋標(biāo)簽,這樣就能生成一個表。下面帶大家看一下XUtils3的實(shí)體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;}@Overridepublic String toString() {return "PersonTable [id=" + id + ", name=" + name + ", age=" + age+ ", sex=" + sex + ", salary=" + salary + "]";}}通過上方的實(shí)體bean,我們需要知道一個表對應(yīng)的實(shí)體bean需要注意以下幾點(diǎn):
1.在類名上面加入@Table標(biāo)簽,標(biāo)簽里面的屬性name的值就是以后生成的數(shù)據(jù)庫的表的名字
2.實(shí)體bean里面的屬性需要加上@Column標(biāo)簽,這樣這個標(biāo)簽的name屬性的值會對應(yīng)數(shù)據(jù)庫里面的表的字段。
3.實(shí)體bean里面的普通屬性,如果沒有加上@Column標(biāo)簽就不會在生成表的時候在表里面加入字段。
4.實(shí)體bean中必須有一個主鍵,如果沒有主鍵,表以后不會創(chuàng)建成功,@Column(name=”id”,isId=true,autoGen=true)這個屬性name的值代表的是表的主鍵的標(biāo)識,isId這個屬性代表的是該屬性是不是表的主鍵,autoGen代表的是主鍵是否是自增長,如果不寫autoGen這個屬性,默認(rèn)是自增長的屬性。
既然知道怎么寫實(shí)體bean了,下面看看如何在程序中創(chuàng)建一個數(shù)據(jù)庫和如何生成表的吧。
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() {@Overridepublic void onUpgrade(DbManager db, int oldVersion, int newVersion) {}});}return daoConfig;}}通過XUti.getDaoConfig()方法,我們能夠獲取到一個DaoConfig對象。通過getDaoConfig()方法,我們可以知道這個方法主要可以做以下事情:
1.setDbName 設(shè)置數(shù)據(jù)庫的名稱
2.setDbDir 設(shè)置數(shù)據(jù)庫存放的路徑
3.setDbVersion 設(shè)置數(shù)據(jù)庫的版本
4.setAllowTransaction(true) 設(shè)置允許開啟事務(wù)
5.setDbUpgradeListener 設(shè)置一個版本升級的監(jiān)聽方法
那么具體我們什么時候創(chuàng)建的表呢?如果我們單純的調(diào)用XUti.getDaoConfig()方法是不能夠創(chuàng)建PersonTable這個實(shí)體對應(yīng)的person這張表的,那么如何創(chuàng)建表呢?
只需要一下幾步:
1.DaoConfig daoConfig=XUtil.getDaoConfig();
2.DbManager db = x.getDb(daoConfig);
這里我要告訴大家的是,數(shù)據(jù)庫里面表的創(chuàng)建的時間,只有在你對數(shù)據(jù)庫里面的操作涉及到這張表的操作時,會先判斷當(dāng)前的表是否存在,如果不存在,才會創(chuàng)建一張表,如果存在,才會進(jìn)行相應(yīng)的CRUD操作,但是只要我們想進(jìn)行一張表的CRUD操作,我們必須先執(zhí)行上面的2步,通俗點(diǎn)說就是必須拿到一個Dbmanger這個對象,我為什么這么說呢?那么咱們就先看一下DbManger的廬山真面目吧。
DbManager部分源碼如下:
public interface DbManager extends Closeable {DaoConfig getDaoConfig();SQLiteDatabase getDatabase();/*** 保存實(shí)體類或?qū)嶓w類的List到數(shù)據(jù)庫,* 如果該類型的id是自動生成的, 則保存完后會給id賦值.** @param entity* @return* @throws DbException*/boolean saveBindingId(Object entity) throws DbException;/*** 保存或更新實(shí)體類或?qū)嶓w類的List到數(shù)據(jù)庫, 根據(jù)id對應(yīng)的數(shù)據(jù)是否存在.** @param entity* @throws DbException*/void saveOrUpdate(Object entity) throws DbException;/*** 保存實(shí)體類或?qū)嶓w類的List到數(shù)據(jù)庫** @param entity* @throws DbException*/void save(Object entity) throws DbException;/*** 保存或更新實(shí)體類或?qū)嶓w類的List到數(shù)據(jù)庫, 根據(jù)id和其他唯一索引判斷數(shù)據(jù)是否存在.** @param entity* @throws DbException*/void replace(Object entity) throws DbException;///////////// deletevoid 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;///////////// updatevoid 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;/*** 關(guān)閉數(shù)據(jù)庫,* xUtils對同一個庫的鏈接是單實(shí)例的, 一般不需要關(guān)閉它.** @throws IOException*/void close() throws IOException;///////////// customvoid 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 獲取數(shù)據(jù)庫的配置信息
2.getDatabase 獲取數(shù)據(jù)庫實(shí)例
3.saveBindingId saveOrUpdate save 插入數(shù)據(jù)的3個方法(保存數(shù)據(jù))
4.replace 只有存在唯一索引時才有用 慎重
5.delete操作的4種方法(刪除數(shù)據(jù))
6.update操作的2種方法(修改數(shù)據(jù))
7.find操作6種方法(查詢數(shù)據(jù))
8.dropTable 刪除表
9.addColumn 添加一列
10.dropDb 刪除數(shù)據(jù)庫
插入操作
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();}}結(jié)果如下:
3種插入操作所需要的參數(shù)都是一個實(shí)體bean。save和saveOrUpdate的區(qū)別就是當(dāng)一個實(shí)體里面的主鍵一樣時如果使用saveOrUpdate會將當(dāng)前主鍵對應(yīng)的這條數(shù)據(jù)進(jìn)行替換,而如果你使用了save就會報錯。
saveBindingId主要是存進(jìn)去的數(shù)據(jù)如果當(dāng)前表有主鍵回合主鍵進(jìn)行綁定關(guān)聯(lián)。
當(dāng)你執(zhí)行完這個方法后,你會看到數(shù)據(jù)庫里面person表里面多了一條數(shù)據(jù).
查詢操作
當(dāng)前數(shù)據(jù)庫中的表的效果如下:
1.findById的使用
該方法主要是通過主鍵的值來進(jìn)行查找表里面的數(shù)據(jù)
需求:查找上方person表里面id為3的數(shù)據(jù)
private void query(){try {PersonTable person = db.findById(PersonTable.class, "2");Log.e("person",person.toString());} catch (DbException e) {e.printStackTrace();}}結(jié)果如下:
2.findFirst的使用
該方法主要是返回當(dāng)前表里面的第一條數(shù)據(jù)
需求:查找上方person表里面的第一條數(shù)據(jù)
private void query() {try {PersonTable person = db.findFirst(PersonTable.class);Log.e("person", person.toString());} catch (DbException e) {e.printStackTrace();}}
3.findAll的使用
該方法主要是返回當(dāng)前表里面的所有數(shù)據(jù)
需求:查找person表里面的所有數(shù)據(jù)
private void query() {try {List<PersonTable> persons = db.findAll(PersonTable.class);Log.e("persons", persons.toString());} catch (DbException e) {e.printStackTrace();}}
4.selector的使用
該方法主要是用來進(jìn)行一些特定條件的查找
需求:查找person表里面age大于30并且性別為man的數(shù)據(jù)
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));}}通過源碼,我們分析發(fā)現(xiàn)DbModel本質(zhì)就是一個key為當(dāng)前表的字段,value為當(dāng)前某條記錄的值的一個HashMap.
需求:查找person表中第一條數(shù)據(jù)的那個人的年齡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對象的創(chuàng)建的構(gòu)造參數(shù)只需要傳入一個sql語句即可。
6.findDbModelAll的用法
該方法的用途就是返回滿足sqlInfo信息的所有數(shù)據(jù)的字段的一個集合。
需求:查找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種方式都說了一遍,當(dāng)然上面的6種需求不一定完全用上面的查詢方法可以查出結(jié)果,我這么查詢的目的主要是帶領(lǐng)大家熟悉一下XUtils3的6種查詢方法是如何使用的,會了上面的6種方法,我相信你的查詢不會有太大問題,至于復(fù)雜的查詢無非就是sql語句的基本功力了,大家趕緊動手操練一下吧。
修改操作
當(dāng)前數(shù)據(jù)庫中的表的效果如下:
修改一共有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的這個實(shí)體bean,如果你對里面的哪個字段需要修改,只需要重新set這個屬性的值,然后調(diào)用DBManager.update方法,第一個參數(shù)是需要修改的實(shí)體,第二個參數(shù)是對應(yīng)的屬性。
第二種:
需求:將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();}}
修改數(shù)據(jù)一共就2種方法,基本都是需要一個實(shí)體bean對象去進(jìn)行操作的,上面的第二種方法無非就是在修改數(shù)據(jù)時,多了一個限制條件,這樣修改數(shù)據(jù)顯得靈活一些。
上面第二種update的方法的參數(shù)簡單介紹一下:
第一個參數(shù):實(shí)體bean對象
第二個參數(shù):一個WhereBuilder對象,主要是通過靜態(tài)b方法去構(gòu)造一個where條件語句
第三個參數(shù):需要修改的字段名,如果你的需求是修改了2個或者更多個字段,只需要在后面加上相應(yīng)的參數(shù)即可,例如第二種方法我不止修改salary還需要修改age統(tǒng)一為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();}}刪除操作
當(dāng)前數(shù)據(jù)庫中的person表的效果如下:
1.deleteById的用法
該方法主要是根據(jù)表的主鍵進(jìn)行單條記錄的刪除
需求:刪除上方person表中id為5的記錄
private void delete() {try {db.deleteById(PersonTable.class, 5);} catch (DbException e) {e.printStackTrace();}}結(jié)果如下:
2.delete(Object entity)的用法
該方法主要是根據(jù)實(shí)體bean進(jìn)行對表里面的一條或多條數(shù)據(jù)進(jìn)行刪除
需求:刪除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)
該方法主要是用來刪除表格里面的所有數(shù)據(jù),但是注意:表還會存在,只是表里面數(shù)據(jù)沒有了
private void delete() {try {db.delete(PersonTable.class);} catch (DbException e) {e.printStackTrace(); }}4.delete(Class<?> entityType, WhereBuilder whereBuilder)
該方法主要是根據(jù)where語句的條件進(jìn)行刪除操作
需求:將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()
該方法是用來刪除數(shù)據(jù)庫
db.dropDb();
其他方法
1.addColumn(Class<> entityType, String column)
需求:在上方表中加入一個country字段
PersonTable的實(shí)體代碼如下:
@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;}@Overridepublic 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();}}執(zhí)行完addColumn方法,我們看到person表里面多了一個country字段.
結(jié)果如下:

總結(jié)
上面主要介紹了XUtils3的數(shù)據(jù)庫模塊,包括如何創(chuàng)建數(shù)據(jù)庫,如何創(chuàng)建表,如何給表進(jìn)行添加一列,如何對表進(jìn)行增刪查改的操作。說了這么多,相信大家肯定對XUtils3的數(shù)據(jù)庫模塊有了一個基本的理解,至于一表對一表,多表對一表,多表對多表等等這類需求,無非就是在某個表里面加入一個字段,或者創(chuàng)建一個第三方表用來維護(hù)表與表之間的關(guān)系,這種類型的例子我就不舉例說明了,原因是那些需求都離不開上面的增刪查改的方法,我相信你只要把上面的方法完全會用,你的XUtils3的數(shù)據(jù)庫模塊的基本使用就不會有問題了。
新聞熱點(diǎn)
疑難解答
圖片精選