GreenDao实现原理

GreenDao 是一款针对 Android 平台优化的轻量级对象关系映射 (ORM) 框架,它将 Java 对象映射到 SQLite 数据库,以简化数据持久化操作。GreenDao 的主要优点包括高性能、低内存占用、易于使用以及对数据库加密的支持。

以下是基于源码的 GreenDao 实现原理分析:

1. 代码生成

GreenDao 的一大特性是在编译阶段生成所有必要的 DAO(Data Access Object)类和相关辅助类,而不是在运行时通过反射来创建这些类。这意味着,当应用程序运行时,GreenDao 不再需要解析复杂的元数据或执行反射调用,从而提高了性能和响应速度。

生成过程:
  • 当你使用 GreenDao 时,你需要添加一个注解处理器依赖到你的项目中。
  • 编译时,GreenDao 的注解处理器会扫描带有特定注解(如 @Entity)的类。
  • 根据这些类的定义,处理器会生成 DAO 类、实体类的映射代码以及其他辅助类,例如 DaoMaster 和 DaoSession

2. DAO Master 和 DAO Session

  • DaoMaster:负责管理整个数据库环境,包括创建和升级数据库版本。DaoMaster 包含了 DevOpenHelper 的实例,用于数据库的创建和版本控制。
  • DaoSession:提供了一组方法用于访问和操作所有实体的 DAO。当你需要执行 CRUD 操作时,通常会通过 DaoSession 来获取特定实体的 DAO 实例。

3. 实体映射

每个被标记为 @Entity 的类都会被映射到一个数据库表。GreenDao 支持多种属性类型,包括基本数据类型、枚举、数组和集合等。通过 @Id 注解可以指定主键,而 @Unique 可以确保字段的唯一性。

4. 数据库操作

GreenDao 提供了一系列方法来执行常见的数据库操作,如 insert, update, delete, loadqueryBuilder。这些方法在 DAO 实例中定义,允许以面向对象的方式进行数据库操作。

5. 性能优化

GreenDao 使用了缓存机制来加速查询,通过缓存实体对象和 SQL 查询结果,减少了数据库的直接访问次数。此外,它还使用了代理模式和策略模式来封装不同的数据库操作,提供了良好的扩展性和维护性。

6. 加密支持

通过集成 SqlCipher 或 SQLite 的加密版本,GreenDao 可以提供数据库级别的加密功能,增强了数据的安全性。

7. 异步操作

GreenDao 支持 RxJava 集成,使得异步数据库操作变得更加简单和高效。

8.基本使用

第一步:项目配置

首先,你需要在你的项目中添加 GreenDao 的依赖。在你的模块级 build.gradle 文件中添加以下依赖:

Groovy

1dependencies {
2    implementation 'org.greenrobot:greendao:3.2.2'
3    kapt 'org.greenrobot:greendao:3.2.2' // kapt 用于处理注解处理器
4}

同时,在 build.gradle 文件中加入 GreenDao 插件配置:

Groovy

1apply plugin: 'com.android.application'
2apply plugin: 'kotlin-android'
3
4android {
5    // ...
6}
7
8dependencies {
9    // ...
10}
11
12greendao {
13    schemaVersion 1 // 数据库版本号
14    daoPackage 'com.example.yourapp.database' // Dao 包名
15    targetGenDir 'src/main/java' // 生成文件的目标目录
16}

第二步:定义实体类

接下来,定义 User 实体类,使用 GreenDao 的注解进行标注:

Java

1package com.example.yourapp.database;
2
3import org.greenrobot.greendao.annotation.Entity;
4import org.greenrobot.greendao.annotation.Id;
5import org.greenrobot.greendao.annotation.Generated;
6
7@Entity
8public class User {
9    @Id(autoincrement = true)
10    private Long id;
11    private String name;
12    private int age;
13
14    public User(String name, int age) {
15        this.name = name;
16        this.age = age;
17    }
18
19    public Long getId() {
20        return id;
21    }
22
23    public void setId(Long id) {
24        this.id = id;
25    }
26
27    public String getName() {
28        return name;
29    }
30
31    public void setName(String name) {
32        this.name = name;
33    }
34
35    public int getAge() {
36        return age;
37    }
38
39    public void setAge(int age) {
40        this.age = age;
41    }
42
43    @Generated(hash = 199499842)
44    public User(Long id, String name, int age) {
45        this.id = id;
46        this.name = name;
47        this.age = age;
48    }
49
50    @Generated(hash = 1669913653)
51    public User() {
52    }
53}

第三步:创建数据库

在你的应用程序中,你需要创建 DaoMasterDaoSession 的实例:

Java

1import org.greenrobot.greendao.database.Database;
2
3import android.content.Context;
4
5public class AppDatabase {
6    private static DaoMaster.DevOpenHelper helper;
7    private static DaoMaster daoMaster;
8    private static DaoSession daoSession;
9
10    public static DaoSession getDaoSession(Context context) {
11        if (helper == null) {
12            helper = new DaoMaster.DevOpenHelper(context, "user-db");
13            daoMaster = new DaoMaster(helper.getWritableDatabase());
14            daoSession = daoMaster.newSession();
15        }
16        return daoSession;
17    }
18}

