Android XUtils3框架的基本使用方法(二)
上一篇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的数据库模块的基本使用就不会有问题了。