复习一下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 大大简化了数据库操作的复杂性。

相关推荐
拭心31 分钟前
Google 提供的 Android 端上大模型组件:MediaPipe LLM 介绍
android
独行soc1 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍08-基于时间延迟的SQL注入(Time-Based SQL Injection)
数据库·sql·安全·渗透测试·漏洞挖掘
White_Mountain1 小时前
在Ubuntu中配置mysql,并允许外部访问数据库
数据库·mysql·ubuntu
Code apprenticeship1 小时前
怎么利用Redis实现延时队列?
数据库·redis·缓存
百度智能云技术站1 小时前
广告投放系统成本降低 70%+,基于 Redis 容量型数据库 PegaDB 的方案设计和业务实践
数据库·redis·oracle
装不满的克莱因瓶1 小时前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb
带电的小王3 小时前
WhisperKit: Android 端测试 Whisper -- Android手机(Qualcomm GPU)部署音频大模型
android·智能手机·whisper·qualcomm
梦想平凡3 小时前
PHP 微信棋牌开发全解析:高级教程
android·数据库·oracle
TianyaOAO3 小时前
mysql的事务控制和数据库的备份和恢复
数据库·mysql
Ewen Seong3 小时前
mysql系列5—Innodb的缓存
数据库·mysql·缓存