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, load 和 queryBuilder。这些方法在 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}
第三步:创建数据库
在你的应用程序中,你需要创建 DaoMaster 和 DaoSession 的实例:
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) 框架,它将 Java 对象映射到 SQLite 数据库,以简化数据持久化操作。GreenDao 的主要优点包括高性能、低内存占用、易于使用以及对数据库加密的支持。 以下是基于源码的 GreenDao 实现原…...
Perl语言之数组
Perl数组可以存储多个标量,并且标量数据类型可以不同。 数组变量以开头。访问与定义格式如下: #! /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改:内容、逻辑结构、语句 3、查标题及其标号 4、修改格式:仿宋 、正文统一为小三,标题三号,1.5倍行距,加页码。 采用VBA代码自动修改,不知为何标题无法修改字体 Sub 插入页…...
Centos---命令详解 vi 系统服务 网络
目录 一、CentOS vi命令详解 二、CentOS系统服务命令 三、CentOS权限管理命令: 四、CentOS网络管理命令介绍: 一、CentOS vi命令详解 Vi是一款强大的文本编辑器,在CentOS中广泛使用。以下是Vi编辑器的一些常用命令: 1. 打开…...
【.NET全栈】ASP.NET开发web应用——ASP.NET中的样式、主题和母版页
文章目录 前言一、在ASP.NET中应用CSS样式1、创建CSS样式(1)内联样式(2)内部样式表(3)外部样式表 2、应用CSS样式(1)菜鸟教程-简单例子(2)菜鸟教程-用户界面&…...
[ruby on rails]部署时候产生ActiveRecord::PreparedStatementCacheExpired错误的原因及解决方法
一、问题: 有时在 Postgres 上部署 Rails 应用程序时,可能会看到 ActiveRecord::PreparedStatementCacheExpired 错误。仅当在部署中运行迁移时才会发生这种情况。发生这种情况是因为 Rails 利用 Postgres 的缓存准备语句(PreparedStatementCache)功能来…...
函数传值面试题
let a {name: aa };function fun1(a) {a []; // 这里创建了一个新的局部变量a,它是一个空数组// a.name "芜湖" }fun1(a); // 调用fun1,传入a的引用副本 console.log(a); // 输出:{ name: aa }在 JavaScript 中,当你…...
redis笔记2
redis是用c语言写的,放不频繁更新的数据(用户数据。课程数据) Redis 中,"穿透"通常指的是缓存穿透(Cache Penetration)问题,这是指一种恶意或非法请求直接绕过缓存层,直接访问数据库或…...
Kafka(四) Consumer消费者
一,基础知识 1,消费者与消费组 每个消费者都有对应的消费组,不同消费组之间互不影响。 Partition的消息只能被一个消费组中的一个消费者所消费, 但Partition也可能被再平衡分配给新的消费者。 一个Topic的不同Partition会根据分配…...
前端路由手写Hash和History两种模式
文章目录 1. Hash模式:简洁而广泛适用2. History模式:更自然的用户体验3. 结论 在现代Web开发中,单页面应用(Single Page Application,简称SPA)因其流畅的用户体验和高效的页面交互能力而备受青睐。前端路由…...
Redis的单线程讲解与指令学习
目录 一.Redis的命令 二.数据类型 三.Redis的key的过期策略如何实现? 四.Redis为什么是单线程的 五.String有关的命令 Redis的学习专栏:http://t.csdnimg.cn/a8cvV 一.Redis的命令 两个基本命令 在Redis当中,有两个基本命令࿱…...
为什么MySQL会选择B+树作为索引
为什么MySQL会选择B树作为索引 在数据库管理系统中,索引是提升查询效率的关键技术之一。MySQL作为广泛使用的关系型数据库管理系统,其核心存储引擎InnoDB选择B树作为其索引结构,这一选择背后蕴含了深刻的性能和存储效率考量。本文将简要介绍…...
k8s secret-从环境变量里去读和从yaml文件里读取secret有什么区别?
从环境变量和YAML文件中读取Kubernetes Secret的区别主要体现在使用方式、动态更新能力以及管理便捷性上。以下是详细的区别说明: 1. **使用方式**: - **环境变量方式**:Kubernetes允许将Secret作为环境变量注入到Pod的容器中。这种方式的好处…...
Springboot+Aop用注解实现阿里云短信验证码校验,校验通过自动删除验证码缓存
1.新建操作类型枚举(这里的IEnum是我自定义的http请求拦截接口,不需要的话可以不用实现) Getter AllArgsConstructor public enum OperationType implements IEnum<Integer> {/*** 注册*/SIGN_UP(0),/*** 密码登录*/LOGIN_BY_PWD(1),/…...
无线物联网新时代,RFID拣货标签跟随潮流
拣选技术的演变历程,本质上是从人力操作向自动化、智能化转型的持续进程。近期,“货寻人”技术成为众多企业热烈追捧的对象,它可以根据企业的特定需求,从众多拣选方案中选出最优解。那么,在采用“货到人”拣选技术时&a…...
Java8 根据List实体中一个字段去重取最大值,并且根据该字段进行排序
1、前言 某个功能要求需要对一个list对象里数据按照股票分组,并且取分组涨跌幅最大的,返回一个新的list对象,并且按照涨跌幅字段进行排序,这么一连串的要求,如果按照传统的写法,我们需要写一大坨的代码&am…...
微服务经纬:Eureka驱动的分布式服务网格配置全解
微服务经纬:Eureka驱动的分布式服务网格配置全解 在微服务架构的宏伟蓝图中,服务网格(Service Mesh)作为微服务间通信的独立层,承担着流量管理、服务发现、故障恢复等关键任务。Eureka,Netflix开源的服务发…...
关于前端数据库可视化库的选择,vue3+antd+g2plot录课计划
之前:antdv 现在:g2plot https://g2plot.antv.antgroup.com/manual/introduction 录课内容:快速入门 图表示例: 选择使用比较广泛的示例类型,录课顺序如下: 1、折线图2、面积图3、柱形图4、条形图5、饼…...
linux进行redis的安装并使用RDB进行数据迁移
现在有两台电脑,分别是A,B,现在我要把A电脑上的redis的数据迁移到B电脑上,B电脑上是没有安装redis的 1.找到A电脑的redis的版本 1.先启动A电脑的redis,一般来说,都是直接在linux的控制台输入:re…...
深入理解Scikit-learn:决策树与随机森林算法详解
用sklearn实现决策树与随机森林 1. 简介 决策树和随机森林是机器学习中的两种强大算法。决策树通过学习数据特征与标签之间的规则来进行预测,而随机森林则是由多棵决策树组成的集成算法,能有效提高模型的稳定性和准确性。 2. 安装sklearn 首先&#…...
nRF52轻量级NFC Type 2标签驱动库解析
1. 项目概述aconno_nrf52_nfc是一个专为 Nordic Semiconductor nRF52 系列 SoC(如 nRF52832、nRF52840)设计的轻量级 NFC 标签驱动库。该库不依赖于 Nordic SDK 的完整 NFC 协议栈(如nfc_t2t_lib或nfc_ndef),而是直接操…...
嵌入式设备参数存储优化方案与实践
1. 嵌入式设备参数存储的痛点与常见方案在嵌入式系统开发中,参数存储是个看似简单却暗藏玄机的基础功能。我经历过多个量产项目,发现参数管理不当导致的现场问题占比高达30%。最常见的场景是:设备运行多年后需要功能升级,新增几个…...
到底什么是 TCP 连接:从三次握手到四次挥手,从数据结构到状态机
到底什么是 TCP 连接:从三次握手到四次挥手,从数据结构到状态机01. 前言:每天都在用,却说不清它是什么02. 一句话定义03. TCP 连接不是物理的,而是逻辑的04. TCP 连接的核心标识:四元组05. TCP 连接在内核中…...
OBS屏幕录制全攻略:从零开始轻松上手
1. OBS屏幕录制入门指南 第一次接触OBS的朋友可能会被它复杂的界面吓到,但其实它的核心功能非常简单。我刚开始用OBS时也走了不少弯路,现在就把这些经验分享给大家。OBS Studio(Open Broadcaster Software)是一款开源免费的屏幕录…...
告别OBS!用JavaCV+FFmpeg在Windows上搭建个人直播推流服务器(含Nginx配置)
用JavaCVFFmpeg构建Windows直播推流服务器的全栈指南 直播技术正在从专业领域向个人开发者渗透,但传统方案如OBS往往过于笨重且缺乏定制性。本文将带你用JavaCVFFmpegNginx搭建一套轻量级直播推流服务器,实现从视频采集、编码推流到服务端分发的完整链路…...
ngx_sort
1 定义 ngx_sort 函数 定义在 ./nginx-1.24.0/src/core/ngx_string.cvoid ngx_sort(void *base, size_t n, size_t size,ngx_int_t (*cmp)(const void *, const void *)) {u_char *p1, *p2, *p;p ngx_alloc(size, ngx_cycle->log);if (p NULL) {return;}for (p1 (u_char…...
2025届毕业生推荐的六大降重复率网站推荐
Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 针对用户试图降低文本里人工智能生成内容的可识别度,降AIGC工具发挥作用…...
智能应急灯V16:多场景照明解决方案
目录 一、方案概述 二、硬件方案设计 2.1 硬件整体架构 2.2 核心模块选型与设计 2.2.1 主控模块(核心单元) 2.2.2 电源管理模块(供电核心) 2.2.3 照明驱动模块 2.2.4 状态监测模块 2.2.5 通信模块(可选&#…...
AutoCAD转SolidWorks必看:用装配体功能优化树莓派小车结构的5个技巧
AutoCAD转SolidWorks必看:用装配体功能优化树莓派小车结构的5个技巧 从AutoCAD转向SolidWorks的设计师常会遇到一个关键挑战:如何将二维绘图思维转化为三维装配思维。上周一位机械工程师向我展示了他的树莓派小车AutoCAD图纸——虽然二维尺寸精确到毫米…...
打卡信奥刷题(3066)用C++实现信奥题 P6877 [JOI 2020 Final] 只不过是长的领带 / Just Long Neckties
P6877 [JOI 2020 Final] 只不过是长的领带 / Just Long Neckties 题目描述 JOI 公司发明了一种领带,一共有 N1N1N1 条领带,编号为 111 到 N1N1N1,第 iii 条领带的长度为 AiA_iAi。 JOI 公司开了一个派对,派对中有 NNN 名员工…...
