当前位置: 首页 > article >正文

【Android】GreenDao数据库的使用方式

需求

使用GreenDao数据库进行数据的存储。

介绍

GreenDao 是一个轻量级的对象关系映射(ORM)库,用于简化 Android 应用中的数据库操作。它提供了以下主要功能:

简化数据库操作:通过注解定义实体类,GreenDao 自动生成 DAO(数据访问对象)类,简化了数据库的增、删、改、查操作。

高性能:GreenDao 设计目标之一是高效地执行数据库操作,尤其在处理大量数据时表现出色。

自动生成代码:通过编译时生成代码,减少了手动编写 SQL 和数据处理逻辑的需要。

事务支持:支持数据库事务,确保数据操作的原子性和一致性。

灵活性:可以通过自定义查询和批量操作,满足复杂的数据处理需求。

小巧:库体积小,适合需要轻量级 ORM 的应用。

集成

在 build.gradle 文件中添加 GreenDao 依赖:

implementation 'org.greenrobot:greendao:3.3.0'

配置 build.gradle 以生成 DAO 类。添加插件和配置:

apply plugin: 'org.greenrobot.greendao'

greendao {
    schemaVersion 1 //定义数据库的版本号,用于处理数据库升级。
    daoPackage 'com.example.dao' //指定生成的 DAO 类包名。
    targetGenDir 'src/main/java' //指定生成的实体类包名。
}
使用

创建实体类:
使用 GreenDao 提供的注解定义实体类。举例:

@Entity
public class UpdateBean{
     @Id(autoincrement = true)
    private Long id;
    private String name;

    // getters and setters
}

创建实体类之后,使用Build重新构建一下项目,然后会自动生成相关文件
【DaoMaster】【DaoSession】【UpdateBeanDao】

创建一个帮助类 【UpdateOpenHelper】

public class UpdateOpenHelper extends DaoMaster.OpenHelper {

    public UpdateOpenHelper(Context context, String name) {
        super(context, name);
    }

    public UpdateOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
        super(context, name, factory);
    }

    @Override
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        DaoMaster.dropAllTables(wrap(db), true);
    }
    
    @Override
    public void onUpgrade(Database db, int oldVersion, int newVersion) {
        super.onUpgrade(db, oldVersion, newVersion);
    }
}

创建一个管理类【UpdateManager 】

public class UpdateManager {

    private Context mContext;
    private static UpdateManager manager = new UpdateManager();
    private static ConcurrentHashMap<String, DaoMaster> masterMap = new ConcurrentHashMap<>();
    private static ConcurrentHashMap<String, DaoSession> daoSessionMap = new ConcurrentHashMap<>();
    private static ConcurrentHashMap<String, UpdateOpenHelper> helperMap = new ConcurrentHashMap<>();

    public static UpdateManager getInstance() {
        return manager;
    }

    public void init(Context context) {
        this.mContext = context;
    }

