欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android中数据库操作框架(ActiveAndroid、ormlite、greenDAO、DBFlow、Realm)介绍及使用详情

程序员文章站 2022-04-03 08:14:01
介绍 无论是ios平台还是Android平台,底层数据库都是基于开源的SQLite实现,然后在系统层封装成用于应用层的API。虽然直接使用系统的数据库API性能很高,但是这些AP...

介绍

无论是ios平台还是Android平台,底层数据库都是基于开源的SQLite实现,然后在系统层封装成用于应用层的API。虽然直接使用系统的数据库API性能很高,但是这些API接口并不是很方便开发者使用,一不小心就会引入Bugs,而且代码的视觉效果也不好,为了解决这个问题,一系列的对象关系映射(ORM)框架出现,这其中比较出名的且广泛使用的有:ActiveAndroid、ormlite、DBFlow和greenDAO。

ActiveAndroid

ActiveAndroid是一种Active Record 风格的ORM框架,它可以极大的简化数据库的使用,使用面向对象的方式管理数据库,告别手写SQL历史。每一个数据库表都可以映射为一个类,开发者只需要使用类似save()或者delete()这样的函数即可。

一、添加依赖,把下面的代码添加到工程的build.gradle中:

 repositories {  
        mavenCentral()  
        maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }  
    }  

    compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'  

二,配置与初始化:

1,在清单文件中配置数据库名称和数据库版本号:

    
        
        

通过mete-data来配置数据库名称和数据库版本号,其中AA_DB_NAME为数据库名称,AA_DB_VERSION为数据库版本号,默认为1,AA_MODELS为对应的模型。

自定义Application,需要让你的Application对象继承自com.activeandroid.app.Application而不android.app.Application。然后在清单文件的applicatin下通过name来引用,这样就完成了ActiveAndroid的初始化工作。

public class MyApp extends Application {
    //为了兼容5.0以上的手机,需添加下面的代码
    @Override
    public void onCreate() {
        super.onCreate();
        Configuration.Builder builder = new Configuration.Builder(this);
        //手动的添加模型类
        builder.addModelClasses(User.class);
        ActiveAndroid.initialize(builder.create());
    }
}

然后在清单文件的applicatin下通过name来引用:

android:name=".MyApp"  

创建Model类 (必须要加空构造函数且super()不然会有时报错)

/**
 * Created by MG_ZXC on 2018/2/4.
 * 1,必须继承Model,继承后就不用声明主键了
 * 2,按照表名添加字段
 * 3,添加注释
 */

@Table(name = "user")
public class User extends Model {
    @Column
    private String userName;
    @Column
    private int userId;
    @Column
    private int age;
    @Column
    private String addr;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public User() {
        super();
    }

    public int getUserId() {

        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", userId=" + userId +
                ", age=" + age +
                ", addr='" + addr + '\'' +
                '}';
    }
}

操作数据库的工具类

/**
 * Created by MG_ZXC on 2018/2/4.
 * 操作数据库的工具类
 */

public class DbManager {
    //添加数据
    public void insertUser(User user){
        //操作数据库的对象就是实体类本身
        user.save();
    }

    //删除数据
    public void deleteUser(User user){
        user.delete();
    }

    //更新数据
    public void updateUser(User user){
        user.setUserName("关羽");
        user.setAddr("北京");
        //在activeandroid中save既可以创建,也可以修改
        user.save();
    }

    //查询所有的数据
    public List queryUser(){
        List execute = new Select()
                .from(User.class) //model类
                .execute();
        return execute;
    }

    //条件查询
    public List query(String userName){
        List queryName = new Select()
                .from(User.class)
                .where("userName = ?", userName) //查询条件
                .execute();
        return queryName;
    }

    //条件删除
    public void delete(String userName){
        new Delete()
                .from(User.class)
                .where("userName = ?", userName)
                .execute();
    }

    //条件更新
    public void update(String userName){
        Update update = new Update(User.class);
        update.set("addr = ?","上海")
                .where("userName=?",userName)
                .execute();
    }
}

使用:

增加:

User user = new User();  
                user.setAddr("信阳");  
                user.setAge(28);  
                user.setUserId(1);  
                user.setUserName("张飞");  
                dbManager.insertUser(user);  