第四步:使用 GreenDao

现在你可以使用 AppDatabase.getDaoSession() 方法获取 DaoSession,然后使用 UserDao 进行数据库操作:

Java

1import org.greenrobot.greendao.query.QueryBuilder;
2
3import android.app.Activity;
4import android.os.Bundle;
5import android.view.View;
6import android.widget.Button;
7import android.widget.TextView;
8
9public class MainActivity extends Activity {
10    private Button insertButton;
11    private TextView textView;
12
13    @Override
14    protected void onCreate(Bundle savedInstanceState) {
15        super.onCreate(savedInstanceState);
16        setContentView(R.layout.activity_main);
17
18        insertButton = findViewById(R.id.insert_button);
19        textView = findViewById(R.id.text_view);
20
21        insertButton.setOnClickListener(new View.OnClickListener() {
22            @Override
23            public void onClick(View v) {
24                insertUser();
25            }
26        });
27    }
28
29    private void insertUser() {
30        DaoSession daoSession = AppDatabase.getDaoSession(this);
31        UserDao userDao = daoSession.getUserDao();
32
33        User user = new User("John Doe", 30);
34        userDao.insert(user);
35
36        QueryBuilder<User> queryBuilder = userDao.queryBuilder();
37        List<User> users = queryBuilder.where(UserDao.Properties.Name.eq("John Doe")).list();
38        textView.setText(users.get(0).getName());
39    }
40}

以上就是一个基本的 GreenDao 使用示例,展示了如何定义实体类、创建数据库、以及如何插入和查询数据。注意,实际项目中可能需要根据具体需求调整数据库的创建逻辑,比如处理数据库升级的情况。

结论

GreenDao 的设计原则是尽量减少运行时的开销,通过预编译代码生成和缓存机制来提升性能。它提供了丰富的 API 来简化数据库操作,并且通过注解驱动的方式降低了使用门槛。如果你正在寻找一个高性能且易于使用的 Android 数据库解决方案,GreenDao 是一个值得考虑的选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/47698.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI 应用还没有大量出现,缺什么?缺聊天机器人编程语言 | Chatopera

只有帮助人发挥创意的才是大市场 现在是需要大量的 AI 应用了。如何产生大量的 AI 应用呢&#xff1f;当年乔布斯说&#xff0c;他看到了个人电脑的两个趋势&#xff0c;一个是图形化用户界面&#xff0c;一个是面向对象编程语言。今天&#xff0c;AI 应用也是新的【图形用户界…

【QT】label中添加QImage图片并旋转(水平翻转、垂直翻转、顺时针旋转、逆时针旋转)

目录 0.简介 1.详细代码及解释 1&#xff09;原label显示在界面上 2&#xff09;水平翻转 3&#xff09;垂直翻转 4&#xff09;顺时针旋转45度 5&#xff09;逆时针旋转 0.简介 环境&#xff1a;windows11 QtCreator 背景&#xff1a;demo&#xff0c;父类为QWidget&a…

Cisco 路由重发布 —— 实现路由信息在不同路由选择域间的传递

一、技术背景 在实际的组网中&#xff0c;可能会遇到这样一个场景&#xff1a;在一个网络中同时存在两种或者两种以上的路由协议。例如客户的网络原先是纯 Cisco 的设备&#xff0c;使用 EIGRP 协议将网络的路由打通。但是后来网络扩容&#xff0c;增加了一批华为的设备&#…

应用层——HTTP

像我们电脑和手机使用的应用软件就是在应用层写的&#xff0c;当我们的数据需要传输的时候换将数据传递到传输层。 应用层专门给用户提供应用功能&#xff0c;比如HTTP,FTP… 我们程序员写的一个个解决我们实际的问题都在应用层&#xff0c;我们今天来聊一聊HTTP。 协议 协议…

【接口自动化_12课_基于Flask搭建MockServer】

知识非核心点&#xff0c;面试题较少。框架搭建的过程中的细节才是面试要点 第三方接口&#xff0c;不方便进行测试&#xff0c; 自己要一个接口去进行模拟。去作为我们项目访问模拟接口。自己写一个接口&#xff0c;需要怎样写 一、flask:轻量级的web应用的框架 安装命令 …

旧系统的会员信息如何导入新系统?

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…

ES6 中的 generator 函数究竟是什么

ES6 中的 generator 函数究竟是什么 我们在学习 js 的时候应该都知道一个概念&#xff1a;一旦函数开始执行&#xff0c;它将运行直至完成&#xff0c;没有其他的代码可以在运行期间干扰它。 但是在 ES6 中引入了一种新型的函数&#xff0c;它不按照“运行至完成”的规则。这…

数据库相关概念

MySQL 启动停止 MySQL安装完成之后&#xff0c;在系统启动时&#xff0c;会自动启动MySQL服务&#xff0c;无需手动启动。 手动的通过指令启动停止&#xff0c;以管理员身份运行cmd&#xff0c;进入命令行执行如下指令&#xff1a; net start mysql80 net stop mysql80 注意 …