    private DaoMaster getDaoMaster(String dbName) {
        if (!masterMap.containsKey(dbName)) {
            UpdateOpenHelper openHelper = helperMap.get(dbName);
            if (openHelper == null) {
                UGDaoContext daoContext = new UGDaoContext(mContext);
                openHelper = new UpdateOpenHelper(daoContext, dbName, null);
                helperMap.put(dbName, openHelper);
            }
            DaoMaster master;
            try {
                master = new DaoMaster(openHelper.getWritableDatabase());
                masterMap.put(dbName, master);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return masterMap.get(dbName);
    }


    public DaoSession getDaoSession(String dbName) {
        if (!daoSessionMap.containsKey(dbName)) {
            DaoMaster master = getDaoMaster(dbName);
            if (master != null) {
                DaoSession session = master.newSession();
                daoSessionMap.put(dbName, session);
            }
        }
        return daoSessionMap.get(dbName);
    }

    /**
     * 关闭指定数据库连接
     *
     * @param dbName 数据库名字
     */
    public void closeConnection(String dbName) {
        DaoSession session = daoSessionMap.get(dbName);
        if (session != null) {
            session.clear();
            daoSessionMap.remove(dbName);
        }
        DaoMaster master = masterMap.get(dbName);
        if (master != null) {
            master = null;
            masterMap.remove(dbName);
        }
        UpdateOpenHelper helper = helperMap.get(dbName);
        if (helper != null) {
            helper.close();
            helperMap.remove(dbName);
        }
    }

    /**
     * 关闭所有数据库连接
     */
    public void closeAllConnection() {
        // 关闭所有DaoSessions
        synchronized (this) {
            for (String dbName : daoSessionMap.keySet()) {
                closeConnection(dbName); // 关闭每一个连接
            }
            // 额外步骤:清理所有映射
            daoSessionMap.clear();
            masterMap.clear();
            helperMap.clear();
        }
    }

}

还有需要修改数据库的文件的存储路径,GreenDao数据库默认的存储路径是在应用内部私有存储,所以如果删除了应用之后,数据文件也会被删除,同时也不利于外部查找数据库文件。

创建【UGDaoContext】修改数据库文件地址

public class UGDaoContext extends ContextWrapper {

    public UGDaoContext(Context base) {
        super(base);
    }

    @Override
    public File getDatabasePath(String name) {
        String dbDir;
        boolean isExistSDCar = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        if (isExistSDCar) {
            dbDir = Environment.getExternalStorageDirectory().getAbsolutePath();
        } else {
            dbDir = Environment.getDataDirectory().getAbsolutePath();
        }
        String dbDirPath = dbDir + File.separator + "app_dao" + File.separator + "data_update";

        Log.d("TAG", "数据库的文件夹地址:" + dbDirPath);
        File dbDirFile = new File(dbDirPath);
        if (!dbDirFile.exists()) {
            dbDirFile.mkdirs();
        }
        String dbNamePath = dbDirPath + File.separator + name;
        File dbNameFile = new File(dbNamePath);
        boolean isSuccess = false;
        if (!dbNameFile.exists()) {
            try {
                isSuccess = dbNameFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            isSuccess = true;
        }
        if (isSuccess) {
            Log.d("TAG", "数据库的文件地址:" + dbNamePath);
            return dbNameFile;
        } else {
            return super.getDatabasePath(name);
        }
    }

    @Override
    public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory) {
        return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null);
    }

    @Override
    public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
        return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null);
    }
}

接下里再创建一个工具类实现对数据库的操作【UpdateDaoUtil】

public class UpdateDaoUtil {

    private UpdateManager manager;

    public UpdateDaoUtil(Context context) {
        manager = UpdateManager.getInstance();
        manager.init(context);
    }

    /**
     * 完成UpdateBean记录的插入
     */
    public synchronized boolean insertUpdate(UpdateBean updateBean, String dbName) {
        boolean flag = false;
        if (manager.getDaoSession(dbName).getUpdateBeanDao().insert(updateBean) != -1) {
            flag = true;
        }
        return flag;
    }

    /**
     * 完成UpdateBean记录的插入
     */
    public synchronized boolean insertUpdate(UpdateBean updateBean) {
        boolean flag = false;
        if (manager.getDaoSession(getCurrentDBName()).getUpdateBeanDao().insert(updateBean) != -1) {
            flag = true;
        }
        return flag;
    }


    /**
     * 完成UpdateBean列表记录的插入
     */
    public synchronized boolean insertUpdate(List<UpdateBean> list) {
        int frequency = 0;
        UpdateBeanDao dao = manager.getDaoSession(getCurrentDBName()).getUpdateBeanDao();

        for (UpdateBean updateBean : list) {
            if (dao.insert(updateBean) == -1) {
                frequency++;
            }
        }
        return frequency == 0;
    }