查询:

users = dbManager.query("张飞");  

删除:

dbManager.delete("张飞");  

更新:

dbManager.update("张飞");  

数据库升级

上面的代码完全能够实现ActiveAndroid的功能了,但ActiveAndroid的数据库升级不像其他数据库升级那么简单,只需改变版本号就行了,下面介绍一下ActiveAndroid的版本升级的步骤:

1,先把数据库版本改为要升级到的版本,如改为2

2,在工程下新建assets/migrations,在该目录下增加一个修改过得版本号,比如我现在的版本号升级为2,则文件夹名为2.sql。

3,在2.sql文件夹下使用sql语句来编写版本升级新增的功能,如新增了一个字段:

   ALTER TABLE user ADD COLUMN Count INTEGER;  

OK,到这里ActiveAndroid的使用已经完成了。

通过GitHub上的ActiveAndroid在14年已经停止更新,而且本人在使用ActiveAndroid过程中发现,在高版本Android 中会报一些”莫名其妙”的Bug.

ormlite

ormlite是Java平台的一个ORM框架,支持JDBC链接,Spring和Android平台,在Android中使用包含两部分。简述: 优点: 1.轻量级;2.使用简单,易上手;3.封装完善;4.文档全面。缺点:1.基于反射,效率较低(本人还没有觉得效率低);2.缺少中文翻译文档

ormlite-core:核心模块,无论在哪个平台使用,都必须基于这个核心库,是实现ORM映射的关键模块。 ormlite-android:基于ormlite-core封装的针对Android平台的适配模块,Android开发中主要跟这个模块打交道。

定义Bean类

@DatabaseTable(tableName = "user")
public class User {
    @DatabaseField(useGetSet=true, columnName = "userName")
    private String userName;
    //generatedId定义主键自增长,columnName定义该字段在数据库中的列名
    @DatabaseField(useGetSet=true,generatedId=true,columnName="id")
    private int userId;
    @DatabaseField(useGetSet=true, columnName = "age")
    private int age;
    @DatabaseField(useGetSet=true, columnName = "addr")
    private String addr;

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", userId=" + userId +
                ", age=" + age +
                ", addr='" + addr + '\'' +
                '}';
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }
}

SQLiteOpenHelper类

原生的数据库操作,都需要继承SQLiteOpenHelper,而ormlite我们则需要继承OrmLiteSqliteOpenHelper

