复习一下Greendao...

GreenDAO 是一个轻量级的 ORM(对象关系映射)框架,专为 Android 平台设计。它帮助开发者更方便地操作 SQLite 数据库,而无需编写大量的 SQL 语句。以下是 GreenDAO 的主要使用方面:

1. 环境准备

在使用 GreenDAO 之前,需要在项目中引入依赖。通常可以通过 Gradle 来管理依赖。

添加依赖

build.gradle 文件中添加 GreenDAO 的依赖:

groovy 复制代码
dependencies {
    implementation 'org.greenrobot:greendao:3.3.0' // 请使用最新版本
}

2. 实体类生成

GreenDAO 使用注解处理器来自动生成实体类和 DAO(Data Access Object)类。你需要定义实体类,并使用 GreenDAO 的注解。

定义实体类

java 复制代码
@Entity
public class User {
    @Id
    private Long id;

    @Property
    private String name;

    @Property
    private String email;

    // Getters and Setters
}

3. DAO 生成

使用 GreenDAO 的注解处理器生成 DAO 类。你需要在项目中配置 GreenDAO 的注解处理器。

配置注解处理器

build.gradle 文件中添加注解处理器:

groovy 复制代码
dependencies {
    implementation 'org.greenrobot:greendao:3.3.0'
    annotationProcessor 'org.greenrobot:greendao-generator:3.3.0'
}

4. 数据库管理

GreenDAO 提供了一个 DaoMasterDaoSession 类来管理数据库连接和操作。

初始化数据库

java 复制代码
public class MyApplication extends Application {
    private DaoMaster.DevOpenHelper helper;
    private DaoMaster daoMaster;
    private DaoSession daoSession;

    @Override
    public void onCreate() {
        super.onCreate();
        helper = new DaoMaster.DevOpenHelper(this, "mydb.db", null);
        daoMaster = new DaoMaster(helper.getWritableDatabase());
        daoSession = daoMaster.newSession();
    }

    public DaoSession getDaoSession() {
        return daoSession;
    }

    public DaoMaster getDaoMaster() {
        return daoMaster;
    }
}

5. 插入数据

使用 Dao 类的 insert 方法插入数据。

插入数据示例

java 复制代码
public class MainActivity extends AppCompatActivity {
    private UserDao userDao;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MyApplication app = (MyApplication) getApplication();
        userDao = app.getDaoSession().getUserDao();

        User user = new User(null, "John Doe", "john@example.com");
        userDao.insert(user);
    }
}

6. 查询数据

使用 Dao 类的 queryBuilder 方法构建查询条件。

查询数据示例

java 复制代码
public class MainActivity extends AppCompatActivity {
    private UserDao userDao;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MyApplication app = (MyApplication) getApplication();
        userDao = app.getDaoSession().getUserDao();

        // 查询所有用户
        List<User> users = userDao.loadAll();
        for (User user : users) {
            Log.d("MainActivity", "User: " + user.getName());
        }

        // 根据条件查询
        List<User> usersWithName = userDao.queryBuilder()
                .where(UserDao.Properties.Name.eq("John Doe"))
                .list();
        for (User user : usersWithName) {
            Log.d("MainActivity", "User with name John Doe: " + user.getEmail());
        }
    }
}

7. 更新数据

使用 Dao 类的 update 方法更新数据。

更新数据示例

java 复制代码
public class MainActivity extends AppCompatActivity {
    private UserDao userDao;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MyApplication app = (MyApplication) getApplication();
        userDao = app.getDaoSession().getUserDao();

        // 查询用户
        User user = userDao.queryBuilder()
                .where(UserDao.Properties.Name.eq("John Doe"))
                .unique();

        if (user != null) {
            // 更新用户信息
            user.setEmail("john_new@example.com");
            userDao.update(user);
        }
    }
}

8. 删除数据

使用 Dao 类的 delete 方法删除数据。

删除数据示例

java 复制代码
public class MainActivity extends AppCompatActivity {
    private UserDao userDao;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MyApplication app = (MyApplication) getApplication();
        userDao = app.getDaoSession().getUserDao();

        // 查询用户
        User user = userDao.queryBuilder()
                .where(UserDao.Properties.Name.eq("John Doe"))
                .unique();

        if (user != null) {
            // 删除用户
            userDao.delete(user);
        }
    }
}

9. 关系映射

GreenDAO 支持一对一、一对多和多对多的关系映射。

一对一关系

java 复制代码
@Entity
public class User {
    @Id
    private Long id;

    @Property
    private String name;

    @ToOne(joinProperty = "addressId")
    private Address address;

    @Property
    private Long addressId;

    // Getters and Setters
}

@Entity
public class Address {
    @Id
    private Long id;

    @Property
    private String street;

    // Getters and Setters
}

一对多关系

java 复制代码
@Entity
public class User {
    @Id
    private Long id;

    @Property
    private String name;

    @ToMany(referencedJoinProperty = "userId")
    private List<Note> notes;

    // Getters and Setters
}