    /**
     * 删除单条记录
     */
    public synchronized boolean deleteUpdateBean(UpdateBean updateBean, String dbName) {
        boolean flag = false;
        try {
            manager.getDaoSession(dbName).delete(updateBean);
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 删除单条记录
     */
    public synchronized boolean deleteUpdateBean(UpdateBean updateBean) {
        boolean flag = false;
        try {
            manager.getDaoSession(getCurrentDBName()).delete(updateBean);
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }


    /**
     * 删除所有记录
     */
    public synchronized boolean deleteAll(String dbname) {
        boolean flag = false;
        try {
            manager.getDaoSession(dbname).deleteAll(UpdateBean.class);
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 删除所有记录
     */
    public synchronized boolean deleteAll() {
        boolean flag = false;
        try {
            manager.getDaoSession(getCurrentDBName()).deleteAll(UpdateBean.class);
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }


    /**
     * 查询数据库前 number 条数据
     */
    public synchronized List<UpdateBean> queryDataNumber(int number, String dbname) {
        QueryBuilder<UpdateBean> queryBuilder = manager.getDaoSession(dbname).queryBuilder(UpdateBean.class);
        return queryBuilder.limit(number).list();
    }

    /**
     * 查询数据库前 number 条数据
     */
    public synchronized List<UpdateBean> queryDataNumber(int number) {
        QueryBuilder<UpdateBean> queryBuilder = manager.getDaoSession(getCurrentDBName()).queryBuilder(UpdateBean.class);
        return queryBuilder.limit(number).list();
    }


    /**
     * 删除数据库前 number 条数据
     */
    public synchronized void deleteDataNumber(int number, String dbname) {
        UpdateBeanDao dao = manager.getDaoSession(dbname).getUpdateBeanDao();
        List<UpdateBean> lists = dao.queryBuilder().limit(number).list();
        dao.deleteInTx(lists);
    }

    /**
     * 删除数据库前 number 条数据
     */
    public synchronized void deleteDataNumber(int number) {
        UpdateBeanDao dao = manager.getDaoSession(getCurrentDBName()).getUpdateBeanDao();
        List<UpdateBean> lists = dao.queryBuilder().limit(number).list();
        dao.deleteInTx(lists);
    }


    /**
     * 查询所有记录
     */
    public synchronized List<UpdateBean> queryAll(String dbName) {
        return manager.getDaoSession(dbName).loadAll(UpdateBean.class);
    }


    /**
     * 查询所有记录
     */
    public synchronized List<UpdateBean> queryAll() {
        return manager.getDaoSession(getCurrentDBName()).loadAll(UpdateBean.class);
    }





    /**
     * 使用指定名称的数据库,每次查询200条未上传的数据
     *
     * @param dbname 数据库表名称
     */
    public synchronized List<UpdateBean> queryListUpdate(String dbname) {
        QueryBuilder<UpdateBean> queryBuilder = manager.getDaoSession(dbname).queryBuilder(UpdateBean.class);
        return queryBuilder.where(UpdateBeanDao.Properties.IsUpdate.eq(0)).limit(200).list();
    }

    /**
     * 更新是否上传状态
     *
     * @param list 上传数据的ID的list
     */
    public synchronized void updateStatus(List<Long> list) {
        DaoSession daoSession = manager.getDaoSession(getCurrentDBName());
        UpdateBeanDao updateBeanDao = daoSession.getUpdateBeanDao();
        try {
            daoSession.runInTx(() -> {
                for (Long id : list) {
                    UpdateBean bean = updateBeanDao.load(id);
                    if (bean != null) {
                        bean.setIsUpdate(1);
                        updateBeanDao.update(bean);
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 更新是否上传状态
     *
     * @param dbName 数据库表名字
     * @param list   上传数据的ID的list
     */
    public synchronized void updateStatus(String dbName, List<Long> list) {
        DaoSession daoSession = manager.getDaoSession(dbName);
        UpdateBeanDao updateBeanDao = daoSession.getUpdateBeanDao();
        try {
            daoSession.runInTx(() -> {
                for (Long id : list) {
                    UpdateBean bean = updateBeanDao.load(id);
                    if (bean != null) {
                        bean.setIsUpdate(1);
                        updateBeanDao.update(bean);
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 使用queryBuilder进行查询未上传的数据
     */
    public synchronized List<UpdateBean> queryItemByQueryBuilder(int isUpdate) {
        QueryBuilder<UpdateBean> queryBuilder = manager.getDaoSession(getCurrentDBName()).queryBuilder(UpdateBean.class);
        return queryBuilder.where(UpdateBeanDao.Properties.IsUpdate.eq(isUpdate)).limit(100).list();
    }




    /**
     * 关闭当前日期资源
     */
    public synchronized void close() {
        manager.closeConnection(getCurrentDBName());
    }

    /**
     * 关闭特定名字的数据资源
     */
    public synchronized void close(String dbName) {
        manager.closeConnection(dbName);
    }

    /**
     * 关闭所有连接
     */
    public synchronized void closeAll() {
        manager.closeAllConnection();
    }

    /**
     * 数据表的名称是当天的日期
     *
     * @return 当天日期
     */
    private static String getCurrentDateFormatted() {
        long currentTimeMillis = System.currentTimeMillis();
        Date date = new Date(currentTimeMillis);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
        return sdf.format(date);
    }

    /**
     * 获取当天数据库表的名称
     */
    private static String getCurrentDBName() {
        return getCurrentDateFormatted() + "_db";
    }

    /**
     * 组装数据库名字
     *
     * @param dateTime 日期时间 例如 20240814
     */
    public static String setDBName(String dateTime) {
        return dateTime + "_db";
    }
}

这样基本上一个数据库就创建了,剩下就是如何使用了。

UpdateDaoUtil updateDaoUtil;
updateDaoUtil = new UpdateDaoUtil(this);
   if (updateDaoUtil != null) {
                    Log.i("TAG", "将List数据存入本地数据库,存入条数 " + updateBeanList.size());
                    List<UpdateBean> list = new ArrayList<>(updateBeanList);
                    boolean update = updateDaoUtil.insertUpdate(list);
                    if (update) {
                        Log.i("TAG", "数据存入数据库正常");
                  
                    }
                }

记得销毁

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (updateDaoUtil != null) {
            updateDaoUtil.closeAll();
        }
    }

GreenDao数据库的基本使用方式就是这样了。


http://www.kler.cn/a/300226.html

相关文章:

  • MDX语言的语法糖
  • HarmonyOS NEXT:华为分享-碰一碰开发分享
  • vulnhub靶场【IA系列】之Tornado
  • 工业网口相机:如何通过调整网口参数设置,优化图像传输和网络性能,达到最大帧率
  • 【服务器】Ubuntu22.04配置静态ip
  • 内网渗透测试工具及渗透测试安全审计方法总结
  • 三菱机器人手柄维修示教器维修手操器面板等
  • Centos7.9部署Gitlab-ce-16.9
  • python列表判断是否为空的三种方式
  • 数据结构(邓俊辉)学习笔记】排序 5——选取:通用算法
  • JavaScript语言基础知识
  • fastjson漏洞--以运维角度进行修复
  • kafka单机安装
  • linux运维常见命令行
  • vulhub spring 远程命令执行漏洞(CVE-2016-4977)
  • 当 PLC 遇见 “IT”
  • R语言数据整理和分析(1)
  • 栈---java--黑马
  • Git的Rebase操作,手动merge时主分支的提交记录的保留规则
  • 【Redis】redis5种数据类型(list)
  • vue如何获取一个元素的基本信息
  • 15 章 在微服务中服务众多如何实践他们复杂的依赖关系进行 helm安装
  • Robust Image Denoising through Adversarial Frequency Mixup
  • SPI驱动学习四(通过SPI操作外设模块)
  • QT作业3
  • SprinBoot+Vue宠物店管理系统的设计与实现