public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
    private static final String TABLE_NAME = "ormlite.db";//默认是在data/data/包名/databases/路径下
    private static final int DB_VERSION = 1;

    private Map daos = new HashMap();

    private DatabaseHelper(Context context) {
        super(context, context.getFilesDir().getAbsolutePath()+TABLE_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
        try {
            TableUtils.createTableIfNotExists(connectionSource, User.class);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase database,
                          ConnectionSource connectionSource, int oldVersion, int newVersion) {
        //整表删除创建

            // TableUtils.dropTable();

           onCreate(database, connectionSource);

    /*    //更新数据库时只需添加新增字段
        if (newVersion == 3) {
            //数据库、表名、列名、类型
            DatabaseUtil.updateColumn(database, "", "", "VARCHAR", null);
        }*/
    }

    private static DatabaseHelper instance;

    /**
     * 单例获取该Helper
     *
     * @param context
     * @return
     */
    public static synchronized DatabaseHelper getHelper(Context context) {
        context = context.getApplicationContext();
        if (instance == null) {
            synchronized (DatabaseHelper.class) {
                if (instance == null)
                    instance = new DatabaseHelper(context);
            }
        }

        return instance;
    }

    public synchronized Dao getDao(Class clazz) throws SQLException {
        Dao dao = null;
        String className = clazz.getSimpleName();

        if (daos.containsKey(className)) {
            dao = daos.get(className);
        }
        if (dao == null) {
            dao = super.getDao(clazz);
            daos.put(className, dao);
        }
        return dao;
    }

    /**
     * 释放资源
     */
    @Override
    public void close() {
        super.close();

        for (String key : daos.keySet()) {
            Dao dao = daos.get(key);
            dao = null;
        }
    }
}

DatabaseUtil

public class DatabaseUtil {
    public static void updateColumn(SQLiteDatabase db, String tableName,
                                    String columnName, String columnType, Object defaultField) {
        try {
            if (db != null) {
                Cursor c = db.rawQuery("SELECT * from " + tableName
                        + " limit 1 ", null);
                boolean flag = false;

                if (c != null) {
                    for (int i = 0; i < c.getColumnCount(); i++) {
                        if (columnName.equalsIgnoreCase(c.getColumnName(i))) {
                            flag = true;
                            break;
                        }
                    }
                    if (flag == false) {
                        String sql = "alter table " + tableName + " add "
                                + columnName + " " + columnType + " default "
                                + defaultField;
                        db.execSQL(sql);
                    }
                    c.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void deleteRecordsWithoutForeignKey(SQLiteDatabase db, String tableName){
        if (db != null) {
            String sql = "DELETE from " + tableName;
            db.execSQL(sql);
        }
    }
}

编写Dao类

我们可以将需要的增、删、改、查等方法都放在Dao里,便于操作使用

public class DBDao {
    private Dao userDao;
    private DatabaseHelper helper;

    public DBDao(Context contex) {
        try {
            helper = DatabaseHelper.getHelper(contex);
            userDao = helper.getDao(User.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 增
     * @param
     */
    public void addUser(User user) {
        try {
            userDao.create(user);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删(通过实体)
     * @param 
     */
    public void delUser(User user) {
        try {
            userDao.delete(user);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删(通过id)
     * @param id
     */
    public void delUserById(Integer id) {
        try {
            userDao.deleteById(id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 改
     * @param user
     */
    public void updateUser(User user) {
        try {
            userDao.update(user);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 查
     * @return
     */
    public List queryAllUser() {
        ArrayList users = null;
        try {
            users = (ArrayList) userDao.queryForAll();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return users;
    }

    /**
     * 获取user
     * @param id user编号
     * @return
     */
    public User getUser(Integer id) {
        try {
            //父母信息为空
            return userDao.queryForId(id);
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }
}

greenDAO

greenDAO是一个轻量化且快速的ORM框架,专门为Android高度优化和定制的,它能够支持每秒数千记录的CRUD操作。我们从官网上面一张Benchmark图可以看出它与ormlite和ActiveAndroid的性能对比,

Android中数据库操作框架(ActiveAndroid、ormlite、greenDAO、DBFlow、Realm)介绍及使用详情

添加依赖:

// In your root build.gradle file:
    buildscript {
        repositories {
            jcenter()
            mavenCentral() // add repository
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:2.3.3'
            classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
        }
    }

    // In your app projects build.gradle file:
    apply plugin: 'com.android.application'
    apply plugin: 'org.greenrobot.greendao' // apply plugin

    dependencies {
        compile 'org.greenrobot:greendao:3.2.2' // add library
    }

实体类生成

@Entity
public class User {
    @Id(autoincrement = true)
    private Long userId;
    @Property(nameInDb = "userName")
    private String userName;
    @Property(nameInDb = "age")
    private int age;
    @Property(nameInDb = "addr")
    private String addr;
    @Generated(hash = 2044495610)
    public User(Long userId, String userName, int age, String addr) {
        this.userId = userId;
        this.userName = userName;
        this.age = age;
        this.addr = addr;
    }
    @Generated(hash = 586692638)
    public User() {
    }
    public Long getUserId() {
        return this.userId;
    }
    public void setUserId(Long userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return this.userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public int getAge() {
        return this.age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getAddr() {
        return this.addr;
    }
    public void setAddr(String addr) {
        this.addr = addr;
    }

    @Override
    public String toString() {
        return "User{" +
                "userId=" + userId +
                ", userName='" + userName + '\'' +
                ", age=" + age +
                ", addr='" + addr + '\'' +
                '}';
    }
}

@Entity  表明这个实体类会在数据库中生成一个与之相对应的表。
@Id  对应数据表中的 Id 字段,有了解数据库的话,是一条数据的唯一标识。且数据类型必须为Long类型
@Property(nameInDb = “STUDENTNUM”)  表名这个属性对应数据表中的 STUDENTNUM 字段。
@Property  可以自定义字段名,注意外键不能使用该属性
@NotNull  该属性值不能为空
@Transient  该属性不会被存入数据库中
@Unique  表名该属性在数据库中只能有唯一值

当你写完实体类中的属性之后,点击编译,就会自动生成相应的 setter 和 getter 方法,至于那些 hash 值是自动赋值上去的。并且在该目录下生成 DaoMaster 和 DaoSession 这两个类用于初始化数据库。

增删改查

一般数据库的操作都离不开增删改查,那么我们就从这开始。

初始化

 DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(context, "user", null);
        DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDb());
        daoSession = daoMaster.newSession();

如果实体类有更新,那么要调用 daoSession.clear() 清除缓存,才能得到更新。

  public void add(User user){
        UserDao userDao = daoSession.getUserDao();
        userDao.insert(user);
    }

 public void delete(User user){
        UserDao userDao = daoSession.getUserDao();
        userDao.delete(user);//通过实体删除
        //userDao.deleteByKey(user.getUserId());//通过主键删除
    }

改:

public void update(User user){
        UserDao userDao = daoSession.getUserDao();
        userDao.update(user);
    }

查:

public List query(User user){
        UserDao userDao = daoSession.getUserDao();
        List users=userDao.queryBuilder()
                .offset(1)
                .limit(3)
                .orderAsc(UserDao.Properties.UserName)
                .where(UserDao.Properties.UserName.eq(user.getUserName()))
                .build()
                .list();
        return users;
    }
    public List queryAll(){
        UserDao userDao = daoSession.getUserDao();
        List users = userDao.queryBuilder().list();
        return users;
    }

DBFlow

添加依赖:

 annotationProcessor 'com.github.Raizlabs.DBFlow:dbflow-processor:4.2.4'
    compile 'com.github.Raizlabs.DBFlow:dbflow-core:4.2.4'
    compile 'com.github.Raizlabs.DBFlow:dbflow:4.2.4'

需要创建一个application文件,在onCrete()方法中初始化

  //DBFlow初始化配置
        FlowManager.init(getApplicationContext());

这样整个配置就完成了,下面我们来看看如何使用

第一,创建数据库

我们需要自己创建一个数据库,定义数据库名称,版本号

@Database(name = DBFlowDatabase.NAME, version = DBFlowDatabase.VERSION)
public class DBFlowDatabase {
    //数据库名称
    public static final String NAME = "DBFlowDatabase";
    //数据库版本号
    public static final int VERSION = 1;
}

其次创建model文件

@Table(database = DBFlowDatabase.class)
public class User extends BaseModel {
    @Column
    public String userName;
    @Column
    public String addr;
    @Column
    public int age;

    @PrimaryKey(autoincrement = true)//ID自增
    public long userId;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", addr='" + addr + '\'' +
                ", age=" + age +
                ", userId=" + userId +
                '}';
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public long getUserId() {
        return userId;
    }

    public void setUserId(long userId) {
        this.userId = userId;
    }
}

这里简单介绍下,必须继承BaseModel,BaseModel包含了基本的数据库操作(save、delete、update、insert、exists),可以发现这个表是关联上面定义的数据库,UserModel 的id是自增的id(autoincrement )。

一个正确的数据表类需要以下几项: 对类添加@Table注解 声明所连接的数据库类,这里是DBFlowDatabase。 定义至少一个主键。
这个类和这个类中数据库相关列的修饰符必须是包内私有或者public。 这样生成的_Adapter类能够访问到它。 NOTE:
列(Column)属性可以是private,但这样就必须指定公有public的getter和setter方法。

创建完成后,需要编译一下,点击编译按钮,或者Build->Make Project即可,它会自动生成一些数据库文件,也会提示你创建是否有误!

然后,就是重头戏,怎么使用增删改查

       User user = new User();
        user.setAddr("信阳");
        user.setAge(28);
        user.setUserName("张飞");
       user.save();
        //people.update();//更新对象
        //people.delete();//删除对象
        //people.insert();//插入对象

查询:

List users = SQLite.select()
                    .from(User.class)
                    .where(User_Table.age.greaterThan(18))
                    .queryList();

查询全部:

List users=new Select().from(User.class).queryList()

Realm

Realm 是一个全新的移动数据库引擎,它既不是基于ios平台的Core Data,也不是基于SQLite,它拥有自己的数据库存储引擎,并实现了高效快速的数据库构建操作,相比Core Data和SQLite,Realm操作要快很多,跟ORM框架相比就更不用说了。

数据库Realm,是用来替代sqlite的一种解决方案,它有一套自己的数据库存储引擎,比sqlite更轻量级,拥有更快的速度,并且具有很多现代数据库的特性,比如支持JSON,流式api,数据变更通知,自动数据同步,简单身份验证,访问控制,事件处理,最重要的是跨平台,目前已有Java,Objective C,Swift,React-Native,Xamarin这五种实现。

开发者应该尝试使用Realm的理由如下:

跨平台:Android和ios已经是事实上的两大移动互联网操作系统,绝大部分应用都会支持这两个平台。使用Realm,Android和ios无需考虑内部数据的架构,调用Realm的Api即可轻松完成数据的交互,实现“一个数据库,两个平台之间的无缝衔接” 用法简单:相比Core Data和SQLite所需要的入门知识,Relam可以极大降低开发者的学习成本,快速实现数据库存贮功能。 可视化操作:Relam为开发者提供了一个轻量级的数据库可视化操作工具,开发者可以轻松查看数据库里的内容,并实现简单的插入和删除操作。

环境搭建:
参考 GITHUB

buildscript {
    repositories {
        jcenter()
        google()
        maven {
            url 'https://oss.jfrog.org/artifactory/oss-snapshot-local'
        }
    }
    dependencies {
        classpath "io.realm:realm-gradle-plugin:-SNAPSHOT"
    }
}

allprojects {
    repositories {
        jcenter()
        google()
        maven {
            url 'https://oss.jfrog.org/artifactory/oss-snapshot-local'
        }
    }
}

使用默认配置

public class MyApplication extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    // The Realm file will be located in Context.getFilesDir() with name "default.realm"
    Realm.init(this);
    RealmConfiguration config = new RealmConfiguration.Builder().build();
    Realm.setDefaultConfiguration(config);
  }
}

使用自定义配置

public class MyApplication extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    Realm.init(this);
    RealmConfiguration config = new  RealmConfiguration.Builder()
                                         .name("myRealm.realm")
                                         .deleteRealmIfMigrationNeeded()
                                         .build();
    Realm.setDefaultConfiguration(config);
  }
}

在AndroidManifest.xml配置自定义的Application


创建实体

新建一个类继承RealmObject

public class User extends RealmObject {
    public String userName;
    public String addr;
    public int age;
    @PrimaryKey
    public long userId;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public long getUserId() {
        return userId;
    }

    public void setUserId(long userId) {
        this.userId = userId;
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", addr='" + addr + '\'' +
                ", age=" + age +
                ", userId=" + userId +
                '}';
    }
}

(2)其他相关说明

1、支持的数据类型:
boolean, byte, short, int, long, float, double, String, Date and byte[]
在Realm中byte, short, int, long最终都被映射成long类型

2、注解说明

@PrimaryKey
①字段必须是String、 integer、byte、short、 int、long 以及它们的封装类Byte, Short, Integer, and Long

②使用了该注解之后可以使用copyToRealmOrUpdate()方法,通过主键查询它的对象,如果查询到了,则更新它,否则新建一个对象来代替。

③使用了该注解将默认设置@index注解

④使用了该注解之后,创建和更新数据将会慢一点,查询数据会快一点。

@Required
数据不能为null

@Ignore
忽略,即该字段不被存储到本地

@Index
为这个字段添加一个搜索引擎,这将使插入数据变慢、数据增大,但是查询会变快。建议在需要优化读取性能的情况下使用。

(1)实现方法一:事务操作

类型一 :新建一个对象,并进行存储

Realm realm=Realm.getDefaultInstance();
realm.beginTransaction();
User user = realm.createObject(User.class); // Create a new object
user.setUserName("John");
user.setAge(18);
user.setAddr("asd");
user.setuserId(1);
realm.commitTransaction();

类型二:复制一个对象到Realm数据库

Realm realm=Realm.getDefaultInstance();
User user = new User();
user.setUserName("john");
user.setAge(18);
user.setAddr("asd");
user.setuserId(1);
// Copy the object to Realm. Any further changes must happen on realmUser
realm.beginTransaction();
realm.copyToRealm(user);
realm.commitTransaction();

(2)实现方法二:使用事务块

Realm  mRealm=Realm.getDefaultInstance();
final User user = new User();
user.setUserName("john");
user.setAge(18);
user.setAddr("asd");
user.setuserId(1);
mRealm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {

            realm.copyToRealm(user);

            }
        });

 Realm  mRealm=Realm.getDefaultInstance();
    final RealmResults users=  mRealm.where(User.class).findAll();
        mRealm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                User user=users.get(5);
                user.deleteFromRealm();
                //删除第一个数据
                users.deleteFirstFromRealm();
                //删除最后一个数据
                users.deleteLastFromRealm();
                //删除位置为1的数据
                users.deleteFromRealm(1);
                //删除所有数据
                users.deleteAllFromRealm();
            }
        });

同样也可以使用同上的beginTransaction和commitTransaction方法进行删除

Realm  mRealm=Realm.getDefaultInstance();
Dog dog = mRealm.where(User.class).equalTo("userId", 2).findFirst();
mRealm.beginTransaction();
dog.setName("asd");
mRealm.commitTransaction();

同样也可以用事物块来更新数据

(1)查询全部

查询结果为RealmResults,可以使用mRealm.copyFromRealm(users)方法将它转为List

    public List queryAllUser() {
        Realm  mRealm=Realm.getDefaultInstance();
        RealmResults usres = mRealm.where(User.class).findAll();
        return mRealm.copyFromRealm(usres);
    }

(2)条件查询

    public User queryUserById(int id) {
        Realm  mRealm=Realm.getDefaultInstance();
        User user = mRealm.where(User.class).equalTo("userId", id).findFirst();
        return user;
    }

常见的条件如下(详细资料请查官方文档):

between(), greaterThan(), lessThan(), greaterThanOrEqualTo() & lessThanOrEqualTo()

equalTo() & notEqualTo()

contains(), beginsWith() & endsWith()

isNull() & isNotNull()

isEmpty() & isNotEmpty()

(3)对查询结果进行排序

 /**
     * query (查询所有)
     */
    public List queryAllUser() {
        RealmResults users = mRealm.where(User.class).findAll();
        /**
         * 对查询结果,按Id进行排序,只能对查询结果进行排序
         */
        //增序排列
        users=users.sort("userId");
        //降序排列
        users=users.sort("userId", Sort.DESCENDING);
        return mRealm.copyFromRealm(users);
    }

(4)其他查询

sum,min,max,average只支持整型数据字段

 /**
     *  查询平均年龄
     */
    private void getAverageAge() {
         double avgAge=  mRealm.where(User.class).findAll().average("age");
    }

    /**
     *  查询总年龄
     */
    private void getSumAge() {
      Number sum=  mRealm.where(User.class).findAll().sum("age");
        int sumAge=sum.intValue();
    }

    /**
     *  查询最大年龄
     */
    private void getMaxId(){
      Number max=  mRealm.where(User.class).findAll().max("age");
        int maxAge=max.intValue();
    }

这里就介绍到这里,对于Realm的异步操作,以及数据库的数据迁移(版本升级

前四个ORM框架的大小是在正常范围之内的,但是Realm的大小一般项目可能无法接受,我们将这个JAR包解压,如下图所示

原来不同的CPU架构平台的.so文件增加了整个包的大小,由于arm平台的so在其他平台上面使能够以兼容模式运行的,虽然会损失性能,但是这样可以极大的减少函数库占用的空间。因此,可以选择只保留armeabi-v7a和x86两个平台的.so文件,直接删除无用的.so文件,或者通过在工程的build.gradle文件增加ndk abi过滤 语法如下:

android{
    defaultConfig{
        ndk{
            abiFilters "armeabi-v7a","x86"
        }
    }

}

总结

因此,综合考虑性能,包的大小及开源的可持续发展等因素,建议使用greenDAO。