JMeter使用小功能-(持续更新)

1、jmeter在同一个线程组内&#xff0c;uuid的复用 方式一&#xff1a; 方式二&#xff1a; 2、获得jMeter使用的线程总数 ctx.getThreadGroup().getNumberOfThreads()来表示活动线程总数 int threadNumctx.getThreadGroup().getNumThreads(); String threads Integer…

机械学习—零基础学习日志(高数05——函数概念与特性)

零基础为了学人工智能&#xff0c;真的开始复习高数 本小节讲解隐函数&#xff0c;有点神奇&#xff0c;我竟然完全没有隐函数记忆了。 隐函数 隐函数&#xff0c;我个人通俗理解就是&#xff0c;在复杂的环境里&#xff0c;发现纯净天地。例如&#xff0c;在外太空的某个大陆…

工信部信通院首份全景图 | 天空卫士产品26个版块多覆盖

近日&#xff0c;2024全球数字经济大会——数字安全生态建设专题论坛在北京成功举办&#xff0c;论坛由全球数字经济大会组委会主办&#xff0c;中国信息通信研究院和公安部第三研究所共同承办。论坛上&#xff0c;中国信息通信研究院隆重推出了业界首期《数字安全护航技术能力…

Flink集群搭建

&#xff08;1&#xff09;JAVA_HOME 配置 conf/flink-conf.yaml env.java.home &#xff08;2&#xff09;与Hadoop关联&#xff0c;如果确认使用Hadoop相关功能&#xff0c;需要关注对应的版本。如果不使用&#xff0c;则随意 使用flink版本 下载最新版本后&#xff0c;将存…

(四)原生js案例之手风琴效果

手风琴效果也是业务开发中一个比较常见的效果,类似QQ那样的折叠功能 效果预览 代码实现 必要的css * {margin: 0;padding: 0;}body {height: 100vh;background: linear-gradient(200deg, #ffff00 0%, #ee82ee 100%);overflow: hidden;}ul {list-style: none;}#List {margin:…

更新weibo sdk(去掉so以适配Android 15的16K Page Size的版本)记录

1、修改模块的gradle 从 implementation io.github.sinaweibosdk:core:13.6.1aar 改为 implementation io.github.sinaweibosdk:core:13.10.4aar 同步、运行报错&#xff1a; Didnt find class "androidx.core.content.FileProvider" 解决&#xff1a;据此提示…

Stable Diffusion:质量高画风清新细节丰富的二次元大模型二次元插图

今天和大家分享一个基于Pony模型训练的二次元模型&#xff1a;二次元插图。关于该模型有4个不同的分支版本。 1.5版本&#xff1a;loar模型&#xff0c;推荐底模型niji-动漫二次元4.5。 xl版本&#xff1a;SDXL模型版本 mix版本&#xff1a;光影减弱&#xff0c;减少SDXL版本…

C/C++ yaml 库

文章目录 一、yaml 介绍1.1 yaml 介绍1.2 yaml 教程1.3 yaml 在线工具1.4 yaml 出现背景 二、C/C yaml 库选型2.2 libfyaml2.3 yaml-cpp 一、yaml 介绍 1.1 yaml 介绍 YAML&#xff08;YAML Ain’t Markup Language&#xff09;是一种人类可读的数据序列化格式&#xff0c;通…

客户在哪儿AI的ToB获客服务和AI外呼机器人的有何不同

客户在哪儿AI全面提供服务已经快一个月了&#xff0c;我们收到了一些反馈。其中问的最多也是最有意思的问题就是&#xff0c;客户在哪儿AI与市面上其他几类服务于B端的科技产品有什么不同。既然如此&#xff0c;我们决定连出几篇文章把这件事给讲清楚。本期讲——客户在哪儿AI的…

模型训练中出现loss为NaN怎么办?

文章目录 一、模型训练中出现loss为NaN原因1. 学习率过高2. 梯度消失或爆炸3. 数据不平衡或异常4. 模型不稳定5. 过拟合 二、 针对梯度消失或爆炸的解决方案1. 使用torch.autograd.detect_anomaly()2. 使用 torchviz 可视化计算图3. 检查梯度的数值范围4. 调整梯度剪裁 三、更具…

uni-app开发日志:unicloud使用时遇到的问题解决汇总(不断补充)

插件安装后提示与原数据库表冲突&#xff08;2024.7.18&#xff09; 安装uni-admin后再安装uni-cms&#xff0c;在uni-admin中添加好菜单&#xff0c;结果提示该错误 回到hbuilder中uniCloud/database中找到冲突的部分 比较一下&#xff0c;选中老的删除 opendb-news-articl…

HarmonyOS根据官网写案列~ArkTs从简单地页面开始

Entry Component struct Index {State message: string 快速入门;build() {Column() {Text(this.message).fontSize(24).fontWeight(700).width(100%).textAlign(TextAlign.Start).padding({ left: 16 }).fontFamily(HarmonyHeiTi-Bold).lineHeight(33)Scroll() {Column() {Ba…