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

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 是一个值得考虑的选择。

相关文章:

GreenDao实现原理

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

Perl语言之数组

Perl数组可以存储多个标量&#xff0c;并且标量数据类型可以不同。   数组变量以开头。访问与定义格式如下&#xff1a; #! /usr/bin/perl arr("asdfasd",2,23.56,a); print "输出所有:arr\n"; print "arr[0]$arr[0]\n"; #输出指定下标 print…...

写材料word和PPT

一、WORD 1、写内容 2、参考GPT改&#xff1a;内容、逻辑结构、语句 3、查标题及其标号 4、修改格式&#xff1a;仿宋 、正文统一为小三&#xff0c;标题三号&#xff0c;1.5倍行距&#xff0c;加页码。 采用VBA代码自动修改&#xff0c;不知为何标题无法修改字体 Sub 插入页…...

Centos---命令详解 vi 系统服务 网络

目录 一、CentOS vi命令详解 二、CentOS系统服务命令 三、CentOS权限管理命令&#xff1a; 四、CentOS网络管理命令介绍&#xff1a; 一、CentOS vi命令详解 Vi是一款强大的文本编辑器&#xff0c;在CentOS中广泛使用。以下是Vi编辑器的一些常用命令&#xff1a; 1. 打开…...

【.NET全栈】ASP.NET开发web应用——ASP.NET中的样式、主题和母版页

文章目录 前言一、在ASP.NET中应用CSS样式1、创建CSS样式&#xff08;1&#xff09;内联样式&#xff08;2&#xff09;内部样式表&#xff08;3&#xff09;外部样式表 2、应用CSS样式&#xff08;1&#xff09;菜鸟教程-简单例子&#xff08;2&#xff09;菜鸟教程-用户界面&…...

[ruby on rails]部署时候产生ActiveRecord::PreparedStatementCacheExpired错误的原因及解决方法

一、问题&#xff1a; 有时在 Postgres 上部署 Rails 应用程序时&#xff0c;可能会看到 ActiveRecord::PreparedStatementCacheExpired 错误。仅当在部署中运行迁移时才会发生这种情况。发生这种情况是因为 Rails 利用 Postgres 的缓存准备语句(PreparedStatementCache)功能来…...

函数传值面试题

