XUtils===XUtils3框架的基本使用方法(二)

转载自:http://blog.csdn.net/a1002450926/article/details/50364196


上一篇文章,主要介绍了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 删除数据库

插入操作

<span style="font-size:18px;">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();
        }
    }</span>
结果如下:

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对象,那么该对象是什么呢?
DbModel源码如下:

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的数据库模块的基本使用就不会有问题了。


  • 8
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
xUtils 包含了很多实用的android工具. xUtils 支持超大文件(超过2G)上传,更全面的http请求协议支持(11种谓词),拥有更加灵活的ORM,更多的事件注解支持且不受混淆影响... xUtils 最低兼容Android 4.0 (api level 14). (Android 2.3?) xUtils3变化较多所以建立了新的项目不在旧版(github.com/wyouflf/xUtils)上继续维护, 相对于旧版本: HTTP实现替换HttpClient为UrlConnection, 自动解析回调泛型, 更安全的断点续传策略. 支持标准的Cookie策略, 区分domain, path. 事件注解去除不常用的功能, 提高性能. 数据库api简化提高性能, 达到和greenDao一致的性能. 图片绑定支持gif, webp; 支持圆角, 圆形, 方形等裁剪, 支持自动旋转... 使用Gradle构建时添加一下依赖即可: compile 'org.xutils:xutils:3.1.+' // or // compile 'org.xutils:xutils:3.1.15' 如果使用eclipse可以 点击这里下载aar文件, 然后用zip解压, 取出jar包和so文件. 混淆配置参考示例项目sample的配置 使用前配置 需要的权限 初始化 // 在application的onCreate中初始化 @Override public void onCreate() { super.onCreate(); x.Ext.init(this); x.Ext.setDebug(true); // 是否输出debug日志 ... } 使用@Event事件注解(@ContentView, @ViewInject等更多示例参考sample项目) /** * 1. 方法必须私有限定, * 2. 方法以Click或Event结尾, 方便配置混淆编译参数 : * -keepattributes *Annotation* * -keepclassmembers class * { * void *(android.view.View); * *** *Click(...); * *** *Event(...); * } * 3. 方法参数形式必须和type对应的Listener接口一致. * 4. 注解参数value支持数组: value={id1, id2, id3} * 5. 其它参数说明见{@link org.xutils.event.annotation.Event}类的说明. **/ @Event(value = R.id.btn_test_baidu1, type = View.OnClickListener.class/*可选参数, 默认是View.OnClickListener.class*/) private void onTestBaidu1Click(View view) { ... } 访问网络(更多示例参考sample项目) /** * 自定义实体参数类请参考: * 请求注解 {@link org.xutils.http.annotation.HttpRequest} * 请求注解处理模板接口 {@link org.xutils.http.app.ParamsBuilder} * * 需要自定义类型作为callback的泛型时, 参考: * 响应注解 {@link org.xutils.http.annotation.HttpResponse} * 响应注解处理模板接口 {@link org.xutils.http.app.ResponseParser} * * 示例: 查看 org.xutils.sample.http 包里的代码 */ BaiduParams params = new BaiduParams(); params.wd = "xUtils"; // 有上传文件时使用multipart表单, 否则上传原始文件流. // params.setMultipart(true); // 上传文件方式 1 // params.uploadFile = new File("/sdcard/test.txt"); // 上传

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值