【Android】GreenDao 3.X 结合Volley以及Gson、ImageLoader实现数据存储

来源:互联网 发布:陈坤孩子的母亲知乎 编辑:程序博客网 时间:2024/06/18 11:16

关于GreenDao的优点已经不用再说了,关于第三方数据库框架有很多,相对于Android系统本身的SQLite以及其它第三方而言,我感觉GreenDao使用更方便,体积小、速度更快。网上大多是关于GreenDao之前版本的介绍,关于3.0+新版的介绍不多。GreenDao新版改动还是挺大的,之前版本使用起来比较复杂,需要新建项目,然后再项目中配置各个实体的字段等相关属性,然后生成实体以及DAO操作相关的一些类。而GreenDao3.0及其以后是通过注解的方式定义实体类,并且是通过插件来生成相应代码。
数据库应用的场景也非常多,比如:电商类app中最常见的就是搜索的历史记录等等,使用数据库进行增删改查就相对方便多了,并且GreenDao提供了数据库加密设置,更加安全。
先来张效果图
这里写图片描述

再看下我们通过@Entity设置的实体类中的字段在数据库中对应的字段以及相应的存储数据
这里写图片描述

这里说明一下:此demo演示的场景是,有网时,联网请求数据,请求成功后将数据保存到GreenDao数据库,没网时,则从数据库中取数据。访问数据接口采用的是Volley框架,当然了你还可以使用OkHttp等,采用Gson解析方式,或者采用阿里的FastJson,两种解析方式差不多,在设计实体类的时候要注意下,字段什么的要跟服务端给你的json串中字段相同,从而操作更加简单。其中请求接口返回三条数据,这里解释下为什么第二条数据没有图片,这不是Bug。。。这是因为第二条数据压根就没给图片,就是这么任性,所以说有时间还是要学学后端的,这样就可以自己写服务端了,测试起来也方便。由于接口返回数据比较多,这里主要是演示GreenDao3.0X数据库保存数据,这里我只是解析了部分字段,保存的时候也只是保存了两文本字段,图片相对麻烦就没有保存,正式开发的话是保存到缓存中的。

下面还是说下怎么使用新版GreenDao3.X 吧,先给出官网github地址:https://github.com/greenrobot/greenDAO

首先我们需要在Gradle中添加如下配置

//首先在project的gradle文件中引入greenDAO插件buildscript {    repositories {        mavenCentral()    }    dependencies {        classpath 'org.greenrobot:greendao-gradle-plugin:3.0.0'    }}//然后在module的gradle文件中添加greenDAO的插件,并引入相关类库apply plugin: 'org.greenrobot.greendao'dependencies {    compile 'org.greenrobot:greendao:3.0.0'}

最新版本是3.2.0,这里说下为什么我没用3.2.0版本,因为使用此版本编译一直报可奇怪的错,这里选用3.0.0也一样,主要就是为了说明跟之前2.X版本的区别。其中,我们看到classpath ‘org.greenrobot:greendao-gradle-plugin:3.0.0’这是添加插件的,用插件生成我们的相应代码用的。

同时,我们还可以配置当插件根据我们所定义的实体类自动生成的DaoMaster、DaoSession以及实体类相对应的XXXDAO类文件的存放目录。

greendao {    schemaVersion 1    daoPackage 'com.example.testproject.greendao.gen'    targetGenDir 'src/main/java'}

说明:schemaVersion:表示指定数据库schema版本号,如果需要数据库升级,可以在这里修改数据库最新版本号。 daoPackage:表示生成的这些类文件在哪个包下面(默认为你的entity所在的包名)。 targetGenDir:就是上面所说的制定这些类文件所在的目录,这里我们设置跟我们代码目录相同,都是在java目录中,方便查看。

我们接下来写我们的实体类(ProductBean),这些实体类中的字段是要写进数据库的,就相当于一张表(ProductBean表)。写完之后我们选择Build–>Make Project,剩下的就交给插件了,就会自动帮我们生成(每次修改字段啥的,不要忘记Build–>Make Project), 如下图所示:

这里写图片描述

