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

相关推荐
阿里云大数据AI技术12 分钟前
云栖实录|MaxCompute全新升级:AI时代的原生数据仓库
大数据·数据库·云原生
不剪发的Tony老师35 分钟前
Valentina Studio:一款跨平台的数据库管理工具
数据库·sql
weixin_307779131 小时前
在 Microsoft Azure 上部署 ClickHouse 数据仓库:托管服务与自行部署的全面指南
开发语言·数据库·数据仓库·云计算·azure
六元七角八分1 小时前
pom.xml
xml·数据库
Jerry1 小时前
Compose 为元素赋予动画特效
android
虚行1 小时前
Mysql 数据同步中间件 对比
数据库·mysql·中间件
奥尔特星云大使1 小时前
mysql读写分离中间件Atlas安装部署及使用
数据库·mysql·中间件·读写分离·atlas
牛马baby2 小时前
【mysql】in 用到索引了吗?
数据库·mysql·in
Jeled2 小时前
协程工具类
android·android studio
杀气丶2 小时前
L2JBR - 修复数据库编码为UTF8
数据库·sql·oracle