let a {name: aa };function fun1(a) {a []; // 这里创建了一个新的局部变量a&#xff0c;它是一个空数组// a.name "芜湖" }fun1(a); // 调用fun1&#xff0c;传入a的引用副本 console.log(a); // 输出&#xff1a;{ name: aa }在 JavaScript 中&#xff0c;当你…...

redis笔记2

redis是用c语言写的,放不频繁更新的数据&#xff08;用户数据。课程数据&#xff09; Redis 中&#xff0c;"穿透"通常指的是缓存穿透&#xff08;Cache Penetration&#xff09;问题&#xff0c;这是指一种恶意或非法请求直接绕过缓存层&#xff0c;直接访问数据库或…...

Kafka(四) Consumer消费者

一&#xff0c;基础知识 1&#xff0c;消费者与消费组 每个消费者都有对应的消费组&#xff0c;不同消费组之间互不影响。 Partition的消息只能被一个消费组中的一个消费者所消费&#xff0c; 但Partition也可能被再平衡分配给新的消费者。 一个Topic的不同Partition会根据分配…...

前端路由手写Hash和History两种模式

文章目录 1. Hash模式&#xff1a;简洁而广泛适用2. History模式&#xff1a;更自然的用户体验3. 结论 在现代Web开发中&#xff0c;单页面应用&#xff08;Single Page Application&#xff0c;简称SPA&#xff09;因其流畅的用户体验和高效的页面交互能力而备受青睐。前端路由…...

Redis的单线程讲解与指令学习

目录 一.Redis的命令 二.数据类型 三.Redis的key的过期策略如何实现&#xff1f; 四.Redis为什么是单线程的 五.String有关的命令 Redis的学习专栏&#xff1a;http://t.csdnimg.cn/a8cvV 一.Redis的命令 两个基本命令 在Redis当中&#xff0c;有两个基本命令&#xff1…...

为什么MySQL会选择B+树作为索引

为什么MySQL会选择B树作为索引 在数据库管理系统中&#xff0c;索引是提升查询效率的关键技术之一。MySQL作为广泛使用的关系型数据库管理系统&#xff0c;其核心存储引擎InnoDB选择B树作为其索引结构&#xff0c;这一选择背后蕴含了深刻的性能和存储效率考量。本文将简要介绍…...

k8s secret-从环境变量里去读和从yaml文件里读取secret有什么区别?

从环境变量和YAML文件中读取Kubernetes Secret的区别主要体现在使用方式、动态更新能力以及管理便捷性上。以下是详细的区别说明&#xff1a; 1. **使用方式**&#xff1a; - **环境变量方式**&#xff1a;Kubernetes允许将Secret作为环境变量注入到Pod的容器中。这种方式的好处…...

Springboot+Aop用注解实现阿里云短信验证码校验,校验通过自动删除验证码缓存

1.新建操作类型枚举&#xff08;这里的IEnum是我自定义的http请求拦截接口&#xff0c;不需要的话可以不用实现&#xff09; Getter AllArgsConstructor public enum OperationType implements IEnum<Integer> {/*** 注册*/SIGN_UP(0),/*** 密码登录*/LOGIN_BY_PWD(1),/…...

无线物联网新时代,RFID拣货标签跟随潮流

拣选技术的演变历程&#xff0c;本质上是从人力操作向自动化、智能化转型的持续进程。近期&#xff0c;“货寻人”技术成为众多企业热烈追捧的对象&#xff0c;它可以根据企业的特定需求&#xff0c;从众多拣选方案中选出最优解。那么&#xff0c;在采用“货到人”拣选技术时&a…...

Java8 根据List实体中一个字段去重取最大值,并且根据该字段进行排序

1、前言 某个功能要求需要对一个list对象里数据按照股票分组&#xff0c;并且取分组涨跌幅最大的&#xff0c;返回一个新的list对象&#xff0c;并且按照涨跌幅字段进行排序&#xff0c;这么一连串的要求&#xff0c;如果按照传统的写法&#xff0c;我们需要写一大坨的代码&am…...

微服务经纬:Eureka驱动的分布式服务网格配置全解

微服务经纬&#xff1a;Eureka驱动的分布式服务网格配置全解 在微服务架构的宏伟蓝图中&#xff0c;服务网格&#xff08;Service Mesh&#xff09;作为微服务间通信的独立层&#xff0c;承担着流量管理、服务发现、故障恢复等关键任务。Eureka&#xff0c;Netflix开源的服务发…...

关于前端数据库可视化库的选择,vue3+antd+g2plot录课计划

之前&#xff1a;antdv 现在&#xff1a;g2plot https://g2plot.antv.antgroup.com/manual/introduction 录课内容&#xff1a;快速入门 图表示例&#xff1a; 选择使用比较广泛的示例类型&#xff0c;录课顺序如下&#xff1a; 1、折线图2、面积图3、柱形图4、条形图5、饼…...

linux进行redis的安装并使用RDB进行数据迁移

现在有两台电脑&#xff0c;分别是A&#xff0c;B&#xff0c;现在我要把A电脑上的redis的数据迁移到B电脑上&#xff0c;B电脑上是没有安装redis的 1.找到A电脑的redis的版本 1.先启动A电脑的redis&#xff0c;一般来说&#xff0c;都是直接在linux的控制台输入&#xff1a;re…...

深入理解Scikit-learn:决策树与随机森林算法详解

用sklearn实现决策树与随机森林 1. 简介 决策树和随机森林是机器学习中的两种强大算法。决策树通过学习数据特征与标签之间的规则来进行预测&#xff0c;而随机森林则是由多棵决策树组成的集成算法&#xff0c;能有效提高模型的稳定性和准确性。 2. 安装sklearn 首先&#…...

抖音无水印下载终极解决方案:免费高效获取高清视频的实战秘籍

抖音无水印下载终极解决方案&#xff1a;免费高效获取高清视频的实战秘籍 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallbac…...

谷歌 AI Studio 一下午开发三款应用,游戏体验却差强人意?

谷歌 AI Studio 助力开发应用 昨天&#xff0c;我开发出了自己的第一款 Android 应用程序&#xff0c;紧接着又做了两个&#xff0c;一个下午就完成了三款应用。其中一款应用&#xff0c;我在网页浏览器里输入 148 个单词后&#xff0c;十分钟后手机上就有了新应用。开启手机 U…...

QQ音乐加密音频一键解密:qmcdump终极指南

QQ音乐加密音频一键解密&#xff1a;qmcdump终极指南 【免费下载链接】qmcdump 一个简单的QQ音乐解码&#xff08;qmcflac/qmc0/qmc3 转 flac/mp3&#xff09;&#xff0c;仅为个人学习参考用。 项目地址: https://gitcode.com/gh_mirrors/qm/qmcdump 你是否曾为QQ音乐下…...

QMCDecode:3步解锁QQ音乐加密音频,让音乐真正属于你!

QMCDecode&#xff1a;3步解锁QQ音乐加密音频&#xff0c;让音乐真正属于你&#xff01; 【免费下载链接】QMCDecode QQ音乐QMC格式转换为普通格式(qmcflac转flac&#xff0c;qmc0,qmc3转mp3, mflac,mflac0等转flac)&#xff0c;仅支持macOS&#xff0c;可自动识别到QQ音乐下载…...

Android Native内存泄漏系统化分析与排查实战指南

引言 在Android开发中,内存管理是一个至关重要的环节,直接影响应用的性能、稳定性和用户体验。随着应用复杂度增加,内存泄漏问题日益突出,尤其是在Native层(如C/C++代码),其排查难度更大。Native内存泄漏可能导致应用崩溃、卡顿或系统资源耗尽,因此系统化分析和排查成…...

RTX166任务调度:K_IVL与K_TMO事件机制详解

1. RTX166任务调度中的K_IVL与K_TMO事件机制解析在RTX166实时操作系统中&#xff0c;os_wait函数提供的K_IVL和K_TMO事件是任务调度的核心机制。这两个看似相似的延时控制参数&#xff0c;在实际应用中却有着截然不同的行为模式。作为深耕嵌入式领域十余年的开发者&#xff0c;…...

tcpdump 核心选项与过滤表达式实战指南:从基础到高效网络排查

1. 从命令行到洞察力&#xff1a;为什么你需要精通 tcpdump如果你在运维、开发或者网络安全领域工作&#xff0c;网络问题排查几乎是你绕不开的日常。当服务调用超时、接口响应异常&#xff0c;或者流量出现诡异波动时&#xff0c;你需要的不是猜测&#xff0c;而是证据。tcpdu…...

探索Pandas groupby的各种技巧和应用实例

groupby是Pandas中用于数据分析的重要工具&#xff0c;它允许我们根据特定列的不同值&#xff0c;对数据行进行灵活分组。分组后的数据可用于生成各类聚合值&#xff0c;从而帮助我们深入了解数据。在Pandas中&#xff0c;如果你想要分析数据的潜在模式或趋势&#xff0c;group…...

量子加速,多模态跃迁:国产大模型的下一站机遇

量子加速&#xff0c;多模态跃迁&#xff1a;国产大模型的下一站机遇 引言 当国产多模态大模型在理解图文、生成内容上不断突破时&#xff0c;一个更具颠覆性的技术变量正在悄然融入——量子计算。这不仅是实验室里的前沿概念&#xff0c;更是百度、华为、阿里等科技巨头竞相布…...

基于RK3568嵌入式主板的智能炒菜机方案:从硬件选型到系统集成实战

1. 项目概述&#xff1a;当嵌入式主板“掌勺”智能厨房最近几年&#xff0c;智能厨电赛道卷得厉害&#xff0c;从智能电饭煲到自动炒菜机&#xff0c;大家都在琢磨怎么让做饭这件事变得更“傻瓜”。我接触过不少这类项目&#xff0c;发现一个核心痛点&#xff1a;很多所谓的“智…...