@Entity
public class Note {
    @Id
    private Long id;

    @Property
    private String content;

    @Property
    private Long userId;

    // Getters and Setters
}

10. 事务管理

GreenDAO 提供了事务管理功能,确保数据的一致性和完整性。

事务管理示例

java 复制代码
public class MainActivity extends AppCompatActivity {
    private UserDao userDao;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MyApplication app = (MyApplication) getApplication();
        userDao = app.getDaoSession().getUserDao();

        userDao.getSession().runInTx(new Runnable() {
            @Override
            public void run() {
                User user1 = new User(null, "John Doe", "john@example.com");
                User user2 = new User(null, "Jane Smith", "jane@example.com");
                userDao.insert(user1);
                userDao.insert(user2);
            }
        });
    }
}

11. 数据库迁移

当数据库结构发生变化时,需要进行数据库迁移。GreenDAO 提供了 DevOpenHelper 的子类 MigrationHelper 来帮助进行数据库迁移。

数据库迁移示例

java 复制代码
public class MyApplication extends Application {
    private DaoMaster.DevOpenHelper helper;
    private DaoMaster daoMaster;
    private DaoSession daoSession;

    @Override
    public void onCreate() {
        super.onCreate();
        helper = new DaoMaster.DevOpenHelper(this, "mydb.db", null) {
            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                MigrationHelper.migrate(db, User.class, Address.class);
            }
        };
        daoMaster = new DaoMaster(helper.getWritableDatabase());
        daoSession = daoMaster.newSession();
    }

    public DaoSession getDaoSession() {
        return daoSession;
    }

    public DaoMaster getDaoMaster() {
        return daoMaster;
    }
}

12.Q&A

1. 数据对象 id 如果没有设置会有什么问题

在 GreenDAO 中,id 字段通常被标记为 @Id,表示它是主键。如果 id 没有设置,可能会导致以下问题:

  • 无法使用 insertOrReplace 方法insertOrReplace 方法需要根据 id 判定是插入新记录还是替换现有记录。如果 id 没有设置,会导致无法正确执行该方法。
  • 数据唯一性问题 :主键字段通常用于保证数据的唯一性。如果 id 没有设置,可能会导致数据重复插入,从而破坏数据的一致性。

2. GreenDAO 的注解处理器会生成哪些类及其作用

GreenDAO 的注解处理器会生成以下类:

  • DaoMaster :管理数据库的创建和版本控制。包含 DevOpenHelper 类,用于创建和管理数据库。
    • DevOpenHelper :继承自 SQLiteOpenHelper,用于创建和升级数据库。
    • OpenHelper:用于打开数据库连接。
    • DaoMaster.OpenHelper:用于打开数据库连接的辅助类。
    • DaoMaster.DevOpenHelper:用于开发环境中的数据库创建和升级。
  • DaoSession :管理多个 DAO 的会话,提供对多个实体类的操作。
    • DaoSession:提供对多个 DAO 的访问,支持事务管理。
  • EntityDao :每个实体类对应的 DAO 类,提供对该实体类的操作。
    • UserDao :例如,对于 User 实体类,生成的 DAO 类是 UserDao,提供插入、查询、更新、删除等方法。

3. 补充和对比 CRUD 的几个方法

GreenDAO 提供了多种 CRUD 方法,每种方法有不同的用途和特点:

  • insert :插入一条新的记录。

    java 复制代码
    userDao.insert(user);
  • insertInTx :在一个事务中插入多条记录。

    java 复制代码
    userDao.insertInTx(users);
  • update :更新一条记录。

    java 复制代码
    userDao.update(user);
  • updateInTx :在一个事务中更新多条记录。

    java 复制代码
    userDao.updateInTx(users);
  • delete :删除一条记录。

    java 复制代码
    userDao.delete(user);
  • deleteInTx :在一个事务中删除多条记录。

    java 复制代码
    userDao.deleteInTx(users);
  • insertOrReplace :插入一条记录,如果记录已存在则替换。

    java 复制代码
    userDao.insertOrReplace(user);
  • insertOrReplaceInTx :在一个事务中插入或替换多条记录。

    java 复制代码
    userDao.insertOrReplaceInTx(users);
  • insertOrUpdate :插入一条记录,如果记录已存在则更新。

    java 复制代码
    userDao.insertOrUpdate(user);

4. 详细解释一下关系映射的含义、使用、区别