/** * 实体类,存储到数据库 */@Entitypublic class ProductBean {    private Long id;    @Property(nameInDb = "url")    private String picUrl;    @Property(nameInDb = "title")    private String proTitle;    @Property(nameInDb = "info")    private String proInfo;    @Property(nameInDb = "proId")    @Id    private Long proId;}    

这里有几点需要注意:GreenDao3.X 要求主键必须是Long或者long类型的。这里由于接口请求的数据中含有一个id,所以我就用这个id作为主键,当然这个id是String类型的,需要转换下。@Id:表示作为主键 @Property(nameInDb = “url”):表示该字段在数据库中的字段名称,还有很多属性,大家可以到官网上去了解,最后别忘了在定义实体类上面要加上@Entity因为插件要根据它生成相应的DAO。定义的有些字段是没用到的,大家测试的时候也可以自行删除。

GreenDao3.X 配置完了,接下来就是撸代码了。官方推荐将DaoMaster 对象的方法放到 Application 层,这样将避免多次创建生成 Session 对象。下面看下我们的application

/** * 自定义MyApplication */public class MyApplication extends Application {    private static MyApplication myApplication;    public RequestQueue requestQueue;    private static DaoMaster daoMaster;    private static DaoSession daoSession;    @Override    public void onCreate() {        super.onCreate();        myApplication = this;        //创建队列        requestQueue = Volley.newRequestQueue(this);    }    public static DaoMaster getDaoMaster(Context context){        if(daoMaster == null){            DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context,"mydata-db",null);            daoMaster = new DaoMaster(helper.getWritableDatabase());        }        return daoMaster;    }    public static DaoSession getDaoSession(Context context){        if(daoSession == null){            if(daoMaster == null){                daoMaster = getDaoMaster(context);            }            daoSession = daoMaster.newSession();        }        return daoSession;    }    public static MyApplication getApplication() {        return myApplication;    }}

关于增、删、改、查,这些就比较简单了。这里简单说下,首先,我们先获取DaoSession,从而来操作数据库。查看源代码可以看到,GreenDao的一些例如:增、删等操作内部已经封装处理了事务回滚等操作,我们使用起来更加方便。

ProductBeanDao dao = MyApplication.getDaoSession(MainActivity.this).getProductBeanDao();

1. 插入(批量添加时属于耗时操作,GreenDao提供的有异步操作方法runInTx()方法)

ProductBean productBean = new ProductBean(null,null,productData.getName(),productData.getInfo(),Long.parseLong(productData.getId()));dao.insert(productBean);//dao.insertOrReplace(productBean);//批量添加的情况(注意try的位置)final List<ProductBean> lists = new ArrayList<ProductBean>();for(int i=0;i<20;i++){    ProductBean productBean = new ProductBean();    productBean.setProTitle(xxxx);    productBean.setProInfo(xxxx);    lists.add(productBean);    }   try {      MyApplication.getDaoSession(MainActivity.this).runInTx(new Runnable() {      @Override      public void run() {      for(ProductBean bean : lists){           MyApplication.getDaoSession(MainActivity.this).insertOrReplace(bean);                                            }     }   }); }catch (Exception e){         e.printStackTrace(); }

2. 删除(删之前要先查一下,删除的方法有很多,可以删单条数据,也可以全部删除等等)

ProductBean bean = dao.queryBuilder().where(ProductBeanDao.Properties.ProTitle.eq("中青年抗癌互助计划")).build().unique();                    if(bean != null){                        dao.delete(bean);                    }

3. 修改

ProductBean bean = dao.queryBuilder().where(ProductBeanDao.Properties.ProTitle.eq("中青年抗癌互助计划")).build().unique();if(bean != null){      bean.setProTitle("修改title");      dao.update(bean);     }

4. 查询(可以写多个查询条件where,可以设置升序(orderAsc)、降序排列,limit:限制用于显示查询数据的数量,这里只要求显示3条数据,list():表示查询结果为一个集合, 当然了,还可以查单条数据unique())

List<ProductBean> lists = dao.queryBuilder()                            .where(ProductBeanDao.Properties.ProId.eq(3))                            .where(.......)                            .orderAsc(ProductBeanDao.Properties.ProId)                            .limit(3)                            .build().list();

最后看下MainActivity的全部代码(这里我没有采用id自增长的方式(不然数据会添加重复数据),而是用返回数据中的id作为主键,并且采用dao.insertOrReplace(productBean)的方式防止重复添加,不能使用dao.insert(),因为主键不可重复,这样当再次点击按钮添加重复的数据就会报错。仅是测试,情景不同,具体情况具体对待)

public class MainActivity extends AppCompatActivity {    private ListView listView;    private ProductAdapter adapter;    private List<ListProBean> lists;    private Button btnRequest;    private static final  String url = "http://test.xinlechou.com/index.php?r=api/insuranceList";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //初始化控件        iniViews();        getRequestDatas();    }    private void iniViews() {        listView = (ListView) findViewById(R.id.listView);        btnRequest = (Button) findViewById(R.id.btn_request);    }    public void getRequestDatas() {        btnRequest.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //数据库,获取DAO                final ProductBeanDao dao = MyApplication.getDaoSession(MainActivity.this).getProductBeanDao();                if(NetUtil.isNetConnected(MainActivity.this)){                    //volley请求数据                    StringRequest request = new StringRequest(url, new Response.Listener<String>() {                        @Override                        public void onResponse(String response) {                            Gson gson = new Gson();                            ListProBean bean = gson.fromJson(response,ListProBean.class);                            if(bean.getError() == 0){                                ArrayList<ProductData> datas = bean.getData();                                adapter = new ProductAdapter(MainActivity.this,datas);                                listView.setAdapter(adapter);                                //将数据保存到greendao数据库                                for(int i=0;i<datas.size();i++){                                    ProductData productData = datas.get(i);                                    ProductBean productBean = new ProductBean(null,null,productData.getName(),productData.getInfo(),Long.parseLong(productData.getId()));                                    //插入数据库                                   // boolean flag = dao.insert(productBean) != -1 ? true : false;                                    boolean flag = dao.insertOrReplace(productBean) != -1 ? true : false;                                    if(flag){                                        Log.i("TAG","插入成功:"+i);                                    }else{                                        Log.i("TAG","插入失败:"+i);                                    }                                }                            }                        }                    }, new Response.ErrorListener() {                        @Override                        public void onErrorResponse(VolleyError error) {                            //打印错误信息                        }                    });                    //将请求放到队列中                    MyApplication.getApplication().requestQueue.add(request);                }else{                    Toast.makeText(MainActivity.this,"没有联网哟",Toast.LENGTH_SHORT).show();                    //查数据库                    List<ProductBean> lists = dao.queryBuilder().build().list();                    if(lists != null && lists.size() > 0){                        Toast.makeText(MainActivity.this,"从数据库中读取数据",Toast.LENGTH_SHORT).show();                        List<ProductData> productDatas = new ArrayList<ProductData>();                        for(int i=0;i<lists.size();i++){                            ProductBean productBean = lists.get(i);                            String title = productBean.getProTitle();                            String info = productBean.getProInfo();                            ProductData productData = new ProductData();                            productData.setName(title);                            productData.setInfo(info);                            productDatas.add(productData);                        }                        adapter = new ProductAdapter(MainActivity.this,productDatas);                        listView.setAdapter(adapter);                    }                }            }        });    }}

当然了,这里主要介绍了GreenDao3.X 的一些基本使用,还有一些更加深入的知识点,比如:表与表之间的一对一、一对多等映射关系,以及我们要进行数据库升级等操作,我们要自定义OpenHelper继承DaoMaster.DevOpenHelper重写onUpgrade()方法,不然数据库在更新的时候就会新建表,原数据就会丢失。对于这些知识点目前没有深究,以后用到了,我再加以补充,希望能对大家有所帮助,如果发现讲述的有问题,欢迎指出

源码地址:点击下载源码

最后给出查看数据库的一个工具下载地址:http://www.sqliteexpert.com/

0 0
原创粉丝点击