GreenDAO 支持多种关系映射,包括一对一、一对多和多对多关系。

  • 一对一关系

    • 含义:一个实体对象与另一个实体对象之间存在一对一的关系。

    • 使用

      java 复制代码
      @Entity
      public class User {
          @Id
          private Long id;
      
          @Property
          private String name;
      
          @ToOne(joinProperty = "addressId")
          private Address address;
      
          @Property
          private Long addressId;
      
          // Getters and Setters
      }
      
      @Entity
      public class Address {
          @Id
          private Long id;
      
          @Property
          private String street;
      
          // Getters and Setters
      }
    • 区别 :一对一关系通常使用 @ToOne 注解,通过 joinProperty 指定外键。

  • 一对多关系

    • 含义:一个实体对象与多个其他实体对象之间存在一对多的关系。

    • 使用

      java 复制代码
      @Entity
      public class User {
          @Id
          private Long id;
      
          @Property
          private String name;
      
          @ToMany(referencedJoinProperty = "userId")
          private List<Note> notes;
      
          // Getters and Setters
      }
      
      @Entity
      public class Note {
          @Id
          private Long id;
      
          @Property
          private String content;
      
          @Property
          private Long userId;
      
          // Getters and Setters
      }
    • 区别 :一对多关系通常使用 @ToMany 注解,通过 referencedJoinProperty 指定外键。

  • 多对多关系

    • 含义:多个实体对象与多个其他实体对象之间存在多对多的关系。

    • 使用

      java 复制代码
      @Entity
      public class User {
          @Id
          private Long id;
      
          @Property
          private String name;
      
          @ToMany(joinProperties = {
              @JoinProperty(name = "userId", referencedName = "noteId")
          })
          private List<Note> notes;
      
          // Getters and Setters
      }
      
      @Entity
      public class Note {
          @Id
          private Long id;
      
          @Property
          private String content;
      
          // Getters and Setters
      }
      
      @Entity
      public class UserNote {
          @Id
          private Long id;
      
          @Property
          private Long userId;
      
          @Property
          private Long noteId;
      
          // Getters and Setters
      }
    • 区别 :多对多关系通常使用 @ToMany 注解,并通过 joinProperties 指定中间表的外键。

5. 数据库迁移

假设一开始设置 id 自动增长,后来想改为在创建数据的时候自定义 id。可以通过以下步骤进行数据库迁移:

  1. 修改实体类

    java 复制代码
    @Entity
    public class User {
        @Id(autoincrement = false)
        private Long id;
    
        @Property
        private String name;
    
        @Property
        private String email;
    
        // Getters and Setters
    }
  2. 数据库迁移

    • DevOpenHelperonUpgrade 方法中处理数据库迁移。
    • 将现有的 id 字段从自动增长改为手动设置。
    java 复制代码
    public class MyApplication extends Application {
        private DaoMaster.DevOpenHelper helper;
        private DaoMaster daoMaster;
        private DaoSession daoSession;
    
        @Override
        public void onCreate() {
            super.onCreate();
            helper = new DaoMaster.DevOpenHelper(this, "mydb.db", null) {
                @Override
                public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                    // 迁移逻辑
                    if (oldVersion < 2) {
                        // 将现有的 id 字段从自动增长改为手动设置
                        db.execSQL("ALTER TABLE USER RENAME TO USER_OLD");
                        db.execSQL("CREATE TABLE IF NOT EXISTS USER (" +
                                "_id INTEGER PRIMARY KEY," +
                                "name TEXT," +
                                "email TEXT" +
                                ")");
                        db.execSQL("INSERT INTO USER (_id, name, email) SELECT _id, name, email FROM USER_OLD");
                        db.execSQL("DROP TABLE USER_OLD");
                    }
                }
            };
            daoMaster = new DaoMaster(helper.getWritableDatabase());
            daoSession = daoMaster.newSession();
        }
    
        public DaoSession getDaoSession() {
            return daoSession;
        }
    
        public DaoMaster getDaoMaster() {
            return daoMaster;
        }
    }

总结

GreenDAO 提供了一套完整的解决方案,帮助开发者在 Android 应用中高效地管理和操作 SQLite 数据库。通过定义实体类、生成 DAO 类、初始化数据库、插入、查询、更新、删除数据,以及支持关系映射和事务管理,GreenDAO 大大简化了数据库操作的复杂性。

相关推荐
激流丶23 分钟前
【Mysql 底层原理】MySQL 查询优化器的工作原理:如何生成最优执行计划
数据库·mysql·explain·执行计划
雷神乐乐39 分钟前
Sqoop学习
数据库·sqoop
小丑西瓜66644 分钟前
MySQL库操作
linux·服务器·数据库·mysql
谦谦均1 小时前
PostgreSQL序列:创建、管理与高效应用指南
数据库·postgresql
荒川之神1 小时前
RHEL/CENTOS 7 ORACLE 19C-RAC安装(纯命令版)
服务器·数据库·oracle
ZWZhangYu1 小时前
【MyBatis源码】深入分析TypeHandler原理和源码
数据库·oracle·mybatis
七月.末1 小时前
安卓aab包的安装教程,附带adb环境的配置
android·adb
ascarl20103 小时前
系统启动时将自动加载环境变量,并后台启动 MinIO、Nacos 和 Redis 服务
数据库·redis·缓存
LightOfNight3 小时前
Redis设计与实现第9章 -- 数据库 总结(键空间 过期策略 过期键的影响)
数据库·redis·后端·缓存·中间件·架构
Jasonakeke3 小时前
【重学 MySQL】八十四、深入理解 LEAVE 和 ITERATE 在存储过程中的使用
数据库·mysql